Автообмен 8.1 (за 15 минут)




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

26 Comments

  1. artbear

    (0) Цитата:

    «Далее усложним задачу и разберем ситуации когда есть уже 2 базы (допустим в разных магазинах, и бухгалтер захотела получить их себе в автообмене, при том в одной базе – полностью все «подводные камни»).»

    ГДЕ?

    Reply
  2. dmv78

    Ну это далее… Имеется ввиду сейчас сформирую примерную задачу и дам реализацию!

    Сделаю! К воскресенью будет…

    Reply
  3. Abadonna

    На днях делал, потому сразу могу сказать:

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

    2. Не рассмотрен вариант одностороннего обмена — когда в периферийку надо закинуть данные, а в централке надо проигнорировать, но так, чтобы она получила сообщение, что периферийка приняла (т.е. обмен состоялся)

    Reply
  4. WKBAPKA

    2(4): а в 2 без программирования не обойтись 🙂

    Reply
  5. Abadonna

    (5) К сожалению, блин, оказалось, что и по [1] не обойтись (во всяком случае на файловой).

    Был глючок с паролем на блокировку базы. Но там все без пофигуратора делается

    Reply
  6. Evilleo

    Хорошая публикация, есть пара комментариев:

    1. Опыт показал что при обмене лучше использовать не почту, а ftp сервер, т.к.

    а) сообщение почты может попадать в спам, да и долго идти

    б) при изменении конфигурации центрального узла, обычно формируется файл обмена размером 35-80Мб. Такое просто не пройдет по почте, тем более каждые 360 сек, это просто убьет ящик да и канал интернета надолго. Через ftp еще более менее можно пережить этот неприятный момент.

    2. Конечно, когда стоит задача видеть он-лайн остатки, вариантов немного — нужен обмен постоянно. Но для более простого варианта, когда достаточно ежедневного обмена, лучше настроить выполнение автозагрузки при входе определенного пользователя в базу и автовыгрузку при выходе из базы.

    Reply
  7. glinmn

    Присоединяюсь к Evilleo.

    Лучше работать по Ftp.

    НО с одним замечанием ,НЕ НАЗЫВАЙТЕ узлы русскими буквами. У FTP клиента 1с 8.1 глюк с не которыми FTP серверами, например SERV-u, ну не как не хочет понимать русские буквы в названии файла, с другими FTP клиентами все OK.

    Reply
  8. Agema

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

    Reply
  9. anTony86

    где была эта статья, когда я месяц назад как-раз рылся в этих процедурах и функциях?! 😀

    Reply
  10. sinchick

    Желтая книжка «Конфигурация Управление торговлей, редакция 10.3 Описание»

    Глава 20, стр. 807

    Там тоже самое только на примере юсб-флэшки.

    Вот про второй вариант уже интереснее 😉

    Reply
  11. red80

    А как обновлять конфигурацию на периферийной базе показано? Картинок нет. Тоже стандартно делается, через Сервис -> Обновление через интернет.

    Reply
  12. Tarlich

    Хотя и так знаю но все равно + 😀

    Reply
  13. slaviksoft

    +1

    Reply
  14. alferov.oleg

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

    Еще есть вопрос по обмену, правда по Рознице, но не суть… В Рознице в настройках пользователя ИБ каждому пользователю можно добавить роль Автообмен. Но все равно обмен возможен только под пользователем, прописанном в учетной политике. Бред. Мне было бы удобно, если не зависимо от пользователя, который работает в программе, автообмен выполнялся по расписанию без танцев с бубном…

    Reply
  15. pvav

    А как организовать обмен «по расписанию» не используя «ручной» запуск базы под пользователем Автообмен? С использованием штатного виндового планировщика заданий? Т.е. чтобы в определенное время происходил процесс «Запуск-Обмен-Отключение». В 7-ке это можно реализовать с помощью запуска командного файла или скрипта с параметрами и prm-файлом. Можно ли такое же замутить на 8.2 (файловый вариант)?

    Reply
  16. Sairys

    Отличная статья, после неё можно более менее понять что такое обмен и что такое распределённые базы данных в 1с предприятии

    Reply
  17. slavich

    Отличная статья, но как написал (pvav) тоже интересно как можно реализовать с помощью скрипта именно (Запуск-Обмен-Отключение). Реализацию сделал, но возникла именно проблема Отключения.

    Reply
  18. stark.temp

    Вотт если бы опубликовали статью раньше! Долго сам пробовал. Статья дельная!

    Reply
  19. BAPPKAH

    Отличная статья

    Reply
  20. Программулькин

    не показано как настроить авто-обмен в случае, например, после обновления центральной базы, или внесения изменений в конфигурацию. «-» минус!

    Reply
  21. dmv78

    (23) Программулькин, молодой человек, если вы ещё всё рассматривать будете через призму 7.7., то вам тут придется минусы ставить на все статьи по 8.2. К вашему сведению это обновление происходит автоматически после того как обновляется Центральная база. И расписывать эту автоматическую операцию, по моему мнению необходимо только для «даунов», Ваш минус это минус себе. Изучайте внимательнее возможности 8.2. Во вторых — эта статья не для программистов, а для пользователей, там по моему сверху написано это изначально, а раз это не программист — то о каких доработках и изменениях может идти речь??? А программист он и так знает механизм обновления… В общем даже не знаю что вам ещё сказать — BAD.

    Reply
  22. Alav

    (24) А можно поподробнее, а то я по старинки бантики пишу (собственна типовая БП делает тоже самое, пишет cmd файл где вызывает саму себя с параметром обновить ИБ). Где почитать про возможности платформы (!) в плане автоматического обновления?

    Reply
  23. dmv78

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

    Reply
  24. sphomin

    Настраивал обмен с несколькими магазинами через Open VPN т.к. FTP or E-mail не дают гибкости в растройки по событию.

    Например у меня настроено так:

    Бухгалтеру/руководителю захотелось получить актуальную инфу из УРИБ они жмут кнопку Хи программа выгружает файл обмена в каталог-Клиентская программа (та с которой нужно сделать обмен) увидив этот файл загружает его и формирует свой файл выгрузке — а свое время программа Бухгалтера/рук. увидев этот файл — загружает его — воля! Нажатие всего одной кнопки и обмен готов, и нет никаких расписаний (я не против расписаний но при появлении оних — на клиентских машинах когда начинается обмен все операции временно блокируется — что раздражает пользователя и клиента (подождите у нас обмен пошел — пфф), а в моём случае обмен по надобности в ином случае — настраиваем фоновый обмен).

    Пишите в п.м. если есть вопросы — оних индивидуально.

    Reply
  25. skyadmin

    Обмен я настроил с помощью GoogleDrive.

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

    На периферии в настройках GoogleDrive указано, что синхронизировать только свою папку.

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

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

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

    Как этого избежать, делать обмен по ночам? А если мне нужен обмен каждый час?

    У меня Конфигурация Штрих-М Торговое предприятие 5, не имеет возможности загрузки при наличия файла.

    Кстати убогая конфигурация, никому бы не посоветовал…

    Reply
  26. bas_nsk

    (28) skyadmin,

    Цитата:

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

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

    Не удалится, из регистрации удалятся только принятые объекты. Он перенесется при следующем обмене.

    Reply

Leave a Comment

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