Почему внешняя печатная форма в УТ 11 требует проведение документа и как это обойти?

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

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

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

Выясняем причину: почему БСП игнорирует настройки регистрации

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


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

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ВызовСерверногоМетода", ПоказыватьОповещение = Ложь, Модификатор = "ПечатьMXL")
    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Представление = Представление;
    НоваяКоманда.Идентификатор = Идентификатор;
    НоваяКоманда.Использование = Использование;
    НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
    НоваяКоманда.Модификатор = Модификатор;
    НоваяКоманда.ПроверкаПроведенияПередПечатью = Ложь; // Отключаем проверку проведения!
КонецПроцедуры

Мы ожидаем, что раз свойству ПроверкаПроведенияПередПечатью присвоено значение Ложь, система позволит распечатать документ. Однако при попытке печати из формы непроведенного документа (например, Реализация товаров и услуг) перед нами все равно появляется диалоговое окно с предупреждением и предложением провести документ.

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

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

Способ 1. Использование механизма расширений конфигурации

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

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

Давайте разберем по шагам, как реализовать этот перехват в расширении:

  1. Создаем новое расширение конфигурации.
  2. Добавляем в расширение общий модуль ДополнительныеОтчетыИОбработкиКлиентПереопределяемый.
  3. Изменяем метод ПередВыполнениемКомандыПечатиВнешнейПечатнойФормы, используя аннотацию &Вместо.

Ниже представлен пример реализации кода в расширении:


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

Установка параметра СтандартнаяОбработка = Ложь сообщает БСП, что стандартные проверки (включая проверку проведения документа перед формированием печатной формы) выполнять не требуется. Система сразу перейдет к вызову процедуры печати в модуле вашей внешней обработки.

Способ 2. Переход на использование клиентского метода (без расширения)

Что делать, если использовать расширения по каким-то причинам нельзя, а конфигурация должна оставаться полностью типовой? В этом случае мы можем изменить архитектуру самой внешней печатной формы (удобно через внешняя печатная форма для УТ 11), изменив тип использования команды в функции СведенияОВнешнейОбработке().

Вместо стандартного режима ВызовСерверногоМетода мы будем использовать режим ВызовКлиентскогоМетода. При таком подходе БСП передает управление форме нашей внешней обработки, минуя свои стандартные проверки проведения на клиенте.

Разберем этот процесс по шагам.

Шаг 1. Меняем параметры регистрации команды

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


Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ВызовКлиентскогоМетода", ПоказыватьОповещение = Ложь, Модификатор = "ПечатьMXL")
    // Код заполнения команды аналогичен, но Использование теперь строго "ВызовКлиентскогоМетода"
КонецПроцедуры

Шаг 2. Создаем форму внешней обработки

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


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

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

Важнейший нюанс: переработка запросов для непроведенных документов

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

Выясним причину этой проблемы. В современных конфигурациях (таких как УТ 11, КА 2, ERP 2) алгоритмы печати типовых документов (например, накладной ТОРГ-12 или УПД) оптимизированы. Чтобы не нагружать систему повторным расчетом сложных данных, запросы внутри менеджеров печати обращаются не напрямую к табличным частям документов, а к регистрам накопления и регистрам сведений:

Когда документ не проведен, записей в этих регистрах попросту нет! Следовательно, стандартный запрос, скопированный из типовой конфигурации, вернет пустой результат.

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


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

Запрос.УстановитьПараметр("СписокДокументов", МассивОбъектов);
РезультатЗапроса = Запрос.Выполнить();

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

Резюме

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

← На главную