При переносе данных между конфигурациями 1С с помощью конфигурации «Конвертация данных 2.1» (КД 2.1) разработчики часто сталкиваются со сложными задачами, когда структуры метаданных источника и приемника кардинально различаются. Типичный пример — перенос кадровых данных из устаревшей 1С:Зарплата и Управление Персоналом 2.5 (ЗУП 2.5) в современные ERP-решения, такие как 1С:КУФИБ 3 или 1С:ERP.
В процессе такой настройки часто возникает ошибка выгрузки:
Ошибка получения свойства объекта из входящих данных... ОписаниеОшибки = Получение элемента по индексу для значения не определено.
В этой статье мы подробно разберем, почему возникает эта ошибка, проанализируем внутренние механизмы работы обработчиков КД 2.1 и рассмотрим два надежных практических сценария решения проблемы.
---
Для начала проанализируем архитектурную суть проблемы. Автор темы столкнулся с ошибкой при попытке передать данные для справочника ФизическиеЛица. Поскольку в ЗУП 2.5 персональные данные (ИИН/БИН, паспорта, ФИО, гражданство) хранятся в периодических регистрах сведений, а в КУФИБ 3 многие из этих полей перенесены непосредственно в реквизиты справочника ФизическиеЛица, сопоставить их «напрямую» стандартным образом невозможно.
Автор попытался решить это программно: в обработчике «Перед выгрузкой» Правила конвертации объектов (ПКО) для справочника физических лиц он собрал данные из регистров в Таблицу значений (ТЗ) и присвоил ее параметру ИсходящиеДанные:
// Ошибочный подход автора
ИсходящиеДанные = МояТаблицаЗначений;
Почему это привело к падению выгрузки?
В КД 2.1 механизм передачи вспомогательных данных устроен по строгой иерархии:
Структура или Соответствие, где ключами являются имена свойств приемника (например, Код, ИИН, ДатаРождения).ВходящиеДанные["Код"] или ВходящиеДанные.Код.ИсходящиеДанные целую ТаблицаЗначений, система попыталась обратиться к таблице значений по строковому индексу "Код". У объекта ТаблицаЗначений нет такого метода обращения (к ней можно обращаться по целочисленному индексу строки вроде ТЗ[0], но не напрямую к колонкам самой таблицы). Платформа выдала закономерное исключение: «Получение элемента по индексу для значения не определено».Главное правило работы с ПКО: Правило конвертации объекта всегда отвечает за конвертацию одного элемента (одной ссылки). Соответственно, в ПКО (или в ПКС, ведущем к этому ПКО) в качестве ИсходящиеДанные должна передаваться строго одна Структура, содержащая данные для этого конкретного элемента, но никак не целая Таблица значений.
---
Рассмотрим наиболее частый сценарий. Физические лица не выгружаются сами по себе — они переносятся автоматически «по ссылке» в момент выгрузки документов (например, документов ПриемНаРаботу).
Чтобы обогатить выгружаемое физлицо данными из регистров сведений источника, нам нужно перехватить выгрузку свойства в ПКО документа. Разберем этот процесс по шагам:
Шаг 1. Настройка ПКО документа
В правилах конвертации найдем ПКО нашего документа (например, ПриемНаРаботу). Перейдем в список его свойств (ПКС). Нас интересует свойство, отвечающее за перенос физического лица — например, ФизическоеЛицо.
Шаг 2. Написание обработчика в ПКС документа
Откроем свойства этого ПКС и перейдем в обработчик «Перед выгрузкой». Здесь мы напишем запрос, который соберет все необходимые персональные данные для конкретного физического лица на дату документа, и упакует их в Структуру:
// Обработчик "Перед выгрузкой" ПКС "ФизическоеЛицо" в ПКО документа "ПриемНаРаботу"
// Проверяем наличие источника
Если ЗначениеЗаполнено(Источник.ФизическоеЛицо) Тогда
// Создаем структуру для хранения свойств ОДНОГО физлица
ДанныеФизЛица = Новый Структура;
ДанныеФизЛица.Вставить("Код", Источник.ФизическоеЛицо.Код);
ДанныеФизЛица.Вставить("Наименование", Источник.ФизическоеЛицо.Наименование);
// Запросом получаем срез последних данных из регистров сведений ЗУП 2.5
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ФИОФизЛицСрезПоследних.Фамилия,
| ФИОФизЛицСрезПоследних.Имя,
| ФИОФизЛицСрезПоследних.Отчество,
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументНомер КАК ПаспортНомер,
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументСерия КАК ПаспортСерия,
| ФизЛица.ИНН КАК ИИН
|ИЗ
| Справочник.ФизическиеЛица КАК ФизЛица
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ФИОФизЛиц.СрезПоследних(&Период, ФизЛицо = &ФизЛицо) КАК ФИОФизЛицСрезПоследних
| ПО ФИОФизЛицСрезПоследних.ФизЛицо = ФизЛица.Ссылка
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПаспортныеДанныеФизЛиц.СрезПоследних(&Период, ФизЛицо = &ФизЛицо) КАК ПаспортныеДанныеФизЛицСрезПоследних
| ПО ПаспортныеДанныеФизЛицСрезПоследних.ФизЛицо = ФизЛица.Ссылка
|ГДЕ
| ФизЛица.Ссылка = &ФизЛицо";
Запрос.УстановитьПараметр("Период", Источник.Дата);
Запрос.УстановитьПараметр("ФизЛицо", Источник.ФизическоеЛицо);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
// Наполняем структуру данными для приемника КУФИБ 3
ДанныеФизЛица.Вставить("ИИН", Выборка.ИИН);
ДанныеФизЛица.Вставить("ПаспортНомер", Выборка.ПаспортНомер);
ДанныеФизЛица.Вставить("ПаспортСерия", Выборка.ПаспортСерия);
// При необходимости собираем ФИО в одну строку или передаем частями
ДанныеФизЛица.Вставить("Фамилия", Выборка.Фамилия);
ДанныеФизЛица.Вставить("Имя", Выборка.Имя);
ДанныеФизЛица.Вставить("Отчество", Выборка.Отчество);
КонецЕсли;
// Передаем заполненную структуру в ИсходящиеДанные ПКС.
// Она автоматически станет объектом ВходящиеДанные для ПКО "ФизическиеЛица"
ИсходящиеДанные = ДанныеФизЛица;
КонецЕсли;
Шаг 3. Настройка ПКО справочника «ФизическиеЛица»
Теперь откроем ПКО ФизическиеЛица. Для каждого ПКС этого справочника, которое мы хотим заполнить из созданной структуры (например, ИИН, ПаспортНомер, Фамилия и т.д.), необходимо выполнить следующие действия:
---
Если вам требуется выгрузить физических лиц списком (например, всех работающих сотрудников), не привязываясь к конкретным документам, то оптимальным решением будет использование Правила выгрузки данных (ПВД) с произвольным алгоритмом.
Проанализируем этот сценарий по шагам:
Шаг 1. Настройка ПВД
В настройках ПВД для справочника ФизическиеЛица укажем способ выборки данных: «Произвольный алгоритм».
Шаг 2. Написание кода в обработчике «Перед обработкой» ПВД
В этом обработчике мы полностью берем управление выборкой на себя. Сначала мы отменяем стандартный обход справочника платформой, устанавливая параметр Отказ = Истина. Затем пишем запрос ко всей базе данных, чтобы разом получить нужных физлиц и их персональные данные из регистров сведений. После этого обходим выборку в цикле и выгружаем каждого сотрудника индивидуально через метод ВыгрузитьПоПравилу:
// Обработчик "Перед обработкой" ПВД "ФизическиеЛица"
// Отменяем стандартный механизм выгрузки
Отказ = Истина;
// Пишем запрос ко всем физлицам и их регистрам сведений в источнике
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ФизЛица.Ссылка КАК Ссылка,
| ФизЛица.Код КАК Код,
| ФизЛица.Наименование КАК Наименование,
| ФизЛица.ИНН КАК ИИН,
| ФИОФизЛицСрезПоследних.Фамилия КАК Фамилия,
| ФИОФизЛицСрезПоследних.Имя КАК Имя,
| ФИОФизЛицСрезПоследних.Отчество КАК Отчество
|ИЗ
| Справочник.ФизическиеЛица КАК ФизЛица
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ФИОФизЛиц.СрезПоследних(&Период, ) КАК ФИОФизЛицСрезПоследних
| ПО ФИОФизЛицСрезПоследних.ФизЛицо = ФизЛица.Ссылка
|ГДЕ
| НЕ ФизЛица.ЭтоГруппа";
// Установим актуальную дату для получения среза последних данных
Запрос.УстановитьПараметр("Период", ТекущаяДата());
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Для КАЖДОЙ строки создаем индивидуальную структуру данных
ДанныеДляВыгрузки = Новый Структура;
ДанныеДляВыгрузки.Вставить("Код", Выборка.Код);
ДанныеДляВыгрузки.Вставить("Наименование", Выборка.Наименование);
ДанныеДляВыгрузки.Вставить("ИИН", Выборка.ИИН);
ДанныеДляВыгрузки.Вставить("Фамилия", Выборка.Фамилия);
ДанныеДляВыгрузки.Вставить("Имя", Выборка.Имя);
ДанныеДляВыгрузки.Вставить("Отчество", Выборка.Отчество);
// Вызываем выгрузку объекта по правилу ПКО "ФизическиеЛица"
// Третий параметр - это ВходящиеДанные для ПКО приемника
ВыгрузитьПоПравилу(Выборка.Ссылка, , ДанныеДляВыгрузки, , "ФизическиеЛица");
КонецЦикла;
Шаг 3. Проверка настроек ПКО
Аналогично первому варианту, в ПКО ФизическиеЛица для реквизитов, которые мы передаем внутри структуры (ИИН, Фамилия, Имя, Отчество), должен быть установлен флаг «Получить из входящих данных».
---
Для того чтобы не гадать на кофейной гуще при возникновении ошибок конвертации, настоятельно рекомендуется использовать штатный механизм интерактивной отладки обработчиков КД 2.1:
УниверсальныйОбменДаннымиXML.epf в базе-источнике.ВыгрузитьПоПравилу или внутри обработчика ПКС). Вы сможете наглядно увидеть типы и структуру передаваемых переменных в табло отладчика.Применение правильных коллекций данных (Структура вместо ТаблицаЗначений для единичных объектов) и использование отладчика КД 2.1 позволит вам быстро решать любые технические сложности при переносе данных самой разной степени сложности.