Инструмент обмена данными между БД с идентичными конфигурациями (OLE)




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

46 Comments

  1. АндрейКр

    Прошу прощения за отсутствие screenshot’ов. Обязательно поставлю в ближайшее время.

    Reply
  2. cs25

    wolfsoft-у конечно тоже ПЛЮС !!! НиНо рулит !!!

    Reply
  3. ValentinV

    Извините, но у Вас не указана версия 1с.

    Reply
  4. АндрейКр

    (3) Спасибо. Версию указал.

    Reply
  5. АндрейКр

    (2) Долго не мог понять, что значит «НиНо». Теперь понял 🙂 Просто поздно было. Исправлено.

    Reply
  6. АндрейКр

    Выпущен новый релиз — 1.31.1.2

    Изменения — в описании, выше.

    Reply
  7. АндрейКр

    Вновь новый релиз — 1.31.1.3

    Reply
  8. АндрейКр

    Новый релиз 1.31.1.4

    Скачало уже 121 человек, а комментариев и плюсиков почти нет.

    Reply
  9. wolfsoft

    > 6. Потенциально существует опасность бесконечной рекурсии при переборе реквизитов справочников только в случае, если значение ключа элемента справочника замыкается на этот же элемент (в последующих версиях попробую устранить эту проблему).

    Вроде не должно в «оригинале». Повторного переопределения одного и того же объекта не происходит, т.е. бесконечного цикла не должно получиться. Или я чего не продумал?

    ЗЫ: Комментарии к своей обработке читал, даже часть продублировал в «Обратной связи» http://www.1partner.nnov.ru/forum/index.php?fid=3&id=120082323675 для пользы дела.

    Reply
  10. АндрейКр

    (9)

    // ищем по ключу

    Если Ключ = «Код» Тогда



    ИначеЕсли Ключ = «Наименование» Тогда



    Иначе

    ОбъектПриемник.ИспользоватьРодителя(РодительОбъекта);

    Если ОбъектПриемник.НайтиПоРеквизиту(Ключ, ОпределитьОбъект(Объект.ПолучитьАтрибут(Ключ)), 0) = 1 Тогда

    Если ЗамещатьЭлементыСправочников = 0 Тогда

    ОбновитьРеквизиты = 0;

    КонецЕсли;

    Иначе

    СоздатьНовыйОбъект = 1;

    КонецЕсли;

    КонецЕсли;

    т.п. ОпределитьОбъект(…) используется до того как информация о найденом приемнике попадает в ТаблУжеВыгрОб.

    Таким образом, если Объект.ПолучитьАтрибут(Ключ) это сам объект, то получается бесконечная рекурсия.

    Reply
  11. АндрейКр

    Найдена ошибка при переносе реквизитов типа «Счет». Исправил. Проверяю. После проверки выложу релиз.

    Reply
  12. wolfsoft

    (10) Согласен. Хотя вероятность такого ключа мала. Он же по идее уникальный должен быть.

    (11) Суть ошибки?

    Reply
  13. АндрейКр

    (12) Ну это в моей обработке только. В твоей проверял. Там нету. Почему она возникает я так и не понял до конца.

    1. Почему-то некоторые документы переносились без заполненного реквизита типа счет. Причем если выгружать только этот тип документов, то все без проблем переносилось.

    Посмотрел в отладчике. Метод ОпределитьОбъект(…) действительно все правильно определял и возвращал. Метод УстановитьАтрибут(…) тоже выполнялся успешно. Но в результате все равно реквизит оставался пустым.

    Тогда я вернул функцию ОпределитьОбъектСчет(…) к тому виду как у тебя. И все заработало.

    Я ведь как делаю? Перед тем как установить атрибут — сравниваю значение этого атрибута у источника и у приемника. Если они совпадают, тогда вызываю метод ОпределитьОбъект(ЗначениеИсточника, …) (для рекурсии), а чтобы повторно не искался объект приемника (сравнение ведь прошло успешно) передаю туда и УжеНайденныйОбъектПриемника. Как только для счетов я убрал это, сразу все стало на свои места. Только все равно не понимаю, как из этого могла произойти ошибка.

    2. Перенес документы. Сверил — все совпало. Начал проводить — один бухгалтерский документ не проводится. Пишет на счете 207 недостаточно ТМЦ. Смотрю в итогах — остатки есть. А документ не видит. Начал отлаживать. В результате получил следующее: ТМЦ.Счет не равен счету из итогов, хотя коды счетов одинаковые.

    Причем ЗначениеВСтрокуВнутр(ТМЦ.Счет)={..}…{ 0000 73} ,а

    ЗначениеВСтрокуВнутр(СчетИзОстатков)={..}…{ 1879 73}. Ну примерно так. Как так могло получиться? Незнаю. ТМЦ был перенесен из источника.

    Наверное решение первой ошибки — есть решение и второй. Но я не уверен.

    Reply
  14. АндрейКр

    Релиз 1.31.1.5

    Изменения — исправления ошибок:

    !!! При установленном флажке «Помечать на удаление непроведенные новые» старые документы не помечались на удаление/не отменялись с удаления вообще. Исправлено.

    !!! В некоторых случаях не переносились реквизиты типа «Счет».

    Reply
  15. mihenius

    Название файла делай без пробелов ;0)

    Глюк движка сайта.

    Reply
  16. АндрейКр

    (15) У меня все нормально качается. А в чем глюк?

    Reply
  17. mihenius

    При скачке обрезает имя файла до пробела. )

    Может только в Firefox-е

    Reply
  18. АндрейКр

    Вышел новый релиз 1.31.1.6

    Значимые изменения:

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

    +++ В отчетах агрегатные объекты из базы приемника выводятся не как ”OLE”, а в виде [владелец] наименование — для справочников и ВидДокумента НомерДокумента ДатаДокумента для документов.

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

    *** Убрал все лишние сообщения из табло. Теперь в табло сообщений будет появляться только сообщения об ошибках.

    Очень хочется узнать ваше мнение о разработке.

    Возможно есть предложения по работе обработки или возникают какие-либо ошибки — пишите комментарии.

    На сегодняшний момент 691-но скачивание. А комментариев только 17.

    Reply
  19. АндрейКр

    Заметил интересную особенность. Если выполнить следующие команды:

    НачДата=’01.01.80′; //т.е. любая дата

    КонДата=’..’; //Или можно еще так: КонДата=ПолучитьПустоеЗначение(«Дата»);

    Док=СоздатьОбъект(«Документ»);

    Док.ВыбратьДокументы(НачДата,КонДата);

    То в выборку попадут все документы от даты указаной в НачДата до последнего документа в базе включительно.

    А если выполнить:

    Пер=СоздатьОбъект(«Периодический»);

    Пер.ИспользоватьОбъект(«КакойТоПериодРекв»,КакойТоЭлементСправочника);

    Пер.ВыбратьЗначения(НачДата,КонДата);

    То в такую выборку не попадет никогда ни одно значение.

    Чтобы в такую выборку попадали значения аналогично, как в выборку с документами, надо Пер.ВыбратьЗначения(НачДата);

    Reply
  20. Maxis

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

    Reply
  21. АндрейКр

    (20) Нет. Счета не переносятся. Сейчас постараюсь сделать.

    Reply
  22. mihenius

    ПриказОПриемеНаРаботу 23-к от 15.05.2006 1С:Предприятие: Номер не уникальный!

    *Записать 1 => 1С:Предприятие: Номер не уникальный!

    *Дата и время документа 15.05.06 => 1С:Предприятие: Номер не уникальный!

    +++ Приказ об увольнении 71к (31.07.2008)

    *** по собственному желанию, пункт 3 статьи 77 Трудового кодекса Российской Федерации

    *Фасет => 106

    ОбъектПриемник.УстановитьАтрибут(РеквизитИдентификатор,

    {\PROGPROGOLE131_15ИНСТРУМЕНТ ОБМЕНА ДАННЫМИ 1.31.1.5 (OLE).ERT(825)}: 1С:Предприятие: Не выбран элемент!

    Reply
  23. mihenius

    Притом номер уникальный, по ходу старый док не видит, и пытается создать новый

    Reply
  24. mihenius

    Еще _)

    Начата выгрузка:

    Если тблПриемникП.НайтиЗначение(ТекНачДатаПериодРекв,НомСтр,»Дата»)=0 Тогда

    {\PROGPROGOLE131_16ИНСТРУМЕНТ ОБМЕНА ДАННЫМИ 1.31.1.6 (OLE).ERT(916)}: Номер за пределами значения!

    Reply
  25. mihenius

    Обычный 131 работает нормально )

    Reply
  26. mihenius

    При переносе сотрудников Зик 285-Зик 285

    Неправильно переносит реквизит Пол.

    Reply
  27. Катя84

    скачала,попробую

    Reply
  28. gknipas

    При переносе документов «ввод расчета списку сотрудников» из ЗиК-288 в ЗиК-288 суммы округлились до рубля.

    Reply
  29. Hellgard

    Начата выгрузка:

    ОбъектПриемник.Родитель = РодительОбъекта;

    {C:DOCUMENTS AND SETTINGSВЛАДЕЛЕЦРАБОЧИЙ СТОЛНОВАЯ ПАПКА (5)ИНСТРУМЕНТ ОБМЕНА ДАННЫМИ 1.31.1.6 (OLE).ERT(785)}: 1С:Предприятие: Неверное значение!

    Что это означает??

    Reply
  30. АндрейКр

    (29) У меня тоже такое часто бывает. Похоже это не ошибка в обработке — а ошибка в технологии ole. Я в таком случае выключаю 1С и делаю обмен еще раз.

    Reply
  31. borman

    Минус ставить не буду, не разбирался подробно. Но с наскоку воспользоваться не вышло :(.

    Reply
  32. АндрейКр

    (31) А в чем причина? Не запустилась или ошибка какая?

    Reply
  33. VGHOST

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

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

    Reply
  34. knigula

    Спасибо. Очень помогло при поломке базы. Перенес объекты за 2 дня в имеющийся архив.

    Reply
  35. centr1

    Здравствуйте!

    Мне нужна обработка для выгрузки отражения зарплаты в регл. учете из ЗУП в УСН..данная обработка может мне помочь? И как я могу скачать ее?

    Reply
  36. VGHOST

    Эта обработка для v7, на платформе v8 не работает.

    Тут обработка конвертации данных нужна. Если в ЗУП встроенной нет, надо писать.

    Можно воспользоваться конфигурацией «Конвертация данных» с диска ИТС.

    Reply
  37. junglistizzy

    Спасибо! Ваша обработка — чудо!

    Reply
  38. АндрейКр

    (34)(37) Рад что понравилась! Спасибо!

    Reply
  39. chetirepda

    (38) Молодец, достойная обработка, жирный плюс Вам и большое спасибо!

    Reply
  40. alex_gus

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

    Reply
  41. VGHOST

    (41) alex_gus, чтобы ошибок было меньше, нужно присылать хотя бы название конфигурации и тексты сообщений об ошибках. Да и скриншоты закладок обработки с настройками не помешали бы.

    Reply
  42. maksimka1970

    Андрей, спасибо огромное, так вы помогли))

    Reply
  43. АндрейКр

    (39)(43) Спасибо за отзывы! Рад, что помог.

    Reply
  44. Minovich_losha

    Пожелания:

    1. Вывести флаг вывода трассировочных сообщений на форму. Без них быстрее работает.

    2. Контролировать длину выводимых сообщений. Если более 500, то платформа выдает модальное окно «получаемая строка превысит допустимые размеры».

    Reply
  45. TrinitronOTV

    Период, по которому будет выполняться обмен, в вашей обработке можно задавать?

    Reply
  46. АндрейКр

    (46) TrinitronOTV, Да. На вкладке «Выгрузка» группа элементов «Период». Еще посмотрите на вкладке «Настройка» — «Период новых документов».

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

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

    Reply

Leave a Comment

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