Синхронизация документов и справочников




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

36 Comments

  1. PowerBoy

    Сделал сравнительный тест на скорость:

    SQL подключение — проверка 70000 документов за 10 мин. ср. ск-ть = 7000 д/м

    OLE подключение — проверка 15000 документов за 150 мин. ср. ск-ть = 100 д/м

    Вывод скорость проверки SQL сервером в 70 раз быстрее, и это при том, что SQL сервер еще проверял движения.

    Тесты делал на XEON E5410 (2,33GHz x 4) 8Gb , Бухгалтерия 1.6 (9Гб)

    Reply
  2. WiseSnake

    Обработка по описанию вроде классная, но никак не могу понять где ее можно применить. Как бы для этого УРБД есть…

    Подскажите пожалуйста, как Вы ее применяете?

    Reply
  3. PowerBoy

    (2)

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

    2.Одностронний обмен между базами без УРБД. Сравниваете две базы и высылаете разницу между ними.

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

    Можно и еще придумать.

    Reply
  4. np248

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

    Reply
  5. PowerBoy

    (4) Значит конфигурации различаются.

    Reply
  6. WKBAPKA

    2(5): Насколько надежная обработка?

    Reply
  7. PowerBoy

    (6) Использую уже месяц, косяков не замечал. Если найдете — пишите.

    Reply
  8. WKBAPKA

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

    Reply
  9. snic

    Поставил минус за «принуждение к голосованию».

    Обработка мне не пригодилась, почему я должен ставить плюс?

    Reply
  10. PowerBoy

    (9)Какая разница где голосовать, на сайте или в обработке. Это просто дополнительный удобный сервис. В каком месте тебя принудительно заставили ставить плюс?

    Reply
  11. Cyberboy

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

    Reply
  12. artbear

    (0) Есть ли возможность простого сравнения данных, без синхронизации и переноса/изменения данных ?

    Reply
  13. swimdog

    Неплохо было бы автора начальной версии указать

    Reply
  14. PowerBoy

    (13) И так по форме видно, что это доработанная типовая от 1С. + моя SQLPlus.

    Reply
  15. ol_2004

    При выгрузке произошла ошибка (Версия ЗУП 2.5.18.2, подключено через SQL) :{ВнешняяОбработка.СинхронизацияДокументовИСправочников(2912)}: Ошибка при вызове метода контекста (Open): Произошла исключительная ситуация (Microsoft OLE DB Provider for SQL Server): The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.

    по причине:

    Произошла исключительная ситуация (Microsoft OLE DB Provider for SQL Server): The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.

    Ошибка при выгрузке документов. справочник физических лиц перегружает

    Базы идентичные.

    Подскажите, из-за чего ошибка?

    Reply
  16. PowerBoy

    (15) По тексту ошибки — неверный тип даты документа или пустая?

    Может еще настройка формата даты на MS SQL server.?

    Reply
  17. sin_lgm

    при попытке выгрузить данные вышло вот такое сообщение об ошибке

    {ВнешняяОбработка.СинхронизацияДокументовИСправочников(2912)}: Ошибка при вызове метода контекста (Open): Произошла исключительная ситуация (Microsoft OLE DB Provider for SQL Server): Неправильный синтаксис около «.».

    по причине:

    Произошла исключительная ситуация (Microsoft OLE DB Provider for SQL Server): Неправильный синтаксис около «.».

    Выгрузить(как видно из сообщения) пыталась, подключившись к MS SQL.

    Я правильно поняла, что выполнение идёт по-этапно, сначала нужно выгрузить, а потом загрузить, что эти операции не производятся одновременно?(читается и сразу пишется)

    Reply
  18. PowerBoy

    (17) 1)Неправильно настроено соединение с SQL сервером

    2)Да

    Reply
  19. gagar9

    не как не могу выгрузить контрагенты для переноса другой базы пожалуиста сделайте документ каторий показывает пошаговой инструкция или помогите настроить обработку . Очен полезный обработка просто не могу разбиратца

    Reply
  20. PowerBoy

    (19) Базы должны быть однородными. Для простого переноса справочника лучше воспользоваться обработкой: http://infostart.ru/public/14887/

    Reply
  21. samamoiloff

    Не работает под 8.2, вместо Новый COMОбъект(«V81.Application») надо Новый COMОбъект(«V82.Application»)…

    Было бы классно, если добавить возможность загрузки данных непосредственно в Приемник (без файла), как в Выгрузка Загрузка Данных COM-XML v8.1

    Reply
  22. kostyaka

    обработка работает, все ок. но появилась одна проблема с кодами в спр. номенклатуры

    при загрузке указал префикс «S» для документов и справочников, чтобы в последствии видеть какие элементы были добавлены в базу.

    все загрузилось нормально, все видно.

    только сейчас почему-то при создании новой номенклатуры код присваивается типа «S00011513», а код до загрузки был типа «00000012044».

    при создании новых накладных и тд таких проблем нет.

    Reply
  23. Lacrimosa0000

    Присоединяюсь к (21)

    Reply
  24. Alav

    Присоединяюсь к (12)

    Нужна функция тестирования, когда данные не выгружаются, а информация о различиях выводиться в текстовый файл

    Reply
  25. Alav

    Странно, решил протестить, а он в ответ

    {ВнешняяОбработка.СинхронизацияДокументовИСправочников.МодульОбъекта(2912)}: Ошибка при вызове метода контекста (Open)

    по причине:

    Произошла исключительная ситуация (Microsoft OLE DB Provider for SQL Server): Недопустимое имя столбца «_Fld498».

    Подключался через скуль (подключился успешно). Базы точно на одном скуле и это конфигурации одинаковы (УРИБ копия)

    Reply
  26. Gerda999

    Попробовала в Бух 1,6 (8.1.10.50): «Ошибка загрузки документа. Внешняя обработка на может быть прочитана текущей версией программы».

    Где я накосячила?

    Reply
  27. fornasov

    спасибо

    Reply
  28. fornasov

    спс

    Reply
  29. yushmakovmv

    Спасибо, очень пригодилась.

    Reply
  30. Владимир Зайцев

    Вполне надёжна

    Reply
  31. Vincent Vega

    Отлично работает, спасибо!

    Reply
  32. yar555

    спасибо, использовал

    Reply
  33. Volga1904

    нужная обработка

    Reply
  34. EugenLiquor

    По комментариям понял, что нет поддержки 8.2, оттого пользы никакой…

    Reply
  35. bb1962

    Еще и модуль защищен. Об этом предупреждать надо.

    Reply
  36. PowerBoy

    (36)Убрал пароль с модуля, добавил версию для 8.2.

    Reply

Leave a Comment

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