Разработка внешних печатных форм (ВПФ) — это одна из первых серьезных задач, с которой сталкивается начинающий программист 1С. Несмотря на кажущуюся простоту, этот процесс скрывает множество нюансов, связанных с объектной моделью платформы, контекстом выполнения кода и правильным оформлением макетов. В данной статье мы подробно разберем цепочку ошибок, возникших у пользователя при создании акта удержания, и выясним, как их правильно устранять.
Проанализируем первую и самую главную проблему. Ошибка «Итератор для значения не определен» возникает в языке 1С:Предприятие в тот момент, когда платформа встречает конструкцию Для Каждого... Из... Цикл, но объект, стоящий после слова Из, не является коллекцией. Коллекцией в 1С считаются такие типы данных, как ТаблицаЗначений, Массив, ТабличнаяЧасть, СписокЗначений и другие.
Рассмотрим конкретный пример из практики. В коде автора была допущена следующая ошибка:
Для Каждого Строка Из СсылкаНаОбъект.Ссылка.ИтогиРевизии Цикл
// Код обработки строки
КонецЦикла;
Выясним причину сбоя. Если переменная СсылкаНаОбъект уже содержит ссылку на документ, то обращение к свойству .Ссылка является избыточным. В некоторых случаях это может привести к тому, что платформа не сможет корректно разрешить путь к табличной части ИтогиРевизии. Правильным вариантом будет прямое обращение к табличной части через ссылку на объект:
Для Каждого лкСтрока Из СсылкаНаОбъект.ИтогиРевизии Цикл
// Правильное обращение к коллекции
КонецЦикла;
Также важно убедиться, что ИтогиРевизии — это именно табличная часть документа, а не обычный реквизит. Попытка перебора обычного реквизита (строки или числа) всегда будет приводить к ошибке итератора.
При написании кода вручную легко допустить опечатку, которую конфигуратор в режиме проверки может не заметить, если это касается имен процедур или функций, вызываемых в динамическом контексте. В нашем случае была допущена ошибка в стандартном методе:
Соообщить("Не выбран документ!");
Метода с тремя буквами "о" в платформе не существует. Правильное написание — Сообщить(). Стоит помнить, что в современных конфигурациях на базе БСП (Библиотека стандартных подсистем) для вывода сообщений пользователю рекомендуется использовать метод ОбщегоНазначенияКлиентСервер.СообщитьПользователю(), так как он корректно работает и на стороне сервера, и на стороне клиента.
Когда цикл по табличной части наконец заработал, программист может столкнуться со следующей проблемой: невозможностью обратиться к конкретной колонке. Рассмотрим ситуацию подробнее. Код выглядит так:
Для Каждого лкСтрока Из СсылкаНаОбъект.ИтогиРевизии Цикл
ОбластьСотрудники.Параметры.Сотрудник = лкСтрока.Сотрудник;
КонецЦикла;
Если система выдает ошибку, что поле Сотрудник не обнаружено, следует проверить два момента:
ИтогиРевизии называется именно Сотрудник, а не, например, ФизЛицо или Работник.Это одна из самых коварных ошибок, которая часто ставит в тупик новичков. Она означает, что вы пытаетесь обратиться к свойству Параметры у объекта, который равен Неопределено. Проанализируем типичный фрагмент кода:
ОбластьСотрудники = Макет.ПолучитьОбласть("Сотрудники");
ОбластьСотрудники.Параметры.Сотрудник = лкСтрока.Сотрудник;
Если в макете печатной формы отсутствует область с именем "Сотрудники" (или имя написано с ошибкой, лишним пробелом, в другом регистре), метод Макет.ПолучитьОбласть() вернет Неопределено. Следовательно, попытка обратиться к ОбластьСотрудники.Параметры вызовет фатальный сбой.
Как предотвратить эту ошибку:
ОбластьСотрудники = Макет.ПолучитьОбласть("Сотрудники");
Если ОбластьСотрудники <> Неопределено Тогда
ОбластьСотрудники.Параметры.Сотрудник = лкСтрока.Сотрудник;
КонецЕсли;
Рассмотрим исправленный и дополненный вариант процедуры печати для внешней обработки (обычное приложение). Мы объединим все рекомендации, чтобы код был надежным и понятным.
Процедура ПечатьДокумента()
// 1. Проверяем, заполнен ли документ-основание
Если СсылкаНаОбъект = Неопределено Или СсылкаНаОбъект.Пустая() Тогда
Сообщить("Документ не выбран, печать невозможна!");
Возврат;
КонецЕсли;
ТабДок = Новый ТабличныйДокумент;
// Получаем макет из текущей внешней обработки
Макет = ЭтотОбъект.ПолучитьМакет("МакетАкта");
// 2. Формируем Шапку
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
Если ОбластьШапка <> Неопределено Тогда
// Используем Заполнить(), чтобы автоматически перенести данные
// из реквизитов документа в параметры макета с такими же именами
ОбластьШапка.Параметры.Заполнить(СсылкаНаОбъект);
// Ручное заполнение специфических полей, если имена не совпадают
ОбластьШапка.Параметры.НомерДокумента = СсылкаНаОбъект.Номер;
ОбластьШапка.Параметры.ДатаДокумента = СсылкаНаОбъект.Дата;
ТабДок.Вывести(ОбластьШапка);
КонецЕсли;
// 3. Формируем строки (Табличную часть)
// Проверяем наличие табличной части перед итерацией
Для Каждого лкСтрока Из СсылкаНаОбъект.ИтогиРевизии Цикл
ОбластьСтрока = Макет.ПолучитьОбласть("Сотрудники");
Если ОбластьСтрока <> Неопределено Тогда
ОбластьСтрока.Параметры.Заполнить(лкСтрока);
ТабДок.Вывести(ОбластьСтрока);
КонецЕсли;
КонецЦикла;
// 4. Формируем Подвал
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
Если ОбластьПодвал <> Неопределено Тогда
ОбластьПодвал.Параметры.Комментарий = СсылкаНаОбъект.Комментарий;
ОбластьПодвал.Параметры.Ответственный = СсылкаНаОбъект.Ответственный;
ТабДок.Вывести(ОбластьПодвал);
КонецЕсли;
// 5. Настройка отображения и вывод
ТабДок.ТолькоПросмотр = Истина;
ТабДок.ОтображатьСетку = Ложь;
ТабДок.Показать("Печать Акта Удержания");
КонецПроцедуры
Для того чтобы параметры в коде Область.Параметры.ИмяПараметра работали корректно, необходимо правильно настроить ячейки в самом табличном документе (макете):
Проанализировав ситуацию, мы видим, что большинство ошибок при создании ВПФ связаны с невнимательностью к деталям: регистру имен, правильному обращению к коллекциям и проверке существования объектов. Следуя структурированному подходу и проверяя каждый этап формирования документа, вы сможете избежать подобных сложностей в будущем.