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