Как исправить ошибку подключения внешней печатной формы и реализовать печать комплекта документов в 1С?

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

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

Анализ причины ошибки: почему «Неопределено» ломает подключение?

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


АдресВоВременномХранилище = ПоместитьВоВременноеХранилище(Справочники.ДополнительныеОтчетыИОбработки.НайтиПоРеквизиту("ИмяОбъекта", ИмяОбъекта).Ссылка.ХранилищеОбработки.Получить());
СтрокаВО = ВнешниеОбработки.Подключить(АдресВоВременномХранилище, , Ложь);

Проблема номер один: Метод НайтиПоРеквизиту возвращает пустую ссылку, если элемент с таким именем не найден. Если ссылка пустая, то обращение к ХранилищеОбработки.Получить() возвращает Неопределено. В результате в ПоместитьВоВременноеХранилище передается пустое значение, и метод Подключить закономерно завершается аварией, так как ожидает двоичные данные файла, а получает пустоту.

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

Решение 1: Исправление поиска и безопасная инициализация объекта

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


Функция СоздатьОбъектВПФ(ИмяОбъекта)
    
    СсылкаВО = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоРеквизиту("ИмяОбъекта", ИмяОбъекта);
    
    Если СсылкаВО.Пустая() Тогда
        ВызватьИсключение "Внешняя обработка с именем " + ИмяОбъекта + " не найдена в справочнике!";
    КонецЕсли;

    // Получаем двоичные данные файла обработки
    ДвоичныеДанные = СсылкаВО.ХранилищеОбработки.Получить();
    Если ТипЗнч(ДвоичныеДанные) <> Тип("ДвоичныеДанные") Тогда
        ВызватьИсключение "Хранилище обработки пусто или содержит некорректные данные.";
    КонецЕсли;

    АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
    ИмяПодключеннойФормы = ВнешниеОбработки.Подключить(АдресХранилища, , Ложь);
    
    Возврат ВнешниеОбработки.Создать(ИмяПодключеннойФормы);
    
КонецФункции

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

Решение 2: Использование стандартных механизмов БСП (Рекомендуется)

Если ваша конфигурация — это современная «Бухгалтерия предприятия 3.0», «ERP» или «Управление торговлей 11», то в ней уже есть готовый программный интерфейс для работы с дополнительными отчетами и обработками. Вместо того чтобы изобретать велосипед с временными хранилищами, используем возможности общего модуля ДополнительныеОтчетыИОбработки.

Проанализируем шаги для правильного вызова:

  1. Найдем ссылку на нужную обработку по наименованию или имени объекта.
  2. Вызовем метод ОбъектВнешнейОбработки, который сам выполнит подключение и вернет готовый экземпляр объекта.
  3. Вызовем экспортную процедуру Печать этого объекта.

Посмотрим на пример кода, который делает работу «Комплекта» стабильной:


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

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

Почему возникает ошибка «Значение не является значением объектного типа (Печать)»?

Эта ошибка, упомянутая в сообщении 6, возникает, когда объект был успешно создан, но у него нет экспортной процедуры с именем Печать, либо вызов происходит некорректно. Проанализируем типичные ошибки в структуре ВПФ:

Тонкости формирования коллекции печатных форм

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

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

Альтернативный подход: Состав набора (без программирования)

Прежде чем писать сложный код «обертки» для комплекта, разберем штатную возможность БСП, о которой многие забывают. В справочнике «Дополнительные отчеты и обработки» для каждой команды можно настроить состав набора печатных форм. Если ваша конфигурация поддерживает механизм «Печать комплектов», вы можете просто зарегистрировать обе формы (УПД и Накладную) и в интерфейсе пользователя при нажатии кнопки «Печать» отметить обе формы галочками. Если же бухгалтерия требует «печать одной кнопкой без лишних движений», то описанный выше программный метод через создание третьей ВПФ-контейнера является единственным верным решением.

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

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

  1. Используйте ДополнительныеОтчетыИОбработки.ОбъектВнешнейОбработки(Ссылка) для получения объекта — это самый надежный способ в современных конфигурациях.
  2. Всегда проверяйте ссылку на наличие (Не Ссылка.Пустая()) перед получением объекта.
  3. Приведите все вложенные ВПФ к единому стандарту БСП: процедура Печать с 4-мя параметрами должна быть в Модуле объекта и иметь ключевое слово Экспорт.
  4. Следите за тем, чтобы имена объектов (в свойствах метаданных обработки в конфигураторе) были уникальными, иначе 1С может вернуть кешированный объект предыдущей обработки.

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

← На главную