В процессе разработки в среде 1С:Предприятие 8.3 на базе Библиотеки стандартных подсистем (БСП) программисты часто сталкиваются с жестким ограничением: система блокирует печать документов, которые не были проведены. Это логично с точки зрения учета, чтобы избежать печати некорректных данных, однако в реальном бизнесе часто требуется распечатать черновик, например, "Возврат товара от клиента" или "Заказ поставщику", еще до момента его окончательного проведения. В этой статье мы подробно разберем, как обойти это ограничение для внешних печатных форм (ВПФ), используя механизмы расширений и переопределяемых модулей.
Прежде чем переходить к коду, проанализируем причину такого поведения системы. В БСП за печать отвечает подсистема Печать. Когда пользователь нажимает кнопку печати, система проверяет статус документа. Если свойство ПроверкаПроведенияПередПечатью для данной команды установлено в значение Истина (а для документов это значение по умолчанию), БСП вызывает стандартный обработчик, который выводит предупреждение и прерывает процесс. Для встроенных форм это настраивается в модуле менеджера, но для внешних форм ситуация сложнее, так как они регистрируются динамически.
Это самый быстрый способ, который позволяет вмешаться в процесс непосредственно перед вызовом печати внешней формы. Нам понадобится общий модуль ДополнительныеОтчетыИОбработкиКлиентПереопределяемый. В нем существует процедура ПередВыполнениемКомандыПечатиВнешнейПечатнойФормы, которая создана специально для таких случаев.
Рассмотрим пример кода, который нужно разместить в этом модуле (лучше использовать расширение):
Процедура ПередВыполнениемКомандыПечатиВнешнейПечатнойФормы(ПечатаемыеОбъекты, СтандартнаяОбработка) Экспорт
// Проанализируем ситуацию: если в массиве объектов есть наш документ
// и мы хотим разрешить его печать без проверки, отключаем стандартную обработку.
Для Каждого СсылкаИзСписка Из ПечатаемыеОбъекты Цикл
Если ТипЗнч(СсылкаИзСписка) = Тип("ДокументСсылка.ВозвратТовараОтКлиента") Тогда
// Устанавливаем Ложь, чтобы БСП пропустила проверку проведения
СтандартнаяОбработка = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В данном примере мы проверяем тип объекта. Если это ВозвратТовараОтКлиента, мы говорим системе, что берем ответственность за печать на себя, устанавливая СтандартнаяОбработка = Ложь. Однако стоит учесть, что это отключит проверку для всех внешних печатных форм этого типа документа.
Если нам нужно разрешить печать не для всех форм документа, а только для одной конкретной, мы должны проанализировать идентификатор команды. Выясним причину, по которой предыдущий код может быть избыточен: он влияет на все ВПФ. Чтобы сделать проверку более гибкой, нам нужно получить доступ к данным команды.
К сожалению, в процедуру ПередВыполнениемКомандыПечатиВнешнейПечатнойФормы не передается напрямую ссылка на справочник ДополнительныеОтчетыИОбработки. Но мы можем использовать контекст выполнения или проверить имя печатной формы, если она передается в параметрах. Если же мы работаем через расширение модуля менеджера документа, рассмотрим другой путь.
Посмотрим на пример из сообщения 8, где автор пытается изменить свойство команды в процедуре ДобавитьКомандыПечати. Для внешних печатных форм этот метод работает иначе, так как они добавляются в таблицу команд динамически подсистемой ДополнительныеОтчетыИОбработки.
Чтобы это сработало, нужно перехватить момент формирования структуры команд. Разберем по шагам, как это сделать через расширение к общему модулю УправлениеПечатью или в модуле менеджера конкретного документа:
&После("ДобавитьКомандыПечати")
Процедура сн_ДобавитьКомандыПечати(КомандыПечати)
// Проанализируем существующие команды в таблице КомандыПечати
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Идентификатор", "НужныйИдентификаторВПФ");
НайденныеСтроки = КомандыПечати.НайтиСтроки(ПараметрыОтбора);
Для каждого СтрокаКоманды из НайденныеСтроки Цикл
// Принудительно отключаем проверку проведения
СтрокаКоманды.ПроверкаПроведенияПередПечатью = Ложь;
КонецЦикла;
КонецПроцедуры
Важный нюанс: для внешних обработок Идентификатор часто совпадает с именем обработки или уникальным идентификатором, назначенным при регистрации. Проверьте содержимое таблицы КомандыПечати в отладчике, чтобы точно знать, какое поле фильтровать.
Даже если вы успешно "прошли" мимо кнопки и БСП разрешила запуск формы, вы можете столкнуться с тем, что печатная форма выходит пустой. Проанализируем ситуацию: часто разработчики копируют запросы для ВПФ из типовых конфигураций. В типовых запросах почти всегда стоит фильтр:
ГДЕ ДокументТаблица.Ссылка.Проведен = ИСТИНА
Или просто:
ГДЕ ДокументТаблица.Ссылка.Проведен
Если вы пытаетесь распечатать непроведенный документ, такой запрос просто не выберет ни одной строки, и вы получите пустой бланк. Поэтому при создании ВПФ обязательно:
Проведен.Разберем важный момент: печать непроведенного документа — это риск. На печатной форме может быть указана сумма или количество, которые еще не подтверждены и не отражены в учете. Поэтому при использовании СтандартнаяОбработка = Ложь в ПередВыполнениемКомандыПечатиВнешнейПечатнойФормы, рекомендуется добавить интерактивный вопрос пользователю:
// Пример интерактивной проверки
Если Не ПечатаемыеОбъекты[0].Проведен Тогда
Режим = РежимДиалогаВопрос.ДаНет;
Текст = "Документ не проведен. Данные в печатной форме могут быть неактуальны. Продолжить?";
// Обратите внимание: в клиентских переопределяемых модулях
// использование Вопрос() ограничено, лучше использовать ПоказатьВопрос().
КонецЕсли;
В современных конфигурациях 1С работа в процедурах "Перед..." часто требует асинхронного подхода. Если вы используете ПоказатьВопрос, выполнение кода продолжится не дожидаясь ответа. В этом случае правильнее будет всегда устанавливать СтандартнаяОбработка = Ложь, а затем самостоятельно вызывать процедуру печати из описания оповещения после подтверждения пользователем.
Мы проанализировали несколько способов решения задачи. Самым стабильным решением для внешних печатных форм в БСП является использование расширения для общего модуля ДополнительныеОтчетыИОбработкиКлиентПереопределяемый. Это позволяет точечно управлять процессом проверки проведения, обеспечивая гибкость для конечных пользователей и сохраняя стабильность системы.