Перенос данных 1С:Предприятие 7.7




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

34 Comments

  1. lexkex

    Могут быть баги, не судите строго

    Reply
  2. Tatitutu

    добавь пожалуйста описание архива — «ПереносДанных», там 5 файлов.

    Reply
  3. lexkex

    Сори

    В архиве 5 файлов

    1. 1Сv7.md — файл конфигурации содержащий документ по средством, которго можно переносить движения документов которые не проводяться

    2. ВыборСтрокиФильтра.ert — обработка запускаемая из основной формы, для выбора фильтра при переносе данных

    3. ЗагрузкаОбъектовОле.ert — основная форма обработки по переносу данных

    4. РедакторДокументов.ert — обработка запускаемая из основной формы

    5. РедакторФильтра.ert — обработка запускаемая из основной формы

    При отсутсвие каких-либо второстепенных обработок отключаются некоторые функции в основной форме

    Reply
  4. x-arogov-x

    Будем тестить.

    Reply
  5. victuan

    хм

    Reply
  6. volna

    Надо опробовать. Что можно сказать про историю ОС?

    Reply
  7. Тренер

    Удачи!

    Reply
  8. d.snissarenko

    «по средством» «пишетцо» как «посредством», наверное, кажется так, а в целом +

    http://habrahabr.ru/blogs/pishu_pravilno/40434/

    Reply
  9. WKBAPKA

    и все таки конвертация помощнее будет 🙂

    Reply
  10. lexkex

    Просто программа разрабатывалась для восстановления данных из базы данных Торговля + Склад, а после этого и комплексной. В конечном итоге этой обработкой я восстановил около 6-7 БД. Да и зачем сидеть собирать правила если БД идентичные ))

    Reply
  11. 1CBars

    Обработка может перенести справочники из комплексной 7.7 в бухгалтерию 7.7

    Reply
  12. 1CBars

    Это вопрос )

    «?» забыл поставить

    Reply
  13. lexkex

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

    Reply
  14. АлексЧ

    СПАСИБО!

    Reply
  15. Грузефина Тапочкина

    Самое интересное поставила я на загрузку все ревизиты… Не переносит ничего кроме наименования… вот так..

    Reply
  16. Грузефина Тапочкина

    Но все же ОГРОМАДНОЕ СПАСИБО…. Немножко может подправлю!!!

    Reply
  17. lexkex

    (16) Странно

    — иногда бывает что не переносит какие-то реквизиты, но это связано с периодикой реквизитов, иногда помогает повторная загрузка

    — Обязательно нужно указать чтоб загружались справочники по ссылкам

    — Обязательно нужно указать чтоб создавались новые элементы

    Для более полного ответа необходимо указать более подробное Ваше описание действий с обработкой, конфигурацию БД, релиз, типовая или измененная, платформу 1С, и объем переносимой информации в количестве объектов, по возможности выложить скрин настроек которые были произведены перед загрузкой

    Reply
  18. lav_andrew

    В Функция ПолучитьСправочник(…) ошибочка, надо заменить

    Если ПУстоеЗначение(Родитель) = 0 Тогда

    Спр.ИспользоватьРодителя(Родитель);

    КонецЕсли

    на

    Если ПУстоеЗначение(Родитель) = 0 Тогда

    Спр.ИспользоватьРодителя(Родитель);

    ФлагПоискаПоКоду = 1;

    КонецЕсли

    Reply
  19. lexkex

    (18) Обоснуйте пожалуйста, я считаю Ваш вариант не правильным

    Reply
  20. lav_andrew

    (19) Всё очень просто. У вас переменная «ФлагПоискаПоКоду» используется для того, чтобы определить, учитывать ли в поиске иерархию или нет, но при этом только для подчинённых справочников. Метод ИспользоватьРодителя() влияет только на метод ВыбратьЭлементы() и не повлияет на методы НайтиПоКоду() и т.п. при флаге Режим = 0 в этих методах. Исходя из кода обработки и самих типовых конфигураций в итоге поиск в основном происходит по коду. А так как данные могут переноситься из разных баз, то возможность совпадения кодов у абсолютно разных элементов справочников очень вероятна. Тут несколько вариантов.

    1. Мой вариант, как самый простой, но и не самый идеальный. Будет выдавать ошибку и ничего «плохого» с результирующей базой не случится, в противном случае и справочники можно испортить и движения.

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

    3. Создавать новые элементы и соответственно искать с префиксами в коде, ну а для наименований можно сделать постфикс.

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

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

    Reply
  21. lav_andrew

    Добавлю пример:

    Справочник «Сотрудники».

    База 1 Код 00001 Наименование Вася

    База 2 Код 00001 Наименование Петя

    В Базу 1 надо добавить Петю из Базы 2, причём по ссылке, и мы заранее не знаем, нам это не интересно, есть ли в Базе 2 Петя или Гоша. Если оставить как есть, то:

    1. Петя просто заменит Васю.

    2. Вася останется и будет в движениях вместо Пети.

    Reply
  22. lexkex

    (20) Метод ИспользоватьРодителя() устанавливает родителя при создание нового элемента справочника вроде бы… хотя я могу ошибаться. Задача данной обработки сделать базы идентичными… Хотя я бы не стал загружать справочники в другую папку и не стал создавать элементы справочников с другими кодами т. к. при добавление элементов справочника в источнике коды опять будут не совпадать с наименованием. Или при изменение наименования в БД источнике в справочник приемника будет добавлен новый элемент, что ни есть правильно. Тем более при отсутствие кода и наименование синхронизация происходит по первому реквизиту с сортировкой, что тоже не работает в некоторых случаях. В каждой ситуации есть свои нюансы, я предлагаю типовое решение, которое можно дополнить или изменить

    Reply
  23. lexkex

    (21) А если мы добавим Петю с новым кодом, то во все документы, которые будут загружаться после этого вместо пети будет в любом случае попадать Вася

    Reply
  24. Jamez

    а мне вот что при переносе справочника материалов выдает:

    Спр.ИспользоватьРодителя(Родитель);

    {E:AGRUZKAЗАГРУЗКАОБЪЕКТОВОЛЕ.ERT(786)}: Неверное значение!

    не подскажете, шо ента?

    Reply
  25. lexkex

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

    или

    попробуйте вставить эти строки вместо строки №786

    Если ТипЗначенияСтр(Родитель) = «Справочник» тогда

    Если (Родитель.Вид() = ВидСпр) и (Родитель.ЭтоГруппа() = 1) тогда

    Спр.ИспользоватьРодителя(Родитель);

    КонецЕсли;

    КонецЕсли;

    Reply
  26. FIZIK

    В избранное, экономит тучу времени.

    Reply
  27. alfia

    Спасибо

    Reply
  28. ann_ver

    спасибо большое! полезная обработка

    Reply
  29. ann_ver

    спасибо! экономит время

    Reply
  30. Pitot

    Спасибо большое, Очень полезная штука, рекомендую.

    Reply
  31. piffoff

    пользуюсь не нарадуюсь. Еще б найти такую же простую но для перенома даных из 8 — ки в 8 — ку

    Reply
  32. Vich88

    Хорошая обработка, уже скачала и попробовала. Мне нужно было выгрузить только кассовые документы и Voila они перенесены без проблем. Единственной я бы написала инструкцию к использовантию :))) для чайников.

    Reply
  33. tehas99

    не плохо, сенк

    Reply
  34. corsar4ik

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

    Reply

Leave a Comment

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