Как исправить ошибку «Получение элемента по индексу для значения не определено» при выгрузке данных в Конвертации данных 2.1?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При переносе данных между конфигурациями 1С с помощью конфигурации «Конвертация данных 2.1» (КД 2.1) разработчики часто сталкиваются со сложными задачами, когда структуры метаданных источника и приемника кардинально различаются. Типичный пример — перенос кадровых данных из устаревшей 1С:Зарплата и Управление Персоналом 2.5 (ЗУП 2.5) в современные ERP-решения, такие как 1С:КУФИБ 3 или 1С:ERP.

В процессе такой настройки часто возникает ошибка выгрузки:

Ошибка получения свойства объекта из входящих данных... ОписаниеОшибки = Получение элемента по индексу для значения не определено.

В этой статье мы подробно разберем, почему возникает эта ошибка, проанализируем внутренние механизмы работы обработчиков КД 2.1 и рассмотрим два надежных практических сценария решения проблемы.

---

Выясняем причину ошибки

Для начала проанализируем архитектурную суть проблемы. Автор темы столкнулся с ошибкой при попытке передать данные для справочника ФизическиеЛица. Поскольку в ЗУП 2.5 персональные данные (ИИН/БИН, паспорта, ФИО, гражданство) хранятся в периодических регистрах сведений, а в КУФИБ 3 многие из этих полей перенесены непосредственно в реквизиты справочника ФизическиеЛица, сопоставить их «напрямую» стандартным образом невозможно.

Автор попытался решить это программно: в обработчике «Перед выгрузкой» Правила конвертации объектов (ПКО) для справочника физических лиц он собрал данные из регистров в Таблицу значений (ТЗ) и присвоил ее параметру ИсходящиеДанные:


// Ошибочный подход автора
ИсходящиеДанные = МояТаблицаЗначений;

Почему это привело к падению выгрузки?

В КД 2.1 механизм передачи вспомогательных данных устроен по строгой иерархии:

  1. Правило конвертации свойств (ПКС) с флагом «Получить из входящих данных» ожидает, что в его распоряжение поступит объект типа Структура или Соответствие, где ключами являются имена свойств приемника (например, Код, ИИН, ДатаРождения).
  2. Когда XML-выгрузчик КД 2.1 обрабатывает ПКС (в нашем случае ПКС «Код»), он пытается прочитать значение из переданной коллекции по имени этого свойства: ВходящиеДанные["Код"] или ВходящиеДанные.Код.
  3. Поскольку автор передал в ИсходящиеДанные целую ТаблицаЗначений, система попыталась обратиться к таблице значений по строковому индексу "Код". У объекта ТаблицаЗначений нет такого метода обращения (к ней можно обращаться по целочисленному индексу строки вроде ТЗ[0], но не напрямую к колонкам самой таблицы). Платформа выдала закономерное исключение: «Получение элемента по индексу для значения не определено».

Главное правило работы с ПКО: Правило конвертации объекта всегда отвечает за конвертацию одного элемента (одной ссылки). Соответственно, в ПКО (или в ПКС, ведущем к этому ПКО) в качестве ИсходящиеДанные должна передаваться строго одна Структура, содержащая данные для этого конкретного элемента, но никак не целая Таблица значений.

---

Вариант решения №1. Выгрузка физических лиц «по ссылке» через ПКС кадрового документа

Рассмотрим наиболее частый сценарий. Физические лица не выгружаются сами по себе — они переносятся автоматически «по ссылке» в момент выгрузки документов (например, документов ПриемНаРаботу).

Чтобы обогатить выгружаемое физлицо данными из регистров сведений источника, нам нужно перехватить выгрузку свойства в ПКО документа. Разберем этот процесс по шагам:

Шаг 1. Настройка ПКО документа

В правилах конвертации найдем ПКО нашего документа (например, ПриемНаРаботу). Перейдем в список его свойств (ПКС). Нас интересует свойство, отвечающее за перенос физического лица — например, ФизическоеЛицо.

Шаг 2. Написание обработчика в ПКС документа

Откроем свойства этого ПКС и перейдем в обработчик «Перед выгрузкой». Здесь мы напишем запрос, который соберет все необходимые персональные данные для конкретного физического лица на дату документа, и упакует их в Структуру:


