Сравнение документов любых конфигураций




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

18 Comments

  1. makas

    Обработка в базах SQL (УТ и БП) будет сравнивать документы?

    Reply
  2. Stavsles

    Да, там есть возможность выбора файловой или серверной базы.

    Reply
  3. ceramica

    А для УФ будет? Хотелось бы так, как тенденция всеобщего перехода на УФ прогрессирует

    Reply
  4. Stavsles

    (3) ceramica, В ближайшее время точно не будет. У меня не хватает времени взяться за переработку этой обработки. Но в будущем вполне возможно что сделаю.

    Reply
  5. Stavsles

    (5) Yimaida,

    Добрый день! Обработка сравнивает справочники по наименованию. Имеется возможность выбора реквизитов для сравнения, например если из одной базы документы перебрасываются в другую на другую организацию, то можно просто исключить этот реквизит из проверки и обработка не будет по нему искать различия. В случае, когда поменялся порядок строк обработка выдаст сообщение о том, что строки различаются, сопоставление идет по номеру. Посмотрев на подробный отчет вы можете легко понять, что кроме порядка ничего не поменялось.

    Reply
  6. Yimaida

    Добрый день.

    Stavsles, опишите, пожалуйста, как идет сопоставление (сравнение) справочников. А так же как отрабатывается ситуация перемешивания строк в документах, т.е. когда поменялся порядок строк.

    Reply
  7. dassin

    Спасибо за работу. Обработка пригодилась, хотя снимать галочки по полям было неудобно. В открывающемся диалоговом окне «Список полей для выбора» неплохо бы добавить возможность снятия пометок со всех полей (и наоборот), потому что по всем абсолютно полям не всегда нужно сравнивать. Зачем нужен раздел «дополнительные поля» совсем непонятно. 🙂

    Reply
  8. Stavsles

    (8) dassin,

    Рад что обработка пригодилась! По галочкам в контексте моей задачи как раз необходимо было сравнение по всем полям, исключая лишь некоторые, поэтому о кнопке убрать все и отметить все я сразу и не подумал. Дополнительные поля необходимы для удобства просмотра найденных различий по документу непосредственно на форме обработки, в табличной части «Обнаруженные различия».

    Reply
  9. Tanka07

    Здравствуйте! Очень нужна данная обработка, но не могу с ней справиться, выдает ошибку:

    {Форма.Форма.Форма(833)}: Ошибка при вызове конструктора (ComObject)

    ComConnection = Новый ComObject(СтрокаВерсияКоннектора);

    по причине:

    Недопустимая строка с указанием класса

    Пытаюсь сравнить две базы Бухгалтерия предприятия, редакция 2.0 (2.0.64.20)

    Файловая версия

    Пользователя указываю, он без пароля

    Пробовала когда вторая база не запущена и когда запущена, ошибка одна и та же

    Платформа: 8.2.19.102

    Win 7

    Reply
  10. Tanka07

    Все работает. нужно было зарегистрирвоать comcntr.dll

    Reply
  11. mikepin

    Супер!

    Reply
  12. armeec

    Проблемная часть обработки (стр. 240-256) (Превращает реквизит типа Счет плана счетов из ,например, «60.02» просто в «60» ->Число->Окр->Строка….):

    ЗначениеПодключеннойБазы = ПодключеннаяБаза.String(ВыборкаДокументовПодключеннойБазы[Реквизит.Значение]);

    //

    //Если ЗначениеПодключеннойБазы = «Да» Тогда

    // ЗначениеПодключеннойБазы = «истина»;

    //КонецЕсли;

    //Если ЗначениеПодключеннойБазы = «Нет»

    // Тогда ЗначениеПодключеннойБазы = «ложь»;

    //КонецЕсли;

    Если Не(ЗначениеПодключеннойБазы = «истина» или ЗначениеПодключеннойБазы = «ложь») Тогда

    Попытка

    ЗначениеПодключеннойБазы = Число(ЗначениеПодключеннойБазы);

    ЗначениеПодключеннойБазы = Окр(ЗначениеПодключеннойБазы,ВидДокументаОбъект.Реквизиты[Реквизит.Значение].Тип.КвалификаторыЧисла.РазрядностьДробнойЧасти);

    ЗначениеПодключеннойБазы = Строка(ЗначениеПодключеннойБазы);

    Исключение

    КонецПопытки;

    КонецЕсли;

    Reply
  13. Yha

    Сергей, попробовала добавить в ERP 2 (2.2.2.157) , программа не дает добавить обработку. На ERP не работает???

    Reply
  14. Stavsles

    (14) Обработка работает только в режиме обычного приложения.

    Reply
  15. German_Tagil

    Я понимаю что времени уже много прошло

    все работает только одно но …

    при исправлении документа шапка документа стирается

    табличная часть копируется

    в Процедуре КонтекстноеМенюИсправитьДокумент(Кнопка)

    ЗаполнитьЗначенияСвойств(ДокОбъект, ДокКомОбъект,,»Номер»);

    не заполняет реквизита

    год назад подступался — было некогда сейчас решил добить

    Reply
  16. Stavsles

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

    Reply
  17. German_Tagil

    конфигурации одинаковые — но вот почему то не работает

    Reply
  18. Stavsles

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

    Reply

Leave a Comment

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