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




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2026-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 не будет опубликован. Обязательные поля помечены *