// Обработчик "Перед выгрузкой" ПКС "ФизическоеЛицо" в ПКО документа "ПриемНаРаботу"

// Проверяем наличие источника
Если ЗначениеЗаполнено(Источник.ФизическоеЛицо) Тогда
    
    // Создаем структуру для хранения свойств ОДНОГО физлица
    ДанныеФизЛица = Новый Структура;
    ДанныеФизЛица.Вставить("Код", Источник.ФизическоеЛицо.Код);
    ДанныеФизЛица.Вставить("Наименование", Источник.ФизическоеЛицо.Наименование);
    
    // Запросом получаем срез последних данных из регистров сведений ЗУП 2.5
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ФИОФизЛицСрезПоследних.Фамилия,
        |   ФИОФизЛицСрезПоследних.Имя,
        |   ФИОФизЛицСрезПоследних.Отчество,
        |   ПаспортныеДанныеФизЛицСрезПоследних.ДокументНомер КАК ПаспортНомер,
        |   ПаспортныеДанныеФизЛицСрезПоследних.ДокументСерия КАК ПаспортСерия,
        |   ФизЛица.ИНН КАК ИИН
        |ИЗ
        |   Справочник.ФизическиеЛица КАК ФизЛица
        |   ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ФИОФизЛиц.СрезПоследних(&Период, ФизЛицо = &ФизЛицо) КАК ФИОФизЛицСрезПоследних
        |       ПО ФИОФизЛицСрезПоследних.ФизЛицо = ФизЛица.Ссылка
        |   ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПаспортныеДанныеФизЛиц.СрезПоследних(&Период, ФизЛицо = &ФизЛицо) КАК ПаспортныеДанныеФизЛицСрезПоследних
        |       ПО ПаспортныеДанныеФизЛицСрезПоследних.ФизЛицо = ФизЛица.Ссылка
        |ГДЕ
        |   ФизЛица.Ссылка = &ФизЛицо";
        
    Запрос.УстановитьПараметр("Период", Источник.Дата);
    Запрос.УстановитьПараметр("ФизЛицо", Источник.ФизическоеЛицо);
    
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        // Наполняем структуру данными для приемника КУФИБ 3
        ДанныеФизЛица.Вставить("ИИН", Выборка.ИИН);
        ДанныеФизЛица.Вставить("ПаспортНомер", Выборка.ПаспортНомер);
        ДанныеФизЛица.Вставить("ПаспортСерия", Выборка.ПаспортСерия);
        // При необходимости собираем ФИО в одну строку или передаем частями
        ДанныеФизЛица.Вставить("Фамилия", Выборка.Фамилия);
        ДанныеФизЛица.Вставить("Имя", Выборка.Имя);
        ДанныеФизЛица.Вставить("Отчество", Выборка.Отчество);
    КонецЕсли;
    
    // Передаем заполненную структуру в ИсходящиеДанные ПКС.
    // Она автоматически станет объектом ВходящиеДанные для ПКО "ФизическиеЛица"
    ИсходящиеДанные = ДанныеФизЛица;
    
КонецЕсли;

Шаг 3. Настройка ПКО справочника «ФизическиеЛица»

Теперь откроем ПКО ФизическиеЛица. Для каждого ПКС этого справочника, которое мы хотим заполнить из созданной структуры (например, ИИН, ПаспортНомер, Фамилия и т.д.), необходимо выполнить следующие действия:

  1. Дважды кликнуть по ПКС, открыв форму его свойств.
  2. Установить флаг «Получить из входящих данных». При этом поле «Источник» можно оставить пустым, так как данные будут считываться напрямую из переданной структуры.

---

Вариант решения №2. Использование произвольного алгоритма выгрузки в ПВД

Если вам требуется выгрузить физических лиц списком (например, всех работающих сотрудников), не привязываясь к конкретным документам, то оптимальным решением будет использование Правила выгрузки данных (ПВД) с произвольным алгоритмом.

Проанализируем этот сценарий по шагам:

Шаг 1. Настройка ПВД

В настройках ПВД для справочника ФизическиеЛица укажем способ выборки данных: «Произвольный алгоритм».

