Как исправить ошибку «Значение не является значением объектного типа (ТабличныйДокумент)» во внешней печатной форме 1С

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

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

В этой статье мы подробно разберем, почему возникает эта ошибка, проанализируем внутренние механизмы работы БСП с печатными формами и шаг за шагом реализуем архитектурно правильное решение, соответствующее всем стандартам разработки фирмы «1С».

Выясняем причину возникновения ошибки

Давайте проанализируем код, который изначально написал автор темы в Сообщении 0:


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    
    ПечатнаяФорма = УправлениеПечатью.СведенияОПечатнойФорме(КоллекцияПечатныхФорм, "ПФ_MXL_УниверсальныйПередаточныйДокумент981");
    
    ПечатнаяФорма.ТабличныйДокумент = СформироватьТабличныйДокумент(МассивОбъектов, ОбъектыПечати);
    
КонецПроцедуры

В этой процедуре разработчик пытается получить строку коллекции печатных форм с помощью метода УправлениеПечатью.СведенияОПечатнойФорме. Данная функция осуществляет поиск в таблице значений КоллекцияПечатныхФорм по колонке ИмяВРЕГ (приводя переданный идентификатор к верхнему регистру).

Если функция находит строку с указанным идентификатором, она возвращает строку таблицы значений (которая ведет себя как объект с соответствующими свойствами). Если же строка с таким идентификатором не найдена, функция возвращает значение Неопределено. Именно в этот момент и происходит сбой: при попытке обратиться к несуществующему свойству у значения Неопределено платформа выдает критическую ошибку.

Почему же функция возвращает Неопределено? Для этого есть две основные причины:

  1. Несовпадение идентификаторов. Идентификатор команды печати, зарегистрированный в функции СведенияОВнешнейОбработке(), не совпадает с идентификатором, который передается в метод СведенияОПечатнойФорме(). Они должны совпадать символ в символ, включая регистр. Из логов ошибки в Сообщении 9 видно, что система искала идентификатор ПечатьУПДсвернутая, а в коде процедуры Печать был прописан жесткий идентификатор макета ПФ_MXL_УниверсальныйПередаточныйДокумент981.
  2. Внешняя обработка не обновлена в базе данных. Если разработчик изменил идентификатор команды в модуле внешней обработки, но забыл перерегистрировать (обновить) файл обработки в справочнике «Дополнительные отчеты и обработки» в режиме «1С:Предприятие», система продолжит передавать в процедуру Печать старый идентификатор, что приведет к ошибке поиска.

В Сообщении 14 автор попытался решить проблему кардинальным путем — пересозданием коллекции:


КоллекцияПечатныхФорм = УправлениеПечатьюВызовСервера.НоваяКоллекцияПечатныхФорм("ПФ_MXL_УниверсальныйПередаточныйДокумент981");    
КоллекцияПечатныхФорм[0].ТабличныйДокумент = ТабличныйДокумент;

Внимание! Это грубая ошибка проектирования! Параметр КоллекцияПечатныхФорм передается в процедуру Печать из вызывающего контекста БСП уже инициализированным и заполненным. Он может содержать настройки для нескольких различных макетов, если пользователь выбрал групповую или комплектную печать. Полная перезапись этого параметра разрушает логику БСП и лишает систему возможности корректно обрабатывать другие печатные формы.

Решаем проблему правильно по стандартам БСП

