Как получить дополнительный реквизит (Директор) контрагента из объекта Партнер и исправить ошибку итератора?

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

При разработке внешних печатных форм или обработок в 1С часто возникает задача извлечения данных, которые не являются стандартными реквизитами объекта, а вынесены в так называемые «Дополнительные реквизиты и сведения». Одной из типичных проблем является получение ФИО директора контрагента, если эти данные хранятся как свойство. В процессе реализации программисты часто сталкиваются с ошибкой Итератор для значения не определен. Рассмотрим подробно, почему возникает эта ошибка и как правильно извлекать дополнительные реквизиты, используя современные стандарты разработки в 1С.

Причина ошибки «Итератор для значения не определен»

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

Проанализируем тип переменной СсылкаНаОбъект. Если в процедуру печати передается одиночная ссылка на справочник (например, СправочникСсылка.Партнеры), то она не является коллекцией. Попытка применить к ней цикл приводит к немедленной остановке программы. Если ваша задача — обработать только один объект, цикл не нужен вовсе. Если же объектов несколько, необходимо убедиться, что СсылкаНаОбъект является массивом или списком значений.

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

Способ 1: Прямое обращение к табличной части (Упрощенный вариант)

Если нам известно, что данные «Директора» хранятся именно в дополнительных реквизитах контрагента, мы можем обратиться к табличной части ДополнительныеРеквизиты. Рассмотрим исправленный код автора без использования ошибочного цикла:


// Сначала найдем само свойство (вид характеристики)
ДопСвойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Директор"); 

// Проверяем, что свойство найдено, чтобы избежать ошибки при поиске в коллекции
Если Не ДопСвойство.Пустая() Тогда
    // Обращаемся к контрагенту через партнера
    СтрокаСвойства = СсылкаНаОбъект.Контрагент.ДополнительныеРеквизиты.Найти(ДопСвойство, "Свойство");
    
    Если СтрокаСвойства <> Неопределено Тогда
        // Получаем значение (это может быть строка или ссылка на значение свойства)
        ДиректорЗначение = СтрокаСвойства.Значение;
        ОбластьШапкиДанных.Параметры.Пункт0_4 = Строка(ДиректорЗначение); 
    КонецЕсли;
КонецЕсли;

В этом примере мы проанализировали структуру метаданных. У объекта Контрагент есть табличная часть ДополнительныеРеквизиты, где в колонке Свойство хранится ссылка на план видов характеристик, а в колонке Значение — нужные нам данные.

Способ 2: Использование методов БСП (Профессиональный стандарт)

В типовых конфигурациях (УТ 11, ERP 2.5, КА 2.5, БП 3.0) реализована «Библиотека стандартных подсистем» (БСП). Она предоставляет программный интерфейс для работы с доп. свойствами, который гораздо надежнее и проще в использовании. Вместо того чтобы вручную перебирать табличные части, рекомендуется использовать общий модуль УправлениеСвойствами.

Выясним преимущества этого метода: вам не нужно знать, где именно хранится реквизит (в табличной части объекта или во внешнем регистре сведений ДополнительныеСведения). Система сама определит местоположение данных.

Пример использования функции БСП:


// Определяем свойство
ДопСвойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Директор");

// Получаем значение через стандартный механизм БСП
Директор = УправлениеСвойствами.ЗначениеРеквизита(СсылкаНаОбъект.Контрагент, ДопСвойство);

// Выводим результат
Если ЗначениеЗаполнено(Директор) Тогда
    ОбластьШапкиДанных.Параметры.Пункт0_4 = Строка(Директор);
КонецЕсли;

Функция УправлениеСвойствами.ЗначениеРеквизита принимает два параметра: ссылку на объект (Контрагент) и ссылку на свойство. Это сокращает ваш код и делает его устойчивым к изменениям структуры конфигурации.

Риски поиска по наименованию и оптимизация

Рассмотрим критические замечания, высказанные в обсуждении. Использование НайтиПоНаименованию("Директор") — это «хрупкое» решение. Если пользователь создаст еще одно свойство с таким же именем для другого справочника или переименует текущее, код перестанет работать.

Рекомендации по улучшению кода:

  1. Поиск по имени свойства: Если реквизит создан в конфигураторе как предопределенный элемент, лучше обращаться к нему через имя. Если он создан пользователем, можно использовать поиск по уникальному идентификатору (GUID).
  2. Проверка заполнения: Всегда проверяйте результат работы метода Найти() или ЗначениеРеквизита() на Неопределено или ПустаяСсылка.
  3. Работа с типами данных: Помните, что значением дополнительного реквизита может быть не строка, а ссылка на элемент справочника ЗначенияСвойствОбъектов. Функция Строка() поможет получить текстовое представление, но для сложных печатных форм может потребоваться обращение к реквизитам этого справочника.
  4. Оптимизация (Запросы): Если вы выводите таблицу с данными (например, список поставщиков с их директорами), получение значения через точку (Ссылка.Контрагент...) в цикле крайне неэффективно. В этом случае лучше использовать один запрос к базе данных, соединяясь с таблицей дополнительных реквизитов.

Методы отладки при поиске данных

Если данные не возвращаются, как в случае автора (сообщение 5), проанализируем ситуацию с помощью отладки. Проверьте следующие моменты:

Подводя итог, для решения задачи необходимо четко разделять коллекции и одиночные ссылки, отдавать предпочтение методам БСП и минимизировать использование поиска по текстовому наименованию в пользу более надежных идентификаторов объектов.

← На главную