Сравнение объектов и форм метаданных (очередная декомпиляция и анализ форм)




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2025-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='\

22 Comments

  1. MRAK

    огромный + авансом!

    Reply
  2. Душелов

    Нравится!

    Reply
  3. MRAK

    Некоторые недоработки:

    1. Если «вывести объекты» на корне дерева конфы, то вывалится ошибка.

    2. Если попытаться сравнить не формы — вылетит ошибка.

    3. Слишком медленно происходит сравнение. Особо неприятно, если ошибся формой, ждал 5 минут, а обработка сказала, что формы одинаковы.

    4. При закрытии обработки ОЛЕ-база спрашивает «Вы уверены, что хотите выйти?» и это окошко не выводится на передний план, только через альт-таб его видно.

    Но все равно разработка мощная, попозже посмотрю ее получше)

    Reply
  4. alexer

    (3)

    1. Поправил.

    2. Не понял что за ошибка?

    3. Медленно, это да, она же через ОЛЕ подключается.

    4. Это не знаю как поправить, возможно это косяк платформы 1С.

    Reply
  5. MRAK

    2. Что-то уже не воспроизводится, возможно, после исправления 1.

    4.

    Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)

    БазаОле.ЗавершитьРаботуСистемы(Ложь);

    БазаОле = Неопределено;

    КонецПроцедуры // ПередЗакрытием()

    Reply
  6. alexer

    (5) Спасибо, поправил.

    Reply
  7. tormozit

    А она сопоставляет элементы формы по ГУИДам или по именам?

    Reply
  8. alexer

    (7) По именам.

    Reply
  9. MSensey

    Имею средство сравнения и объединения модулей на уровне процедур, но я никому не дам (бесплатно) 😎

    Reply
  10. alexer

    (9) Почем в Одессе рубероид?

    Ответ. Назовите мне разумную цену, и мы договоримся!

    🙂

    Reply
  11. MSensey

    (10) это не сложно ты сможешь и сам сделать 🙂

    Reply
  12. Собеседник

    + одназначно. вещь полезная.

    Reply
  13. e.kogan

    Почему не включили функционал сравнения внешних отчётов и обработок? Маловостребован?

    Reply
  14. alexer

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

    Reply
  15. kote

    Отличная работа.

    Только для деструктивного анализа правильнее анализировать не просто новый объект Форма, а ОТКРЫТЫЙ (можно невидимый) объект Форма..

    Разница в том, что если Вы в форму _программно_ добавили что либо, то пока не _запустишь_ её — анализатор Вам не покажет _программно_ добавленные элементы (в процедуре ПередОткрытием).. Я немного доработал — везде после получения объекта Форма (перед анализом) — открывал форму, после анализа — закрывал.. Все нормально получилось.

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

    Отдельное спасибо за открытый код разработки.

    Reply
  16. alexer

    (15) не буду против если кто-то продолжит тему этой обработки,

    т.к. времени на совершенствование и исправление багов нет

    Reply
  17. MRAK

    (16) такая же фигня!

    Reply
  18. AlexO

    (15) так поделились бы…..

    Или автору отправьте — чтобы вставил дополнение.

    Reply
  19. webranger

    ++ Спасибо. Очень полезный инструмент.

    Reply
  20. ASA1970

    спасибо, очень познавательно

    Reply
  21. serega3333

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

    Reply
  22. Kom-off

    Регулярно использовал данную обработку для анализа измененных реквизитов объектов (ништяк), при этом анализом форм не пользовался — не было необходимости, но вот она пришла. Понадобился простой и надежный анализатор изменения форм. Перебрал многие разработки на эту тему, остановился на этой. В алгоритме анализа форм не понравилось только одно: при формировании текстовых файлов со свойствами элементов формы не учитываются имена элементов формы при окончательной сортировке, т.е. получается (причину не стал искать), что позиция одного элемента в файле не соответствует позиции этого же элемента в файле другой базы, и при отображении сравнения файлов лезет много шума. Т.е. реально элементы формы не изменены, но их позиции в файлах различны. Лечится изменением строчки кода окончательной сортировки таблицы элементов:

    ТаблицаЭлементовФормы.Сортировать(«Панель,Страница,Тип»);

    на

    ТаблицаЭлементовФормы.Сортировать(«Панель, Страница, Тип, Имя»);

    Лично у меня захорошело неимоверно. Прошу автора подправить или обработку или меня.

    Reply

Leave a Comment

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