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

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

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

Почему БСП блокирует печать непроведенных документов?

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

Способ 1. Использование переопределяемого модуля на клиенте

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

Рассмотрим пример кода, который нужно разместить в этом модуле (лучше использовать расширение):


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

В данном примере мы проверяем тип объекта. Если это ВозвратТовараОтКлиента, мы говорим системе, что берем ответственность за печать на себя, устанавливая СтандартнаяОбработка = Ложь. Однако стоит учесть, что это отключит проверку для всех внешних печатных форм этого типа документа.

Способ 2. Точечная настройка для конкретной внешней формы

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

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

Способ 3. Модификация команд печати в расширении

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

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


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

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

Способ 4. Проверка логики внутри самой внешней печатной формы

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

ГДЕ ДокументТаблица.Ссылка.Проведен = ИСТИНА

Или просто:

ГДЕ ДокументТаблица.Ссылка.Проведен

Если вы пытаетесь распечатать непроведенный документ, такой запрос просто не выберет ни одной строки, и вы получите пустой бланк. Поэтому при создании ВПФ обязательно:

  1. Проверьте текст запроса в модуле объекта внешней обработки.
  2. Удалите фильтры по полю Проведен.
  3. Убедитесь, что данные берутся из объектных таблиц документа, а не из регистров (так как в регистрах данных непроведенного документа нет).

Рекомендации по безопасности и методологии

Разберем важный момент: печать непроведенного документа — это риск. На печатной форме может быть указана сумма или количество, которые еще не подтверждены и не отражены в учете. Поэтому при использовании СтандартнаяОбработка = Ложь в ПередВыполнениемКомандыПечатиВнешнейПечатнойФормы, рекомендуется добавить интерактивный вопрос пользователю:


// Пример интерактивной проверки
Если Не ПечатаемыеОбъекты[0].Проведен Тогда
    Режим = РежимДиалогаВопрос.ДаНет;
    Текст = "Документ не проведен. Данные в печатной форме могут быть неактуальны. Продолжить?";
    // Обратите внимание: в клиентских переопределяемых модулях 
    // использование Вопрос() ограничено, лучше использовать ПоказатьВопрос().
КонецЕсли;

В современных конфигурациях 1С работа в процедурах "Перед..." часто требует асинхронного подхода. Если вы используете ПоказатьВопрос, выполнение кода продолжится не дожидаясь ответа. В этом случае правильнее будет всегда устанавливать СтандартнаяОбработка = Ложь, а затем самостоятельно вызывать процедуру печати из описания оповещения после подтверждения пользователем.

Заключение

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

← На главную