<?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='\
А каким образом происходит поиск ссылок?
(1) pepe, генерируется текст запроса 1С по всем метаданным только по реквизитам, содержащим тип ссылки и отбором по значениям «Источник».
Фрагмент этой функции видно на скрине:
(2) так, а чем стандартный поиск дублей не угодил или из инструментов разработчики, да и на худой конец «Поиск и замена значений» , что на диске ИТС? Все это работает без перепроведения документов.
Так это же стандартная обработка с диска ИТС поиска и замены значений, которая точно так же напрямую в движениях заменяет ссылки без перепроведения документов. Куда смотрят модераторы?
(3) karpik666, согласен, варианты есть, но они не совсем подходят для наших задач.
В нашей обработке упор больше сделан на строгость, правильность замены данных (человеческий фактор), а также на большие объёмы данных.
Сейчас регламент работы с данной обработкой следующий: один сотрудник (бухгалтер) в отдельно специализированной обработке «Поиск дублей» готовит список замен, далее выгружает список во внутреннем представлении в файл, далее этот список у себя открывает главный бухгалтер и утверждает, далее список пересылается программисту, программист загружает файл в обработку «Замена ссылок», формирует необходимые отчёты до замены, выполняется замена и т. д.
Ещё в типовой обработке «ПоискИЗаменаЗначений.epf» с диска ИТС выполняется поиск объектов через стандартную функцию «НайтиПоСсылкам», и далее в цикле выполняется перебор всех реквизитов объектов с проверкой на тип и содержание:
…
Для Каждого Реквизит Из СтрокаТаблицы.Метаданные.Реквизиты Цикл
Если Реквизит.Тип.СодержитТип(ТипЗнч(Ссылка)) И Параметры.Объект[Реквизит.Имя] = Ссылка Тогда
…
Для Каждого ТЧ ИЗ СтрокаТаблицы.Метаданные.ТабличныеЧасти Цикл
Для Каждого Реквизит Из ТЧ.Реквизиты Цикл
Если Реквизит.Тип.СодержитТип(ТипЗнч(Ссылка)) Тогда
…
это будет медленно при большом количестве объектов для замены.
Основное отличие нашей обработки в том, что сперва генерируется и выполняется запрос по всем метаданным с получением всех нужных объектов и необходимых реквизитов (добавление в текст запроса только реквизитов заданного типа с отбором по значениям).
Далее выполняется замена ссылок уже по заранее полученным именам таблиц, табличным частям и реквизитам, без излишних проверок в циклах.
(4) insurgut, совсем не стандартная, основные отличия описаны в предыдущем комментарии.
ещё избыточные циклы и проверки в типовой обработке «ПоискИЗаменаЗначений.epf»:
Для Каждого ТЧ ИЗ СтрокаТаблицы.Метаданные.ТабличныеЧасти Цикл
Для Каждого Реквизит Из ТЧ.Реквизиты Цикл
Если Реквизит.Тип.СодержитТип(ТипЗнч(Ссылка)) Тогда
СтрокаТабЧасти = Параметры.Объект[ТЧ.Имя].Найти(Ссылка, Реквизит.Имя);
Пока СтрокаТабЧасти <> Неопределено Цикл
(3) karpik666,
>»или из инструментов разработчики»
внутрь кода не смотрел, но в описании публикации указано «основано на обработке «ПоискИЗаменаДублирующихсяЭлементов» с ИТС»
На двух одинаковых тестовых БД «Бухгалтерия 2» запустил разные обработки, в одной типовую «ПоискИЗаменаЗначений», в другой нашу, настроил одинаковые элементы для замены.
Через несколько секунд «ПоискИЗаменаЗначений» выдала сообщение и прервалась:
Существуют документы, оформленные по договору «Договор №… от 01.01.15г.».
Контрагент договора не может быть изменен, элемент не записан.
Не удалось записать «Договор №… от 01.01.15г. (Договоры контрагентов)»!
Наша обработка успешно завершила выполнение за несколько минут, при этом в журнал регистрации добавлены сообщения вида «Замена <Справочник.Контрагенты;Почта;005;7cba181e-335b-11e4-a84f-001f29081c26> на <Справочник.Контрагенты;Почта России;000011;4a9b2d6c-26b0-11df-97a9-001d7d9bbaae> в таблице <Справочники.ДоговорыКонтрагентов>», данные «Договор №… от 01.01.15г.».
(7) ОбменДанными.Загрузка = Истина, вот и все отличие… Поиск и замена дублирующих использует замены в режиме загрузки данных, поиск и замена значений просто записывает элемент (в итоге выполняются проверки).
(8) insurgut, это знаю, с 1С работаю более 15 лет, смысл в том, что в исходном варианте обработка «ПоискИЗаменаЗначений» не заменяет ссылки и нет флажка на форме чтобы включить режим «ОбменДанными.Загрузка = Истина»
(9) что то непонятно, с 1С более 15 лет, так зачем тогда приводите такое сравнение, или вы думаете, что квалификация посетителей сайта не позволит сказать в чем различия таких данных? Стандартная «поиск и замена значений» предусматривает обмен данными загрузка, просто почему то разработчики не удосужились просто вывести параметр на форму, переделывается это в течении 5 минут, достаточно в функцию замены передавать параметр, что выполнять без проверок. Вам говорят вы изобрели велосипед, притом, что есть уже точно работающие инструменты, и не для одних справочников, а также ПВР, ПВХ, планов счетов, Задач и т.д. А по поводу инструментов, это очень сильно переработанная обработка с ИТС, так как заменяет не только ссылки, но и позволяет оценивать регистры сведений, чтобы не было ошибки на уникальность строк.
(10) karpik666,
>и не для одних справочников, а также ПВР, ПВХ, планов счетов, Задач и т.д.
В нашей обработке тоже есть аналогичная возможность, сейчас в форме в типе элемента явно указано «Справочник», раньше было «Любая ссылка», можно снова выбрать мышкой «Любая ссылка»
>А по поводу инструментов, это очень сильно переработанная обработка с ИТС, так как заменяет не только ссылки, но и позволяет оценивать регистры сведений, чтобы не было ошибки на уникальность строк.
Отлично.
Тоже заменяем в регистре сведений.
>Вам говорят вы изобрели велосипед
Ну и замечательно.
Обработки разные, работают по-разному, и вообще изобретать «велосипеды» полезно 🙂
(11) ладно будь по вашему, может кому то пригодится.
(12) karpik666, Нужно проверить эту обработку, думаю она быстрее работает. Стандартной обработка на моей базе тупо виснет. Через запросы более эффективнее, только сложность, что нужно разбирать метаданные.
(13) pepe,
>Стандартной обработка на моей базе тупо виснет.
Не должна зависать.
В другой сессии 1С в журнале регистрации смотрели запись транзакций фиксируется ?
База файловая или SQL ? Какой размер БД ?
Пробовали выполнить в конфигураторе «Администрирование — Тестирование и исправление» ?
Это проблема размера базы, база уже 600 гбайт. Тестирование и исправление делали относительно не давно.
(5) tunesoft. Вы пишите про обработку «Поиск дублей», который готовит список замен, она есть на инфостарте? Как ее можно получить?
(16) gulchitai, какие-то были, можете через поиск найти.
(17) Свою написала )
Замена ссылок происходит не в режиме ОбменДанными.Загрузка = Истина? При замене появляются сообщения об ошибках, которые у нас вставлены в подписки на события, в них есть такая проверка
Но кажется мы в нее не попадаем… В коде посмотреть не могу, т.к. обработка защищена паролем
(19) gulchitai, запись выполняется в режиме «.ОбменДанными.Загрузка = Истина», но в случае изменения регистра сведений без регистратора используется менеджер записи, у которого нет «ОбменДанными». Почему используется «МенеджерЗаписи», а не «НаборЗаписей» уже не помню 🙂
Ожидал что можно будет любой тип объекта искать, а тут только можно справочники выбирать ))), очень похожа на ИТС версию, и 6 стартмани за это жирно
минус
(21)
Добрый день, Денис.
В обработке можно использовать любые ссылочные типы.
Для этого нужно в конфигураторе у поля выбора присвоить тип «Любая ссылка».
Обычно замена ссылок выполняется для справочников, поэтому задан такой тип чтобы сузить список выбора.
(22)
Ваша обработка для «полного счастья» еще и запаролена (Введите пароль для работы с текстовым модулем).
минус
(23)
пароль подобрать не удалось 🙂
поищу в архивах и сообщу
Отдать 4 стартмани за запароленную обработку!
В описании про это ни слова!
(25) постараюсь убрать пароль и обновить, давно это было