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

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

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

Причина ошибки «Получение элемента по индексу для значения не определено» (Код 68)

Проанализируем текст исходной ошибки обработки универсального обмена:

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

Выясним причину такого поведения. Данное исключение возникает в универсальной обработке выгрузки XML в том случае, если в правиле конвертации свойства (ПКС) включен флаг «Получить из входящих данных», но при вызове правила параметр ВходящиеДанные не был инициализирован (имеет значение Неопределено). Механизм КД пытается обратиться к переданной коллекции по имени свойства как по индексу (ВходящиеДанные["ИмяСвойства"]) и падает с системным исключением.

Если реквизит рассчитывается кодом запроса непосредственно в обработчиках самого ПКС, значение не должно считываться из входящих данных.

Пошаговая настройка ПКС для вычисляемого реквизита

Рассмотрим правильную настройку правила конвертации свойства:

  1. В настройках ПКС реквизит Источник оставляем пустым.
  2. Снимаем флаг «Получить из входящих данных».
  3. Устанавливаем флаг «Передавать данные в приемник» (Истина).
  4. В обработчике ПередВыгрузкой или ПриВыгрузке прописываем логику получения данных через переменную Значение.

Посмотрим на пример корректного кода в обработчике ПриВыгрузке ПКС, исключающего получение данных для групп номенклатуры:


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

Ошибка «Поле объекта не обнаружено (Активность)» при выгрузке регистров

Рассмотрим следующую распространенную проблему: при выгрузке связанных регистров сведений из обработчика ПослеВыгрузкиОбъекта справочника Номенклатура с помощью функции ВыгрузитьПоПравилу возникает ошибка отсутствия поля Активность.

Проанализируем причину. При программной выборке данных из независимого непериодического регистра сведений через запрос (ВЫБРАТЬ *) системное свойство Активность в выборку не попадает. Однако в сгенерированном ПКО регистра сведений для свойства Активность по умолчанию создано ПКС, которое пытается прочитать это поле из источника (выборки запроса).

Для устранения ошибки выполним следующие действия:

  1. Открываем ПКО соответствующего регистра сведений.
  2. Находим ПКС Активность и снимаем с него флаг «Передавать данные в приемник» (отключаем ПКС) либо в обработчике ПередВыгрузкой данного ПКС явно указываем: Значение = Истина;
  3. Аналогичным образом проверяем системные поля Период и НомерСтроки, если регистр является непериодическим.

Организация выгрузки связанных регистров сведений

Разберем, как правильно организовать выгрузку связанных данных (цены, штрихкоды, соответствия ЕГАИС) по текущему объекту номенклатуры. В обработчике ПослеВыгрузки ПКО Номенклатура можно использовать обход выборки запроса:


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

ЗапросЕГАИС.УстановитьПараметр("Номенклатура", Источник.Ссылка);
ВыборкаЕГАИС = ЗапросЕГАИС.Выполнить().Выбрать();

Пока ВыборкаЕГАИС.Следующий() Цикл
    ВыгрузитьПоПравилу(ВыборкаЕГАИС, , , , "СоответствиеНоменклатурыЕГАИС");
КонецЦикла;

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


НаборЗаписей = РегистрыСведений.Штрихкоды.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Владелец.Установить(Источник.Ссылка);
НаборЗаписей.Прочитать();

Для Каждого Запись Из НаборЗаписей Цикл
    ВыгрузитьПоПравилу(Запись, , , , "Штрихкоды");
КонецЦикла;

Настройка сопоставления в обработчике «ПоляПоиска»

Если в базе-приемнике требуется выполнить поиск записи регистра по свойствам, которые формируются динамически или не имеют прямого источника, используем обработчик ПоляПоиска в ПКО приемника.

Посмотрим на пример алгоритма сопоставления:


Если ЗначениеЗаполнено(СвойстваПоиска["АлкогольнаяПродукция"]) ИЛИ ЗначениеЗаполнено(СвойстваПоиска["КодНоменклатурыЕГАИС"]) Тогда
    СтрокаИменСвойствПоиска = "АлкогольнаяПродукция, КодНоменклатурыЕГАИС";
Иначе
    ПрекратитьПоиск = Истина;
КонецЕсли;

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

← На главную