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