Почему возникает ошибка "В обработчике печати не был сформирован табличный документ" и как её исправить?

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

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

Разберем причину возникновения ошибки

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

Проанализируем ситуацию на примере кода. В функции СведенияОВнешнейОбработке мы регистрируем команду:


ДобавитьКоманду(ТаблицаКоманд, 
               НСтр("ru = 'Печать акта'"), 
               "Акт", // Это Идентификатор команды
               "ВызовСерверногоМетода", 
               Истина, 
               "ПечатьMXL");

Здесь строковое значение "Акт" является уникальным ключом — Идентификатором. Выясним причину ошибки: в процедуре Печать разработчик часто допускает опечатку или путает идентификатор команды с именем макета. Посмотрим на некорректный вызов:


УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "Макет1", "Акт", ...);

В данном методе второй параметр — это именно ИмяМакета (в контексте коллекции он должен соответствовать Идентификатору из таблицы команд). Если в БСП передана команда с ID "Акт", а вы пытаетесь зарегистрировать в коллекции форму с ID "Макет1", система просто не «увидит» результат работы вашего кода. Для исправления ситуации необходимо, чтобы идентификатор команды в регистрации и второй параметр функции вывода в коллекцию совпадали.

Шаг 1: Правильная регистрация и экспортная функция Печать

Рассмотрим эталонную структуру регистрации команды и её последующей обработки. Важно следить за количеством параметров в функции Печать. В современных версиях БСП (начиная с 2.x и 3.x) их должно быть ровно четыре.


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

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

Шаг 2: Исправление логики формирования для нескольких документов

Проанализируем распространенную ошибку, связанную с циклом Для каждого. В сообщении №4 автор создает Новый ТабличныйДокумент внутри цикла по массиву объектов. Это критическая ошибка проектирования ВПФ. Если пользователь выделит в списке 10 документов и нажмет печать, программа 10 раз перезапишет переменную ТабДокумент, и в итоге функция вернет только последний документ. Более того, БСП ожидает один общий табличный документ, где страницы разделены разделителями.

Посмотрим на пример правильной организации цикла:


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

Шаг 3: Технические нюансы безопасного режима и методов отображения

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

Также обратим внимание на Безопасный режим. Если при регистрации указано БезопасныйРежим = Истина, 1С накладывает ограничения:

  1. Запрещена работа с файловой системой и реестром.
  2. Запрещено использование внешних компонентов (COM-объектов).
  3. Ограничен доступ к некоторым методам склонения ФИО (например, СклонениеПредставленийОбъектов.Просклонять() может требовать привилегированного режима или специфических разрешений в профиле безопасности).

Если ваша функция формирования «падает» из-за недостатка прав доступа к ресурсам в безопасном режиме, коллекция останется пустой, и пользователь увидит обсуждаемую ошибку. Попробуйте временно установить БезопасныйРежим = Ложь для диагностики.

Шаг 4: Оптимизация запросов

Проанализируем код из сообщения №4. Мы видим выполнение запроса к справочнику КонтактныеЛица внутри цикла. Это антипаттерн разработки 1С. При печати 100 документов система сделает 100 обращений к базе данных, что существенно замедлит формирование. Рассмотрим, как сделать правильно: нужно собрать все ссылки из МассивОбъектов, выполнить один общий запрос к базе, выгрузить результат в таблицу значений или структуру, и уже из неё брать данные внутри цикла формирования документа.

Это не только ускорит работу, но и предотвратит ошибки таймаута на больших объемах данных, которые также могут привести к «недоформированию» табличного документа.

Итог: Чтобы исправить ошибку «В обработчике печати не был сформирован табличный документ», проверьте соответствие идентификатора в СведенияОВнешнейОбработке и в ВывестиТабличныйДокументВКоллекцию, убедитесь, что вы не используете клиентские методы на сервере, и проверьте, что функция Печать принимает актуальное количество параметров.

← На главную