Обработка для замены ссылок (дублей) без перепроведения в "1С:Предприятие 8" для любых конфигураций (обычное приложение)




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

    А каким образом происходит поиск ссылок?

    Reply
  2. tunesoft

    (1) pepe, генерируется текст запроса 1С по всем метаданным только по реквизитам, содержащим тип ссылки и отбором по значениям «Источник».

    Фрагмент этой функции видно на скрине:

    Reply
  3. karpik666

    (2) так, а чем стандартный поиск дублей не угодил или из инструментов разработчики, да и на худой конец «Поиск и замена значений» , что на диске ИТС? Все это работает без перепроведения документов.

    Reply
  4. insurgut

    Так это же стандартная обработка с диска ИТС поиска и замены значений, которая точно так же напрямую в движениях заменяет ссылки без перепроведения документов. Куда смотрят модераторы?

    Reply
  5. tunesoft

    (3) karpik666, согласен, варианты есть, но они не совсем подходят для наших задач.

    В нашей обработке упор больше сделан на строгость, правильность замены данных (человеческий фактор), а также на большие объёмы данных.

    Сейчас регламент работы с данной обработкой следующий: один сотрудник (бухгалтер) в отдельно специализированной обработке «Поиск дублей» готовит список замен, далее выгружает список во внутреннем представлении в файл, далее этот список у себя открывает главный бухгалтер и утверждает, далее список пересылается программисту, программист загружает файл в обработку «Замена ссылок», формирует необходимые отчёты до замены, выполняется замена и т. д.

    Ещё в типовой обработке «ПоискИЗаменаЗначений.epf» с диска ИТС выполняется поиск объектов через стандартную функцию «НайтиПоСсылкам», и далее в цикле выполняется перебор всех реквизитов объектов с проверкой на тип и содержание:



    Для Каждого Реквизит Из СтрокаТаблицы.Метаданные.Реквизиты Цикл

    Если Реквизит.Тип.СодержитТип(ТипЗнч(Ссылка)) И Параметры.Объект[Реквизит.Имя] = Ссылка Тогда





    Для Каждого ТЧ ИЗ СтрокаТаблицы.Метаданные.ТабличныеЧасти Цикл

    Для Каждого Реквизит Из ТЧ.Реквизиты Цикл

    Если Реквизит.Тип.СодержитТип(ТипЗнч(Ссылка)) Тогда



    это будет медленно при большом количестве объектов для замены.

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

    Далее выполняется замена ссылок уже по заранее полученным именам таблиц, табличным частям и реквизитам, без излишних проверок в циклах.

    Reply
  6. tunesoft

    (4) insurgut, совсем не стандартная, основные отличия описаны в предыдущем комментарии.

    ещё избыточные циклы и проверки в типовой обработке «ПоискИЗаменаЗначений.epf»:

    Для Каждого ТЧ ИЗ СтрокаТаблицы.Метаданные.ТабличныеЧасти Цикл

    Для Каждого Реквизит Из ТЧ.Реквизиты Цикл

    Если Реквизит.Тип.СодержитТип(ТипЗнч(Ссылка)) Тогда

    СтрокаТабЧасти = Параметры.Объект[ТЧ.Имя].Найти(Ссылка, Реквизит.Имя);

    Пока СтрокаТабЧасти <> Неопределено Цикл

    (3) karpik666,

    >»или из инструментов разработчики»

    внутрь кода не смотрел, но в описании публикации указано «основано на обработке «ПоискИЗаменаДублирующихсяЭлементов» с ИТС»

    Reply
  7. tunesoft

    На двух одинаковых тестовых БД «Бухгалтерия 2» запустил разные обработки, в одной типовую «ПоискИЗаменаЗначений», в другой нашу, настроил одинаковые элементы для замены.

    Через несколько секунд «ПоискИЗаменаЗначений» выдала сообщение и прервалась:

    Существуют документы, оформленные по договору «Договор №… от 01.01.15г.».

    Контрагент договора не может быть изменен, элемент не записан.

    Не удалось записать «Договор №… от 01.01.15г. (Договоры контрагентов)»!

    Наша обработка успешно завершила выполнение за несколько минут, при этом в журнал регистрации добавлены сообщения вида «Замена <Справочник.Контрагенты;Почта;005;7cba181e-335b-11e4-a84f-001f29081c26> на <Справочник.Контрагенты;Почта России;000011;4a9b2d6c-26b0-11df-97a9-001d7d9bbaae> в таблице <Справочники.ДоговорыКонтрагентов>», данные «Договор №… от 01.01.15г.».

    Reply
  8. insurgut

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

    Reply
  9. tunesoft

    (8) insurgut, это знаю, с 1С работаю более 15 лет, смысл в том, что в исходном варианте обработка «ПоискИЗаменаЗначений» не заменяет ссылки и нет флажка на форме чтобы включить режим «ОбменДанными.Загрузка = Истина»

    Reply
  10. karpik666

    (9) что то непонятно, с 1С более 15 лет, так зачем тогда приводите такое сравнение, или вы думаете, что квалификация посетителей сайта не позволит сказать в чем различия таких данных? Стандартная «поиск и замена значений» предусматривает обмен данными загрузка, просто почему то разработчики не удосужились просто вывести параметр на форму, переделывается это в течении 5 минут, достаточно в функцию замены передавать параметр, что выполнять без проверок. Вам говорят вы изобрели велосипед, притом, что есть уже точно работающие инструменты, и не для одних справочников, а также ПВР, ПВХ, планов счетов, Задач и т.д. А по поводу инструментов, это очень сильно переработанная обработка с ИТС, так как заменяет не только ссылки, но и позволяет оценивать регистры сведений, чтобы не было ошибки на уникальность строк.

    Reply
  11. tunesoft

    (10) karpik666,

    >и не для одних справочников, а также ПВР, ПВХ, планов счетов, Задач и т.д.

    В нашей обработке тоже есть аналогичная возможность, сейчас в форме в типе элемента явно указано «Справочник», раньше было «Любая ссылка», можно снова выбрать мышкой «Любая ссылка»

    >А по поводу инструментов, это очень сильно переработанная обработка с ИТС, так как заменяет не только ссылки, но и позволяет оценивать регистры сведений, чтобы не было ошибки на уникальность строк.

    Отлично.

    Тоже заменяем в регистре сведений.

    >Вам говорят вы изобрели велосипед

    Ну и замечательно.

    Обработки разные, работают по-разному, и вообще изобретать «велосипеды» полезно 🙂

    Reply
  12. karpik666

    (11) ладно будь по вашему, может кому то пригодится.

    Reply
  13. pepe

    (12) karpik666, Нужно проверить эту обработку, думаю она быстрее работает. Стандартной обработка на моей базе тупо виснет. Через запросы более эффективнее, только сложность, что нужно разбирать метаданные.

    Reply
  14. tunesoft

    (13) pepe,

    >Стандартной обработка на моей базе тупо виснет.

    Не должна зависать.

    В другой сессии 1С в журнале регистрации смотрели запись транзакций фиксируется ?

    База файловая или SQL ? Какой размер БД ?

    Пробовали выполнить в конфигураторе «Администрирование — Тестирование и исправление» ?

    Reply
  15. pepe

    Это проблема размера базы, база уже 600 гбайт. Тестирование и исправление делали относительно не давно.

    Reply
  16. gulchitai

    (5) tunesoft. Вы пишите про обработку «Поиск дублей», который готовит список замен, она есть на инфостарте? Как ее можно получить?

    Reply
  17. tunesoft

    (16) gulchitai, какие-то были, можете через поиск найти.

    Reply
  18. gulchitai

    (17) Свою написала )

    Reply
  19. gulchitai

    Замена ссылок происходит не в режиме ОбменДанными.Загрузка = Истина? При замене появляются сообщения об ошибках, которые у нас вставлены в подписки на события, в них есть такая проверка

    Если Отказ ИЛИ Источник.ОбменДанными.Загрузка Тогда
    Возврат;
    КонецЕсли;

    Но кажется мы в нее не попадаем… В коде посмотреть не могу, т.к. обработка защищена паролем

    Reply
  20. tunesoft

    (19) gulchitai, запись выполняется в режиме «.ОбменДанными.Загрузка = Истина», но в случае изменения регистра сведений без регистратора используется менеджер записи, у которого нет «ОбменДанными». Почему используется «МенеджерЗаписи», а не «НаборЗаписей» уже не помню 🙂

    Reply
  21. gragden

    Ожидал что можно будет любой тип объекта искать, а тут только можно справочники выбирать ))), очень похожа на ИТС версию, и 6 стартмани за это жирно

    минус

    Reply
  22. tunesoft

    (21)

    Добрый день, Денис.

    В обработке можно использовать любые ссылочные типы.

    Для этого нужно в конфигураторе у поля выбора присвоить тип «Любая ссылка».

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

    Reply
  23. gragden

    (22)

    тому задан такой тип чтобы сузить с

    Ваша обработка для «полного счастья» еще и запаролена (Введите пароль для работы с текстовым модулем).

    минус

    Reply
  24. tunesoft

    (23)

    пароль подобрать не удалось 🙂

    поищу в архивах и сообщу

    Reply
  25. alexey_t

    Отдать 4 стартмани за запароленную обработку!

    В описании про это ни слова!

    Reply
  26. tunesoft

    (25) постараюсь убрать пароль и обновить, давно это было

    Reply

Leave a Comment

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