Произвольный отбор при открытии формы любого динамического списка




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

29 Comments

  1. slawa

    Для чего Схему помещать во временное хранилище?

    Reply
  2. starik-2005

    (1) в принципе тут схема вообще не нужна — можно создать объект настроек компоновки данных. А помещение в хранилище — дань традициям.

    Reply
  3. nomadon

    без помещения интерактивно не работают доступные поля, мож и тут что то не работает

    Reply
  4. starik-2005

    (3) тут все работает, но компоновка тут нужна лишь для получения фиксированных настроек, т.е. фактически весь этот код можно заменить на «ФиксНастройки = Новый НастройкиКомпоновкиДанных».

    Reply
  5. Yashazz

    Ваще чего-то совсем баян. Из серии «как вывести пользователю сообщение». С чего вдруг столько плюсов?..

    Автор, насчёт производительности что-нибудь известно? Или это вариант только для простых списков по основной таблице?

    Reply
  6. starik-2005

    (5) все зависит от того, что открывает пользователь. Если первый вариант отбора позволяет на «Равно» и «ВСписке» отбирать, то второй фактически определяет любой отбор, доступный пользователю в настройке списка, только при этом пользователь не видит отбор из фиксированных настроек. Производительность определяется полями отбора, которые уже будут влиять на план запроса в СУБД. Если по индексированному полю отбор происходит — производительность будет высокая, а если по какому-то ПОДОБНО в реквизите табличной части, то все зависит от размера таблицы. Я как-то руками группировку попытался сделать по весьма небольшому справочнику — пятнадцать минут ждал, пока программа что-то вернет.

    С другой стороны, если показать пользователю меньше данных, то есть некоторый шанс на то, что пользователь не выберет что-то не то.

    ЗЫ: Ты до сих пор не знаешь, за что на Инфостарте плюсуют? Могу как-нибудь рассказать…

    Reply
  7. zqzq

    (4) Так и надо всю эту воду из статьи убрать и оставить нужное

    
    ФиксНастройки = Новый НастройкиКомпоновкиДанных;
    
    ФиксНастройки.ПараметрыДанных.Элементы.Добавить().Параметр = Новый ПараметрКомпоновкиДанных(«Период»);
    ФиксНастройки.ПараметрыДанных.УстановитьЗначениеПараметра(«Период», ПППП);
    
    УправлениеНебольшойФирмойКлиент.УстановитьЭлементОтбораСписка(ФиксНастройки, «Склад», СССС);
    
    

    Показать

    Reply
  8. Новиков

    (4)

    но компоновка тут нужна лишь для получения фиксированных настроек, т.е. фактически весь этот код можно заменить на «ФиксНастройки = Новый НастройкиКомпоновкиДанных».

    Может быть для потомков покажете вторую редакцию готового кода, с замененными фрагментами? Может как-то бы и в статье это отразить?

    И не понятно, если при всех одинаковых вводных, можно написать меньше когда, то почему не воспользоваться данной возможностью? 🙂

    Reply
  9. mitia.mackarevich

    Забавно, а что будет автор если пользовательские настройки будут идти в наложении(Например сохраненные) или пользователь захочет потом сам настроить дин. список? вывалиться ошибка, наложение икс и пользовательских настроек недопустимо.Тогда имеет смыл запретить редактирование настроек при открытии динамического списка.

    За труды все равно плюсану.

    Reply
  10. starik-2005

    (8) если потомки не смогут сделать это самостоятельно, то за державу станет обидно )))

    Reply
  11. starik-2005

    (7) ну некоторым интересно полностью поглядеть ))

    Reply
  12. starik-2005

    (9) так можно всегда гипотезу попытаться подтвердить или опровергнуть экспериментом!

    Reply
  13. Новиков

    (10) Так вы для кого статью то писали, для себя или для других? Если для себя — вопросов нет. Если для других, вы зачем-то предложили длинный путь при наличии короткого. Дальше эту статью очевидно будут находить поисковиком и просто копи-пастить, меняя название документа и табличной части на свое. И расползется ваша портянища по многим и многим конфам. Я уверен, даже до комментов основная масса не дойдет, зная что решение — работает.

    Дополните статью коротким вариантом, типа «но код можно подсократить, и я покажу как».

    Переживаю сильно, т.к. многие тонны классного навоза вот таким вот копи-паством потом приходится разгребать. Надеюсь вы немножко облегчите этот труд будущим потомкам, а может и мне 🙂

    Спасибо.

    Reply
  14. starik-2005

    (13) как в одном анекдоте про обезьян, прапорщиков, палку и бананы: «что тут думать — прыгать надо!» Отсюда мораль: не стоит упрощать то, что недоступно для понимания масс, чтобы оное оставалось в элитарном сегменте.

    Reply
  15. palsergeich

    Использовать фиксированные настройки не гуд, ибо отбор по полю, на которое наложен уже отбор в фиксированных настройках приведет к ошибке. И часто приводит к тому, что такой список становится нафиг никому не нужен.

    Почему не использовать пользовательские настройки с доступностью — недоступный?

    Reply
  16. palsergeich

    Что то типо такого.

    ПараметрыФормы = Новый Структура(«ПользовательскиеНастройки», ПользовательскиеНастройки);

    ПараметрыФормы.Вставить(«СформироватьПриОткрытии» , Истина);

    Форма = ОткрытьФорму(«Отчет.XXXXX.Форма.ФормаОтчета», ПараметрыФормы, ПараметрыВыполненияКоманды.Источник, ПараметрыВыполненияКоманды.Источник.УникальныйИдентификатор, ПараметрыВыполненияКоманды.Окно);

    Reply
  17. starik-2005

    (16) это для отчетов. В расширении формы динамического нет параметра «ПользовательскиеНастройки». Или есть? Для расширения формы компоновщика настроек есть.

    Reply
  18. alexei366

    В СП можно ввести «Расширение управляемой формы для динамического списка» и там будут и ФиксированныеНастройки и ПользовательскиеНастройки и КлючПользовательскихНастроек. Так что можно поиграться.

    Reply
  19. starik-2005

    (18) у меня в СП так, пользовательские настройки есть — круто!

    Reply
  20. alexei366

    (19)Ну славо богу, хоть СП сопали)))

    Reply
  21. starik-2005

    (20) с пользовательскими настройками то плохо, что пользователь их может отрубить. При этом фиксированные он срубить не сможет. С другой стороны, пользователь всегда прав — и если так, то можно и пользовательские настройки передавать.

    Reply
  22. alexei366

    (21) Надо тестить, ты же их передавать будешь, они может будут замещать пользовательские, плюк ключ пользовательских настроек можно передать какойнить специфический.

    Reply
  23. Pawlick
    1С не работает с соответствием

    С какого числа?

    Проверил: Платформа 1С:Предприятие 8.3 (8.3.8.1784)

    Соответствие = Новый Соответствие;

    Работает!!!

    …Фух… Перепугался даже

    Reply
  24. starik-2005

    (23) это если выдирать из контекста, то работает, а если с контекстом — нет )))

    Reply
  25. Makushimo

    Спасибо!

    Reply
  26. SlavaKron

    (15)(18)(19)

    Так что там с параметром формы ПользовательскиеНастройки? Получилось у кого-нибудь через него установить отбор?

    Reply
  27. starik-2005

    (27) попробуй — узнаешь!

    Reply
  28. SlavaKron

    (28) У меня не получилось, потому и спрашиваю.

    Reply
  29. SlavaKron

    Получилось, хоть и не без шаманства. Оказывается, идентификатор пользовательских отборов для любого динамического списка при создании формы всегда один и тот же: «dfcece9d-5077-440b-b6b3-45a5cb4538eb».

    Может, кому-нибудь пригодится:

    &НаКлиенте
    Процедура Реквизит1НачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    ПользовательскиеНастройки = Новый ПользовательскиеНастройкиКомпоновкиДанных;
    
    ИдентификаторПользовательскойНастройки = «dfcece9d-5077-440b-b6b3-45a5cb4538eb»;
    
    Отбор = ПользовательскиеНастройки.Элементы.Добавить(Тип(«ОтборКомпоновкиДанных»));
    Отбор.ИдентификаторПользовательскойНастройки = ИдентификаторПользовательскойНастройки;
    Отбор.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Авто;
    
    ЭлементОтбора = Отбор.Элементы.Добавить(Тип(«ЭлементОтбораКомпоновкиДанных»));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(«Наименование»);
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит;
    ЭлементОтбора.ПравоеЗначение = «Вода»;
    ЭлементОтбора.Использование = Истина;
    ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ;
    ЭлементОтбора.ИдентификаторПользовательскойНастройки = Новый УникальныйИдентификатор;
    
    ПараметрыФормы = Новый Структура(«ПользовательскиеНастройки», ПользовательскиеНастройки);
    
    ОткрытьФорму(«ВнешняяОбработка.ВнешняяОбработка1.Форма.Форма1», ПараметрыФормы, Элемент);
    КонецПроцедуры

    Показать

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *