<?php // Полная загрузка сервисных книжек, создан 2025-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='\
(0) интересная работа!
Добрый день, а рабтает только для идентичных конфигураций? Для переноса пару доков их БП2 в БП3 пойдет, как думаете?
(2) В БП2 и БП3 структура данных разная. Этим инструментом вашу задачу скорее всего не решить.
Добрый день. А между Промышленной безопасностью и ЗУП 3, выполнит перенос?
(4) Инструмент переносит данные между конфигурациями с идентичной или почти идентичной структурой данных.
Если в конфигураторе объекты называются одинаково и поля этих объектов называются одинаково и имеют одинаковый тип, то они перенесутся, в противном случае — не перенесутся или будет ошибка.
Касательно конфигурации Промышленная безопасность — сказать ничего не могу, т.к. с такой не работал
(6)
Да, на строках неограниченной длины в регистрах падала ошибка.
Исправил. Скачайте еще раз (повторное скачивание в течение первых дней — бесплатное)
ERP 2.4.6.188 (демонстрационная база)
При попытке переноса справочника Номеклатура (нажимаем кнопку Выгрузить):
Выдает окно с сообщением: Получение элемента по индексу для значения не определено
В сообщения выводит:
{ВнешняяОбработка.ПереносДанных.МодульОбъекта(579)}: Значение не является значением объектного типа (Метаданные):[]
(8) Благодарю за подробное описание ошибки.
Была проблема при выгрузке реквизитов, назначенных только для группы или только для элементов.
Выложил исправленную версию
Выложил версию с исправлениями.
Если вы скачивали ранее и хотите получить обновленную версию — напишите мне в личку
ERP 2.4.6.188 (демонстрационная база).
На обновленной обработке заработало.
Но при переносе данных не сохранило структуру (см. приложенный файл).
Левая часть — структура в демонстрационной базе.
Правая часть — структура в базе в которую переносили номенклатуру.
Папки второго уровня переехали на первый уровень.
(11)
Мне не удалось повторить ошибку. Структура папок переносится корректно.
Могу предположить, что группы второго уровня ЯВНО не добавлялись в выгрузку. То есть выгружались элементы, которые находятся в этих группах. При этом когда при загрузке создавались элементы, создались и их родители. Но т.к. родители явно в выгрузке не были указаны, то они создались в корне.
В таком случае если выгрузить-загрузить только группы, то иерархия встанет на место
Если мое предположение не верно, то уточните, пожалуйста:
-версию платформы
-название справочника
-как выгружали загружали: выгрузили полностью справочник и загрузили в пустой справочник в другой базе или как-то иначе?
посмотрим — на обычных формах таб документ сильно выручал
Благодарю, обработка очень помогла восстановить удаленные данные, удобно что после формирования таблицы можно поправить перед загрузкой 🙂
Бух 3.0 (платформа 8.3.12, Релиз 3.0.67)
Ошибка:
ТИП: РегистрБухгалтерии.Хозрасчетный.Ошибка при создании данных из макета в строках с 8 по 12 : {ВнешняяОбработка.ПереносДанных.МодульОбъекта(1190)}: Ошибка компиляции при вычислении выражения или выполнении фрагмента кода: {(1,1)}: Процедура или функция с указанным именем не определена (ЗаполнитьИзТаблицыЗначений_РегистрБухгалтерии)
Ошибка срабатывает при Загрузке документа с движениями.
(16) Спасибо за подробное описание.
Выложил исправленную версию
Отбор по организации (или по контрагенту) есть?
(18)
Стандартные отборы по любым реквизитам шапки. Если режим совместимости конфигурации не древний, то отборы можно накладывать и по табличным частям.
1С:Предприятие 8.3 (8.3.13.1513)
Управление производственным предприятием, редакция 1.3 (1.3.122.2)
Обработка просто не открывается.
(20) Обработка запускается только в режиме управляемого приложения.
УФ в названии — управляемые формы.
Скорее всего запускаете УПП в режиме обычного приложения и пытаетесь открыть ее как внешнюю.
Есть два способа воспользоваться обработкой в конфигурации УПП:
1. Зайти в базу УПП в режиме управляемого приложения и открыть ее как внешнюю обработку
2. Встроить обработку в конфигурацию и не забыть включить флаг использования управляемых форм в режиме обычного приложения. После этого открыть обработку как внутреннюю
(21) Извините, я в 8-ке можно сказать дилетант. Как запустить базу в режиме управляемого приложения?
(22) самый простой способ из конфигуратора.
В конфигураторе в верхнем меню выбрать: Отладка — Начало отладки — Тонкий клиент: начать отладку
(23) Спасибо. Попробовал, запускается.
(23) Прошу прощения, попробовал перенести справочник «Номенклатура» в одной базы в другую (однотипную). Получилось как-то криво, все папки (пустые) и элементы оказались в одном уровне. При выгрузке ставил в настройках глубину выгрузки = 4, при загрузке ничего не ставил. Наряду со справочником «Номенклатура» программа выгрузила ряд других справочников («Контрагенты», «Виды номенклатуры», «Номенклатурные группы» и др.), ссылки на элементы которых, видимо были в справочнике «Номенклатура». По окончании загрузки программа выдала следующие сообщения:
ТИП: Справочник.ЕдиницыИзмерения.Ошибка при создании данных из макета в строках, начиная с 42 : {ВнешняяОбработка.ПереносДанных.МодульОбъекта(1154)}: Ошибка при вызове метода контекста (Вставить): Задано неправильное имя атрибута структуры
ТИП: Справочник.Номенклатура.Ошибка при создании данных из макета в строках, начиная с 43 621 : {ВнешняяОбработка.ПереносДанных.МодульОбъекта(1154)}: Ошибка при вызове метода контекста (Вставить): Задано неправильное имя атрибута структуры
ТИП: Справочник.ГруппыОбъектовРабот.Ошибка при создании данных из макета в строках, начиная с 89 427 : {(1)}: Поле объекта не обнаружено (ГруппыОбъектовРабот)
ТИП: Справочник.НоменклатурныеГруппы.Ошибка при создании данных из макета в строках, начиная с 89 449 : {(1)}: Поле объекта не обнаружено (ГруппыОбъектовРабот)
Что я не так сделал?
(25) попробуйте сделать следующее:
Перенесите группы номенаклатуры отдельно.
1. Установите отбор ЭтоГруппа = Истина,
2. уровень выгрузки = 0, затем
3. нажать кнопку Выбрать все
4. выгрузить
5. загрузить в другую базу
Потом уже грузите нужные элементы номенклатуры с уровнем = 1
Также внимательно прочитайте в публикации пункт Требования
Если перед записью или при записи кодом установлены запреты, проверяющие бизнес-логику, то запись может не получиться.
(25)
объясню, что значит уровень = 4.
Вот ты выгружаешь элемент номенклатуры — сам элемент со всеми реквизитами это уровень 0
Все ссылки, которые в нем упоминаются — это уровень 1.
Все ссылки, которые упоминаются в уровне 1 — это уровень 2
и т.д.
Вот выгружаешь ты элемент номенклатуры, который лежит в папке, которая вложена в другую папку, которая вложена в другую папку и т.д.
При уровне = 4 у тебя выгружается сам выгружаемый элемент номенклатуры, а также четыре уровня папок в которые он вложен.
Если уровень вложенности у переносимого элемента больше 4, четвертый родитель вверх от элемента будет помещен в корень.
В перегружаемом вами справочнике номенклатуры, похоже, что больше 4 уровней, поэтому часть папок оказалась в корне, потому что не переносился их родитель.
Чтобы этого избежать я написал в предыдущем сообщении что нужно сделать. А именно необходимо перенести отдельно всю иерархию папок.
А потом уже переносить элементы с настройкой уровень = 0 или 1 в зависимости от того хотим ли мы создавать ссылки, которые вложены в переносимый элемент или нет
Дело в том, что не часть папок оказалось в корне, а все папки и элементы оказались в корне. Но в общем понял, попробую в два этапа переносить. Не понял только про «отсечки», что это. Что касается указанных мною сообщений об ошибках, то понял, что дело в измененной конфигурации базы-источника (добавлены реквизиты), сделал аналогичные изменения в базе-приемника, посмотрим. Спасибо за то, что помогаете разобраться.
(28) прикладываю пример на скриншоте, как выглядит код типовых конфигурациях.
Вот в примере, если запись происходит в особом режиме, то запись выполняем без проверок (Возврат — означает что ничего не проверяем и не дозаполняем, а просто выходим из процедуры и записываем, а в обычном режиме на примере выполняются проверки и где-то при проверках может установиться Отказ=Истина или выскочить исключение)
Так вот во всех процедурах ПриЗаписи и ПередЗаписью должны стоять отсечки как в приведенном примере. То есть в самом начале каждой процедуры-обработчика должен быть такой код:
Да, спасибо. Еще одно уточнение. Как я понял «уровень» касается вложенных реквизитов, а не родителей? Т.е., если я буду переносить элементы с «уровень = 0», они попадут в ранее перенесенные папки? А что значит «уровень = 1»? Что будут создаваться элементы тех справочников, на которые ссылаются элементы номенклатуры?
(30)
Родитель — это тоже реквизит справочника номенклатуры. Если переносим с уровень=0 и родителя нет в базе, то загружаемый элемент попадет в корень. Если родитель на момент загрузки есть в базе, то загружаемый элемент будет подчиненным этому родителю.
Уровень = 1 — значит, что все ссылочные объекты, которые есть в реквизитах переносимого элемента, тоже создадутся и заполнятся как в базе источнике.
Уровень = 0 — значит, что все ссылочные объекты, которые есть в реквизитах — не будут создаваться, а если объект, на который ссылается реквизит в базе отсутствует, то в реквизите будет битая ссылка.
(31) Сделал, как вы сказали — в 2 этапа. Сначала поставил Отбор: ЭтоГруппа = Истина. Перенеслись все папки. Потом поставил ЭтоГруппа = Ложь. Перенеслись все элементы, но не в папки, а в корень. Кроме того в поле «Код» элементов записывается не код, а часть наименования.