Почему внешняя печатная форма в 1С 8.3 выдает ошибку "Печатная форма недоступна" или "Табличный документ не сформирован"?

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

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

Проанализируем причины этой проблемы и разберем по шагам, как правильно настроить модуль объекта внешней обработки, чтобы избежать подобных ошибок.

Причина 1: Несоответствие идентификаторов команд

Одной из самых коварных ошибок является расхождение между Идентификатором, который мы указываем при регистрации печатной формы, и строковым значением, которое мы проверяем в процедуре Печать. Если система БСП не находит совпадений, она пропускает блок формирования документа, в результате чего коллекция печатных форм остается пустой.

Рассмотрим структуру функции регистрации. Обратим внимание на колонку Идентификатор:


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = Новый Структура;
    ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
    
    МассивНазначений = Новый Массив;
    МассивНазначений.Добавить("Документ.Доверенность");
    ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
    
    ПараметрыРегистрации.Вставить("Наименование", "Доверенность (внешняя)");
    ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
    ПараметрыРегистрации.Вставить("Версия", "1.0");

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

Теперь выясним, как эта команда обрабатывается в процедуре Печать. Проанализируем типичную ошибку: если в проверке НужноПечататьМакет указано другое имя, код внутри условия никогда не выполнится.


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

Причина 2: Массив объектов вместо одиночной ссылки

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

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

Неправильно:


ТекстЗапроса = "ВЫБРАТЬ ... ГДЕ Документ.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", МассивОбъектов[0]); // Ошибка, если массив пустой или имеет другую структуру

Правильно:


ТекстЗапроса = "ВЫБРАТЬ ... ГДЕ Документ.Ссылка В (&МассивОбъектов)";
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов); // Передаем массив целиком

Использование оператора В (&МассивОбъектов) — это стандарт разработки для БСП. Это позволяет вашей печатной форме корректно работать не только из формы документа, но и при групповой печати из списка документов.

Причина 3: Контекст выполнения и "ЭтотОбъект"

В управляемом приложении, когда обработка запускается как внешняя, у нее нет жесткого контекста ЭтотОбъект при вызове методов получения макета, если вы находитесь в модуле объекта и вызываете его некорректно. Рассмотрим, как правильно получать макет во внешней печатной форме.

В функции формирования печатной формы используйте метод ПолучитьМакет непосредственно:


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

Причина 4: Безопасный режим и права доступа

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

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

Рекомендация: Если вы доверяете коду печатной формы, устанавливайте ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);. Также внутри кода формирования печатной формы полезно использовать УстановитьПривилегированныйРежим(Истина), чтобы данные (например, паспортные данные сотрудников или зарплатные сведения) считывались даже у пользователей с ограниченными правами.

Полный пример корректного модуля объекта ВПФ

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


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

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

КонецПроцедуры

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

КонецФункции

Подведем итоги

Чтобы ваша внешняя печатная форма работала стабильно, придерживайтесь следующих правил:

  1. Синхронизируйте идентификаторы: Строка Идентификатора в СведенияОВнешнейОбработке должна быть идентична строке в НужноПечататьМакет и ВывестиТабличныйДокументВКоллекцию.
  2. Работайте с массивом: Всегда используйте В (&МассивОбъектов) в запросах.
  3. Соблюдайте экспортность: Процедура Печать в модуле объекта обязательно должна иметь ключевое слово Экспорт.
  4. Проверяйте безопасный режим: Если форма использует сложные функции типовых модулей, безопасный режим должен быть выключен.
  5. Заполняйте ОбъектыПечати: Это необходимо для корректной работы сервисных функций печати (сохранение в PDF, отправка по e-mail).

Соблюдение этих простых принципов позволит вам создавать надежные ВПФ, которые не будут "падать" после подключения к информационной базе.

← На главную