В процессе разработки часто возникает задача зафиксировать факт физической отправки документа на принтер. Например, это требуется для защиты документа от последующих правок или для ведения лога обращений к конфиденциальной информации. Однако стандартная кнопка Печать (иконка принтера) на панели инструментов сформированного табличного документа является системным элементом платформы 1С. Это означает, что при её нажатии платформа напрямую взаимодействует с драйвером принтера или диалогом операционной системы, не вызывая встроенных событий в коде 1С. Рассмотрим подробнее, какими способами можно обойти это ограничение и внедрить необходимую логику.
Разберем ситуацию: когда мы вызываем метод ТабличныйДокумент.Показать(), открывается стандартное окно просмотра. Кнопки на его панели инструментов не привязаны к командам конфигурации. Проанализируем имеющиеся механизмы: платформа не предоставляет обработчика события типа ПослеНажатияКнопкиПечать. Поэтому нам придется либо подменять стандартные механизмы печати своими, либо внедряться в логику Библиотеки стандартных подсистем (БСП).
Если ваша конфигурация построена на базе БСП (например, УТ 11, ERP 2, БП 3.0), то печать документов обычно проходит через общие модули управления печатью. Хотя саму кнопку в окне предпросмотра мы не перехватим, мы можем зафиксировать момент формирования печатной формы или нажатия кнопки печати в форме самого документа. Рассмотрим, как это сделать через расширение.
Нам необходимо создать расширение и применить механизм &После для процедуры печати. Чаще всего целевой процедурой является УправлениеПечатьюКлиент.ВыполнитьКомандуПечати. Проанализируем пример кода для расширения:
&После("ВыполнитьКомандуПечати")
Процедура Ист_ВыполнитьКомандуПечати(ИмяМенеджераПечати, ИменаКоманд, ОбъектыПечати, ПараметрыФормы, ВладелецФормы)
// В этот момент пользователь уже инициировал печать.
// ОбъектыПечати содержит массив ссылок на документы.
Для Каждого СсылкаИзСписка Из ОбъектыПечати Цикл
// Здесь можно вызвать серверный метод для записи в регистр или установки статуса
ЗафиксироватьФактПечатиНаСервере(СсылкаИзСписка);
КонецЦикла;
КонецПроцедуры
Этот метод хорош тем, что он фиксирует само намерение пользователя напечатать документ. Однако, если пользователь просто открыл форму предпросмотра и закрыл её, не нажав на «принтер», событие все равно сработает. Если требуется более строгий контроль, перейдем к следующему методу.
Выясним причину, почему это самый надежный метод: создавая собственную форму для отображения табличного документа, мы полностью контролируем состав кнопок. Вы можете скрыть стандартную панель инструментов и нарисовать свою кнопку «Печать».
Разберем алгоритм реализации по шагам:
ТабличныйДокумент и выносим его на форму как поле табличного документа.Напечатать().Пример кода для кнопки на вашей форме:
&НаКлиенте
Процедура НапечататьИЗафиксировать(Команда)
// 1. Сначала выполняем бизнес-логику (например, блокировку документа)
РезультатЗаписи = ЗафиксироватьПечатьВБазе(ОбъектПечати);
Если РезультатЗаписи Тогда
// 2. Вызываем штатный диалог печати Windows
// РежимИспользованияПринтера.ПоказатьДиалог позволяет пользователю выбрать принтер
Элементы.ПолеТабличногоДокумента.Напечатать(РежимИспользованияПринтера.ПоказатьДиалог);
Сообщить("Документ отправлен на печать и заблокирован от изменений.");
Иначе
Предупреждение("Не удалось зафиксировать факт печати. Печать отменена.");
КонецЕсли;
КонецПроцедуры
Посмотрим на ситуацию под другим углом. Если директор требует, чтобы после печати документ нельзя было менять, мы можем использовать свойство табличного документа Вывод. Это свойство управляет возможностью печати и копирования данных из формы предпросмотра.
Рассмотрим логику: мы можем выводить документ в режиме «Только просмотр» без права печати, пока пользователь не нажмет специальную кнопку «Утвердить и распечатать». Проанализируем фрагмент кода:
ТабДок = Новый ТабличныйДокумент;
// Заполняем ТабДок данными...
// Если документ еще не прошел стадию фиксации в базе:
Если Не ДокументЗафиксирован Тогда
ТабДок.Вывод = ИспользованиеВывода.Запретить;
// Пользователь увидит документ на экране, но кнопка Печать будет заблокирована платформой
Иначе
ТабДок.Вывод = ИспользованиеВывода.Разрешить;
КонецЕсли;
ТабДок.Показать("Предварительный просмотр");
Такой подход заставляет пользователя сначала выполнить действие в системе (нажать кнопку утверждения), которое запишет данные в базу, и только после этого платформа разблокирует системную кнопку печати.
Если вы работаете с незнакомой конфигурацией и не знаете, где именно формируется печатная форма, используйте Замер производительности. Включите замер, нажмите кнопку печати и остановите замер. В списке вызванных процедур ищите те, которые находятся в модулях с названиями УправлениеПечатью, ПечатьДокументовКлиент или в менеджерах конкретных документов. Это поможет вам найти точное место для установки точки останова или внедрения кода через расширение.
Важно понимать, что ни один метод в 1С не дает 100% гарантии, что бумага действительно вышла из принтера (она могла застрять, или в принтере кончились чернила). Однако для целей управленческого учета наиболее правильным считается следующий подход:
СтатусПечати (Булево) или ДатаПечати.ПередЗаписью документа добавить проверку: если СтатусПечати = Истина и текущий пользователь не имеет прав «Редактирование распечатанных документов», то Отказ = Истина.Проанализировав все варианты, мы видим, что наиболее гибким является использование собственной формы предпросмотра, так как она позволяет полностью кастомизировать процесс взаимодействия пользователя с принтером.