Для того чтобы избежать ручного поиска по таблице значений и исключить возникновение подобных ошибок, в БСП существует специализированный и безопасный метод — УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию. Давайте рассмотрим правильный шаблон написания процедуры Печать для внешней обработки.


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    
    // Идентификатор команды должен в точности соответствовать тому,
    // который зарегистрирован в функции СведенияОВнешнейОбработке()
    ИдентификаторКоманды = "ПечатьУПДсвернутая";
    
    // Проверяем, затребовал ли пользователь печать именно этого макета
    Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, ИдентификаторКоманды) Тогда
        
        // Формируем табличный документ с помощью нашей экспортной функции
        ТабличныйДокумент = СформироватьТабличныйДокумент(МассивОбъектов, ОбъектыПечати);
        
        // Выводим документ в коллекцию стандартным безопасным методом БСП
        УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
            КоллекцияПечатныхФорм,
            ИдентификаторКоманды,
            "Универсальный передаточный документ (свернутый)", // Представление для пользователя
            ТабличныйДокумент
        );
        
    КонецЕсли;
    
КонецПроцедуры

Использование связки методов НужноПечататьМакет и ВывестиТабличныйДокументВКоллекцию полностью страхует разработчика от ошибок обращения к неопределенным объектам и корректно встраивает печатную форму в общий механизм комплектной печати БСП.

Важная ловушка: сигнатура процедуры «Печать»

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

Если во внешнюю обработку по ошибке вставить процедуру с 5 параметрами, БСП при вызове передаст параметры по порядку. В результате в переменную КоллекцияПечатныхФорм попадет структура параметров печати, а сама коллекция окажется сдвинута. Любая попытка вызвать методы работы с коллекцией приведет к падению программы. Всегда строго следите за типом разрабатываемого объекта и количеством параметров!

Реализация групповой печати и связывание объектов

При написании функции формирования табличного документа важно правильно обрабатывать массив передаваемых объектов (ведь пользователь может выделить в списке сразу несколько документов и отправить их на печать одновременно). Также необходимо регистрировать соответствие областей печатной формы конкретным документам с помощью параметра ОбъектыПечати.

Давайте рассмотрим пример структуры функции СформироватьТабличныйДокумент:


Функция СформироватьТабличныйДокумент(МассивОбъектов, ОбъектыПечати) Экспорт
    
    ТабличныйДокумент = Новый ТабличныйДокумент;
    ТабличныйДокумент.АвтоМасштаб = Истина;
    ТабличныйДокумент.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;
    
    // Получаем макет внешней обработки
    МакетОбработки = ПолучитьМакет("ПФ_MXL_УниверсальныйПередаточныйДокумент981");
    
    ПервыйДокумент = Истина;
    
    Для Каждого СсылкаНаДокумент Из МассивОбъектов Цикл
        
        // Если это не первый документ, вставляем разрыв страницы
        Если Не ПервыйДокумент Тогда
            ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
        Иначе
            ПервыйДокумент = Ложь;
        КонецЕсли;
        
        // Фиксируем начальную строку вывода текущего документа для ОбъектовПечати
        НомерСтрокиНачала = ТабличныйДокумент.ВысотаТаблицы + 1;
        
        // --- Здесь идет код вывода областей макета (Шапка, Табличная часть, Подвал) ---
        // Пример вывода шапки:
        // ОбластьШапка = МакетОбработки.ПолучитьОбласть("Шапка");
        // ОбластьШапка.Параметры.Заполнить(СсылкаНаДокумент);
        // ТабличныйДокумент.Вывести(ОбластьШапка);
        
        // Связываем выведенную область табличного документа с конкретным объектом базы данных
        УправлениеПечатью.ЗадатьОбластьПечатиДокумента(
            ТабличныйДокумент, 
            НомерСтрокиНачала, 
            ОбъектыПечати, 
            СсылкаНаДокумент
        );
        
    КонецЦикла;
    
    Возврат ТабличныйДокумент;
    
КонецФункции

Использование метода УправлениеПечатью.ЗадатьОбластьПечатиДокумента крайне важно. Это позволяет платформе:

  1. Отображать удобный интерактивный список документов в левой части формы предварительного просмотра печати.
  2. Корректно разделять документы при отправке печатных форм по электронной почте прямо из программы.
  3. Оптимизировать вывод на двустороннюю печать (чтобы новый документ всегда начинался с нового листа бумаги).

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

← На главную