Методика упрощения поддержки конфигураций. Переопределение и вызов обработчиков событий для УФ 1С 8.2-8.3




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

40 Comments

  1. Поручик

    Пока не пробовал, но работа хорошая. Жалко, что в управляемых формах нет секции инициализации или операторов основной программы. Тогда не пришлось бы вторгаться в штатную процедуру ПриСозданииНаСервере.

    Reply
  2. MarSeN

    Доброе время суток.

    Спасибо автору за статью — обязательно скачаю и попробую. Интересный подход в котором надо разобраться.

    Плюс в копилку.

    Как вариант решения описанной задачи 2 статьи:

    http://infostart.ru/public/171514/?fruser=yes#users_raters

    http://infostart.ru/public/170935/

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

    Буду признателен, если Вы в 2-х словах опишите механизм

    Reply
  3. pbazeliuk

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

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

    Reply
  4. MarSeN

    (3) Baza

    Спасибо, получается что в принципе подходы у нас одинаковые ). Хранение кода в разных местах. Потребность диктует решения.

    Reply
  5. alekseies

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

    Reply
  6. plevakin

    (3) Когда появиться возможность подписки на события формы

    А когда эта возможность появится?

    Reply
  7. akomar

    (5) Зато очень легко вносить изменения в обоработку, на лету, без отключения пользователей от базы, что критично при большом количестве пользователей.

    Reply
  8. pbazeliuk

    (6) plevakin, в платформе 8.3.

    Reply
  9. tormozit

    Было бы неплохо указать ссылку и на основу, опубликованную на инфостарте http://infostart.ru/public/16980/ .

    Reply
  10. pbazeliuk

    (9) tormozit, изменил.

    Reply
  11. Азбука Морзе

    Отличная работа. Обязательно приму на вооружение.

    п.с. В прошлой жизни так припекло с обновлением переделанной УТ11, что пришлось застрелится:)

    Reply
  12. fr.myha

    Интересный материал.

    Reply
  13. alekseies

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

    Reply
  14. pbazeliuk

    (13) alekseies, динамическое обновление в высоконагруженной базе в часто приводит к крашу базы, сама 1С не рекомендует его применять и еще что бы пользователь мог использовать обновления ему нужно перезапустить базу (для каждого сеанса конфигурация кешируеться). В данном методе все безопасно и перезагружать пользователю базу не нужно.

    Reply
  15. TODD22

    (9) Не открывается. Пишет что публикация не активна.

    Reply
  16. ivanov660

    Статья заинтересовала. Буду смотреть, надеюсь это поможет в нашей ситуации.

    Reply
  17. ivanov660

    Посмотрел, кое что понравилось и буду использовать что-то.

    Вопрос: А как влияет на «быстродействие» использование внешних обработок? Я бы, к примеру, создал «Библиотека внешних обработок» как внутреннюю обработку.

    Reply
  18. pbazeliuk

    (17) ivanov660, на быстродействие никак особо не влияет.

    Reply
  19. pbazeliuk

    (17) ivanov660, с ростом числа подключенных обработок начало влиять. К понедельнику выкачу новую статью с оптимизацией данного метода.

    Reply
  20. zakov

    Спасибо за статью, метод классный. Не пойму только как можно вызвать старый обработчик?

    Reply
  21. pbazeliuk

    (20) zakov, к понедельнику в продолжении статьи все опишу.

    Reply
  22. pbazeliuk

    (17) ivanov660, (20) zakov, вот часть 2 — avtomat.biz

    Reply
  23. Andry.Boris

    Спасибо за статью,

    очень интересная реализация…

    Reply
  24. amon_ra

    Отлично. Пожалуй возьму себе на заметку. Огромное спасибо!

    Reply
  25. higs

    Присоединяюсь, интересный подход. И достаточно универсален. Спасибо!!

    Reply
  26. Alex_Japanese_Student

    Плюсую, сильная разработка, очень поможет

    Reply
  27. 0vrcr

    А не появилось варианта назначения нового обработчика на динамически созданный элемент? И чтобы сам обработчик был в глобальном модуле?

    Например, создаем РегистрСведенийНаборЗаписей динамически на форме. Подключаем обработчик ПриИзменении. И чтобы этот обработчик хранился в общем модуле?

    Reply
  28. pbazeliuk

    (27) 0vrcr, появилось что-то похожее, но все равно нужно добавить в форму процедуруфункцию перенаправления на общие модулявнешние модуля

    Reply
  29. 0vrcr

    Ясно. Ну этот метод я знаю, сам использую. Жаль, спасибо! 🙂

    Reply
  30. CheBurator

    Было бы интересно почитать весьма про «внедрения конфигурации «Управление торговлей, редакция 11» в не российской торговой компании, из чего следует, что переписано и изменено было очень многое.» — такие проекты не частые гости…

    Reply
  31. pbazeliuk

    (30) CheBurator, возможно, когда-то. На самом деле реализовано много, что-то более 7000 задач только на разработку, 3000 обращений на поддержку каждый месяц. А конца так и не видно…

    Reply
  32. pbazeliuk

    (30) CheBurator, самое, наверное, интересное — партионная себестоимость, которая полностью за месяц пересчитывается за 1-3 минуты, без перепроведения документов и использования последовательностей.

    Reply
  33. mikhailv

    Видео из статьи не воспроизводится: ролик не найден. Почините, пожалуйста.

    Reply
  34. pbazeliuk

    (33) mikhailv, добрый день, к сожалению, видео безвозвратно утеряно. Постараюсь на выходных обновить статью и снять новое видео.

    Reply
  35. Cyberhawk

    Я правильно понимаю, что нет возможности размещать ЭУ (элементы управления — например, поле формы) в произвольном месте родителя (группы формы)?

    Т.е. программно добавляемые ЭУ всегда размещаются в конце (справа или снизу).

    //

    Отбой, нашел метод Вставить() вместо Добавить()

    Reply
  36. pbazeliuk

    (35) Cyberhawk, используйте процедуру ПереместитьЭлементВКоллекциюЭлементовФорм, если нужно изменить место расположения.

    Reply
  37. UNIT68RUS

    Коллеги не пойму по поводу обработки? Можно скрин обработки?

    Reply
  38. pbazeliuk

    (37) Статья довольно старая, у вас уже есть возможность использовать «Расширения конфигураций». Мы уже понемногу отказываемся от указанного метода и переносим код в расширения, но в 2012 году без него было очень сложно.

    Reply
  39. tormozit

    .

    Reply
  40. pbazeliuk

    (39) Согласен. Обычные формы еще лет 10 проживут; смотрю на то как мы все переносим в расширения — этот процес займет еще лет 5 (не приоритет, бизнес на этом денег больше не заработает).

    Reply

Leave a Comment

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