Подписка на событие получения управляемой формы




Принцип обмена данными из 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='\

26 Comments

  1. Dimasik2007

    Я обычно делаю по другому, в случае как управляемых, так и не управляемых форм. При серьезных модификациях формы, я ее копирую из типовой с префиксом (допустим _) и сменяю в конфигурации основную форму объекта.

    Обновляетмся все довольно легко, система показывает, что измено свойство документа (напр. ОсновнаяФормаДокумента), и тут же легко проверить, вносились ли изменеия в типовую форму (мы же ее не изменяли). Если изменений нет, то форма не появиться в сравнении конфигурации, а значит и делать ничего не нужно. Только не забыть флажок снять)

    Reply
  2. Bassgood

    (1) Dimasik2007, да, можно и так делать, тоже вариант, основное отличие проделывать это через подписки — не снимать дополнительные галочки при сравнении конфигураций.

    Reply
  3. Поручик

    Это одно НО сводит почти на нет ценность фичи. 1С, как всегда, к ложке мёда прилагает бочку дёгтя.

    Reply
  4. Поручик

    Вот сейчас у меня в работе один проект по доработке УТ 11. Необходимо для несколько штатных документов добавить однотипные элементы формы и меню. Но использовать подписку я не хочу, так как нет уверенности, что вызов формы документов будет всегда осуществляться указанным способом.

    Reply
  5. glek

    Если начали разрабатывать такое — значит в итоги долижут. Насчет (1): тоже делал так же. Один нюанс перечеркивает все плюсы: при существенных изменениях в форме от поставщика — все равно переносить ручками.

    Reply
  6. AlexO

    (1) Dimasik2007,

    и каким образом будете вносить изменения от 1С в свою копию формы? это не выход.

    Один нюанс перечеркивает все плюсы: при существенных изменениях в форме от поставщика — все равно переносить ручками.

    да как бы в создании копии формы плюсов немного — потому как это все из разряда «любым способом сохранить совместимость конфигурации».

    Если начали разрабатывать такое — значит в итоги долижут.

    есть прецеденты от 1С?

    Reply
  7. Dimasik2007

    (7) Глобально перепаханные документы (по крайней мере в моей торговой области — заказ покупателя, поступление товаров, заказы поставщику, ОПЗС и проч) в дальнейших обновлениях не нуждаются. По крайней мере за 2 года обновления УПП серьезных изменений не было, т.е. они более статичны.

    А в других доках уже проще — типовая форма уже загружена в базу, можно сравнить и подкопипастить.

    Reply
  8. Dimasik2007

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

    Reply
  9. pumbaE

    (9) Dimasik2007, многие забивают на подписки о событиях, но это не мешает другим их использовать, а не пихать дополнительную процедуру в модуль проведения.

    Reply
  10. AlexO

    (9) Dimasik2007,

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

    1С никогда такого не сделает. Потому как изначально ей этого не сделано при написании платформы (откуда и проблема «одно НО«).

    А уж обращение и перегрузка стандартных событий форм/объектов — забудьте. Это 1С.

    А не среда программирования.

    Reply
  11. Dimasik2007

    (10) Тут уж в зависимости от задачи. Вот я, допустим, при расчете упр. цены в документе ОПЗС в процедуру ОбработкаПроведения вставил такой код

    _Ценообразование.ЗафиксироватьЦены_ОПЗС(ЭтотОбъект, ТаблицаПоПродукции, СтруктураШапкиДокумента, Отказ);

    Зачем мне тут подписка? Заново рассчитывать данные ТаблицаПоПродукции, СтруктураШапки и т.п?

    (11) Не сделает — да и бог с ним. И так кормит) Да и порог вхождения минимальный.

    Reply
  12. Bassgood

    (4) Поручик, (6) glek, (11) AlexO, я так думаю, что это одно НО 1С сделала не случайно, они тем самым учли следующий момент: если возникнет необходимость открыть какую-либо форму объекта (возможно для каких-либо особых случаев или еще чего) — чтобы такая возможность у разработчика была несмотря на существование в конфигурации подобных подписок (иначе постоянно бы открывалась одна и та же форма, назначенная в подписке).

    Reply
  13. tormozit

    Название публикации не соответствует ее содержанию. Здесь описана подписка на событие менеджера объекта метаданных, а не формы.

    Reply
  14. pumbaE

    (12) Dimasik2007, конкретно этот пример неправильный для типовых и 8.2 в подписке обращаемся к ДополнительнымСвойствам:

    Если Источник.ДополнительныеСвойства.Свойство(«СтруктураШапкиДокумента»)
    И Источник.ДополнительныеСвойства.Свойство(«СтруктураТабличныхЧастей») Тогда
    мСтруктураШапкиДокумента = Источник.ДополнительныеСвойства.СтруктураШапкиДокумента;
    
    
    Reply
  15. Bassgood

    (14) tormozit, событие относится к менеджерам объектов, но ведь само событие вызывается при получении формы прикладного объекта (то что подписка относится непосредственно к форме в заголовке ничего не сказано).

    Reply
  16. AlexO

    (10) pumbaE,

    а не пихать дополнительную процедуру в модуль проведения.

    так даже и модуля проведения как такового нет. Так, скромная процедура на обработку события…

    Reply
  17. tormozit

    (16) В общем рекомендую убрать двусмысленность из названия. Например «Подписка на событие «Обработка получения формы» менеджера объекта».

    Reply
  18. AlexO

    (18) tormozit,

    так весь кайф студентам обломаешь :))

    Reply
  19. Bassgood

    (5) Поручик, можно попробовать воспользоваться добавлением в конфигурацию новых команд, в которых указать, чтобы они располагались где-нибудь на форме (в командном меню формы или в ее панели навигации), правда не всегда этим можно воспользоваться.

    Reply
  20. Bassgood

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

    Reply
  21. AlexO

    (21)

    ну согласитесь же, что разбирать «Подписку на получение УФ» намного интереснее, чем какую-то там малохольную «Подписку на событие «Обработка получения формы» менеджера объекта» 😉

    Reply
  22. Bassgood

    (22) AlexO, так оно и есть, особенно не интересна для многих будет тема с заголовком «Подписка на событие «Обработка получения формы» менеджера прикладного объекта, используемой для переопределения управляемой формы на сервере» =)

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

    Reply
  23. Dimasik2007

    (15) Да, к сожалению пример не правильный, в ОПЗС не заполняются ДополнительныеСвойства.

    В том же документе ТребованиеНакладная они заполняются и их можно цеплять извне.

    Там даже пишут «в лоб»:

    //Сделаем переменные доступными из подписок на события

    ДополнительныеСвойства.Вставить(«СтруктураШапкиДокумента», СтруктураШапкиДокумента);

    ДополнительныеСвойства.Вставить(«СтруктураТабличныхЧастей», Новый Структура(«ТаблицаПоТоварам», ТаблицаПоТоварам));

    Reply
  24. Поручик

    Есть ещё одна причина, по которой эта фича в большинстве случаев останется невостребованной. Многие заказчики используют прежние версии платформы 8.2, в которой она отсутствует, и менять платформу желанием не горят.

    Reply
  25. Bassgood

    (25) Поручик, со временем перейдут, всему свое время =)

    Reply
  26. Raminus

    Потестил, пока что не могу найти для себя применение такой возможности, но вещь бесспорно интересная думаю будут развивать.

    (25) Поручик, бесспорно перейдут, нужна будет поддержка бух 3.х перейдут никуда не денутся 🙂

    Reply

Leave a Comment

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