Шаг 2. Написание кода в обработчике «Перед обработкой» ПВД

В этом обработчике мы полностью берем управление выборкой на себя. Сначала мы отменяем стандартный обход справочника платформой, устанавливая параметр Отказ = Истина. Затем пишем запрос ко всей базе данных, чтобы разом получить нужных физлиц и их персональные данные из регистров сведений. После этого обходим выборку в цикле и выгружаем каждого сотрудника индивидуально через метод ВыгрузитьПоПравилу:


// Обработчик "Перед обработкой" ПВД "ФизическиеЛица"

// Отменяем стандартный механизм выгрузки
Отказ = Истина;

// Пишем запрос ко всем физлицам и их регистрам сведений в источнике
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ФизЛица.Ссылка КАК Ссылка,
    |   ФизЛица.Код КАК Код,
    |   ФизЛица.Наименование КАК Наименование,
    |   ФизЛица.ИНН КАК ИИН,
    |   ФИОФизЛицСрезПоследних.Фамилия КАК Фамилия,
    |   ФИОФизЛицСрезПоследних.Имя КАК Имя,
    |   ФИОФизЛицСрезПоследних.Отчество КАК Отчество
    |ИЗ
    |   Справочник.ФизическиеЛица КАК ФизЛица
    |   ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ФИОФизЛиц.СрезПоследних(&Период, ) КАК ФИОФизЛицСрезПоследних
    |       ПО ФИОФизЛицСрезПоследних.ФизЛицо = ФизЛица.Ссылка
    |ГДЕ
    |   НЕ ФизЛица.ЭтоГруппа";

// Установим актуальную дату для получения среза последних данных
Запрос.УстановитьПараметр("Период", ТекущаяДата());

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    
    // Для КАЖДОЙ строки создаем индивидуальную структуру данных
    ДанныеДляВыгрузки = Новый Структура;
    ДанныеДляВыгрузки.Вставить("Код", Выборка.Код);
    ДанныеДляВыгрузки.Вставить("Наименование", Выборка.Наименование);
    ДанныеДляВыгрузки.Вставить("ИИН", Выборка.ИИН);
    ДанныеДляВыгрузки.Вставить("Фамилия", Выборка.Фамилия);
    ДанныеДляВыгрузки.Вставить("Имя", Выборка.Имя);
    ДанныеДляВыгрузки.Вставить("Отчество", Выборка.Отчество);
    
    // Вызываем выгрузку объекта по правилу ПКО "ФизическиеЛица"
    // Третий параметр - это ВходящиеДанные для ПКО приемника
    ВыгрузитьПоПравилу(Выборка.Ссылка, , ДанныеДляВыгрузки, , "ФизическиеЛица");
    
КонецЦикла;

Шаг 3. Проверка настроек ПКО

Аналогично первому варианту, в ПКО ФизическиеЛица для реквизитов, которые мы передаем внутри структуры (ИИН, Фамилия, Имя, Отчество), должен быть установлен флаг «Получить из входящих данных».

---

Рекомендации по отладке правил обмена

Для того чтобы не гадать на кофейной гуще при возникновении ошибок конвертации, настоятельно рекомендуется использовать штатный механизм интерактивной отладки обработчиков КД 2.1:

  1. Откройте вашу информационную базу «Конвертация данных 2.1».
  2. Перейдите в настройки выгрузки и найдите опцию «Настройка отладки выгрузки».
  3. Сгенерируйте модуль отладки (система сформирует обработку или текстовый файл с кодом всех ваших обработчиков).
  4. Подключите этот файл во внешней обработке выгрузки УниверсальныйОбменДаннымиXML.epf в базе-источнике.
  5. Запустите конфигуратор источника и установите точку останова в сгенерированном коде (например, непосредственно перед вызовом функции ВыгрузитьПоПравилу или внутри обработчика ПКС). Вы сможете наглядно увидеть типы и структуру передаваемых переменных в табло отладчика.

Применение правильных коллекций данных (Структура вместо ТаблицаЗначений для единичных объектов) и использование отладчика КД 2.1 позволит вам быстро решать любые технические сложности при переносе данных самой разной степени сложности.

← На главную