Как отловить нажатие системной кнопки печать в 1С 8.3

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

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

Суть проблемы и задачи контроля

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

  1. Фиксации факта печати в Регистре сведений для аудита.
  2. Сохранения версии документа в момент вывода на бумагу.
  3. Генерации уникальных идентификаторов (например, QR-кодов), которые связывают бумажную копию с конкретным состоянием данных в информационной базе.
  4. Предотвращения печати документов, не прошедших определенные проверки.

Разберем по шагам несколько подходов: от программного ограничения прав до использования специализированных внешних компонент.

Метод 1. Использование внешней компоненты (Hooks)

Наиболее эффективным техническим решением для обычных форм является использование механизма Windows Hooks через внешнюю компоненту. Этот метод позволяет перехватывать системные сообщения операционной системы, предназначенные для окна приложения 1С. Проанализируем пример реализации с использованием библиотеки hooklib.dll.

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


Процедура ПриНачалеРаботыСистемы()
    // Предполагаем, что компонента хранится в общем макете в виде ZIP-архива
    Если ПодключитьВнешнююКомпоненту("ОбщийМакет.HookLib", "Hooklib", AddInType.Native) Тогда
        Попытка
            Hooklib = Новый("AddIn.Hooklib.PrintHook");
            // Включаем перехват системных событий
            Hooklib.Перехват();
        Исключение
            Сообщить("Ошибка инициализации компоненты перехвата!");
        КонецПопытки;
    Иначе
        Сообщить("Компонента HookLib не подключена. Контроль печати недоступен.");
    КонецЕсли;
КонецПроцедуры

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


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

Важное ограничение: использование подобных низкоуровневых компонент часто привязано к архитектуре процессора. Большинство таких решений стабильно работают только на x86 (32-битных) клиентах 1С. При использовании 64-битного клиента потребуется соответствующая версия библиотеки.

Метод 2. Управление свойством «Вывод» табличного документа

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

Мы можем установить свойство Вывод в значение ИспользованиеВывода.Запретить. В этом случае системные кнопки печати в меню «Файл» и на панели инструментов станут неактивными. Чтобы пользователь все же мог распечатать документ, мы создаем собственную кнопку «Печать» на форме.

Алгоритм действий будет следующим:

  1. При формировании печатной формы устанавливаем ЭлементыФормы.ПолеТабличногоДокумента.Вывод = ИспользованиеВывода.Запретить;.
  2. Создаем на форме командную панель с кнопкой «Печать».
  3. В обработчике нажатия нашей кнопки выполняем регистрацию события и программно вызываем печать.

Рассмотрим пример кода для нашей кнопки:


Процедура КоманднаяПанельПечать(Кнопка)
    // 1. Фиксируем версию в базе данных
    ЗафиксироватьВерсиюПечатнойФормы();

    // 2. Временно разрешаем вывод для программной печати
    ЭлементыФормы.ПолеДокумента.Вывод = ИспользованиеВывода.Разрешить;
    
    // 3. Отправляем на принтер без показа диалогов или с ними
    ЭлементыФормы.ПолеДокумента.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
    
    // 4. Снова запрещаем вывод, чтобы закрыть лазейку через горячие клавиши
    ЭлементыФормы.ПолеДокумента.Вывод = ИспользованиеВывода.Запретить;
КонецПроцедуры

Этот метод считается более «чистым» с точки зрения поддержки конфигурации, так как не зависит от внешних DLL и разрядности платформы.

Метод 3. Интеграция QR-кодов для сверки версий

Выясним, как связать факт нажатия кнопки с бизнес-логикой, упомянутой в обсуждении. Задача автора заключалась в том, чтобы при печати формировался QR-код, содержащий версию данных. Рассмотрим, как это реализовать структурно.

В момент перехвата события (будь то через Hooklib или через свою кнопку) мы должны собрать метаданные:

Эти данные записываются в Регистр сведений. При печати этот же набор данных кодируется в QR-код и выводится в нижнем углу табличного документа. В дальнейшем, при сканировании бумажного документа, система сможет мгновенно проверить: менялись ли данные в 1С после того, как была выпущена эта бумажная копия. Если версия в базе не совпадает с версией в коде — документ считается неактуальным.

Метод 4. Использование UI Automation (для продвинутых задач)

Для конфигураций, работающих под Windows, существует еще один способ — использование COM-объекта MSScriptControl.ScriptControl или библиотек работы с UI Automation. Это позволяет отслеживать появление в операционной системе новых окон, принадлежащих процессу 1cv8.exe. Когда пользователь нажимает «Печать», открывается модальное окно настроек принтера. Скрипт может обнаружить появление этого окна и сигнализировать об этом в 1С через механизм внешних событий.

Однако стоит учитывать, что работа с MSScriptControl на 64-битных системах требует регистрации компоненты в реестре или использования альтернативных оберток, так как стандартный msscript.ocx является 32-битным.

Резюме

Подведем итог. Нативной возможности «из коробки» подписаться на событие ПриПечати для системных кнопок в 1С 8.3 (особенно в обычных формах) не существует.

Наиболее надежным и стабильным решением является комбинированный подход: программный запрет стандартного вывода через свойство Вывод и использование собственных кнопок печати, которые полностью контролируют жизненный цикл документа. Если же критически важно оставить пользователю возможность работать через системное меню, единственным выходом остается использование внешних компонент-перехватчиков (Hooks), учитывая их специфику работы с разрядностью ОС.

← На главную