Вопрос отслеживания количества копий печатных форм актуален для многих торговых компаний. Это необходимо для предотвращения злоупотреблений, контроля расхода бумаги и исключения повторных отгрузок по дубликатам документов. В типовой конфигурации 1С:Управление торговлей 10.3 (на платформе 8.2 или 8.3 в режиме обычных форм) встроенного счетчика печати не существует. Рассмотрим подробно, какими способами можно решить эту задачу, начиная от простых доработок внутри базы и заканчивая системным мониторингом очереди печати.
Самый логичный и часто используемый метод — это фиксация факта формирования печатной формы в самой базе данных. Разберем по шагам, как это реализовать.
Для начала нам необходимо где-то хранить информацию о количестве распечаток. Создадим для этого новый Регистр сведений, назовем его, например, ИсторияПечатиДокументов.
Объект (тип ДокументСсылка.РеализацияТоваровУслуг) и Пользователь (тип СправочникСсылка.Пользователи).Количество (тип Число, длина 10).Теперь проанализируем, в какой момент нужно увеличивать этот счетчик. В 1С 8.2 формирование печатных форм обычно происходит в модуле объекта документа или в специализированных общих модулях (например, УниверсальныеМеханизмы). Нам нужно найти процедуру Печать.
Рассмотрим пример кода, который мы вставим в обработчик формирования печатной формы. Нам нужно зафиксировать факт нажатия кнопки "Печать":
Процедура ЗафиксироватьПечать(ТекущийДокумент)
МенеджерЗаписи = РегистрыСведений.ИсторияПечатиДокументов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = ТекущийДокумент;
МенеджерЗаписи.Пользователь = ПараметрыСеанса.ТекущийПользователь;
МенеджерЗаписи.Прочитать();
Если МенеджерЗаписи.Выбран() Тогда
МенеджерЗаписи.Количество = МенеджерЗаписи.Количество + 1;
Иначе
МенеджерЗаписи.Объект = ТекущийДокумент;
МенеджерЗаписи.Пользователь = ПараметрыСеанса.ТекущийПользователь;
МенеджерЗаписи.Количество = 1;
КонецЕсли;
МенеджерЗаписи.Записать();
КонецПроцедуры
Важно понимать различие: если вы используете метод ТабДокумент.Показать(), система зафиксирует открытие формы предпросмотра, но не гарантирует, что пользователь нажал на значок принтера. Если же используется прямой вывод на принтер через ТабДокумент.Напечатать(), то учет будет более точным.
Если нам требуется более глубокий контроль (например, учет реальных заданий, ушедших в спулер Windows), мы можем воспользоваться механизмом WMI (Windows Management Instrumentation). Это позволяет обратиться к операционной системе и получить список заданий печати.
Проанализируем ситуацию: каждое задание в очереди печати Windows имеет имя, которое часто совпадает с заголовком окна 1С (например, "Реализация товаров и услуг №..."). Мы можем написать функцию, которая будет опрашивать класс Win32_PrintJob.
Посмотрим на пример реализации на языке VBScript, который можно адаптировать для работы через COMОбъект в 1С:
// Пример логики обращения к очереди печати через WMI
Locator = Новый COMОбъект("WbemScripting.SWbemLocator");
Service = Locator.ConnectServer(".", "root\cimv2");
// Запрос заданий печати, где в заголовке есть номер нашей накладной
Задания = Service.ExecQuery("SELECT * FROM Win32_PrintJob WHERE Caption LIKE '%Реализация %'");
Для Каждого Задание Из Задания Цикл
// Здесь мы можем получить статус задания и количество страниц
Сообщить("Документ: " + Задание.Caption + " Статус: " + Задание.JobStatus);
КонецЦикла;
Этот метод позволяет увидеть, сколько раз документ реально попал в очередь принтера, но он технически сложнее, так как требует прав администратора и настройки сетевых доступов, если принтеры общие.
После того как мы научились собирать данные в регистр сведений, нам нужно отобразить их пользователю. Выясним, как добавить колонку в форму списка документа "Реализация товаров и услуг".
ПриВыводеСтроки пропишем код получения данных из нашего регистра:
Процедура СписокПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
// Запрос к регистру ИсторияПечатиДокументов по ДанныеСтроки.Ссылка
// Установка значения в колонку ОформлениеСтроки.Ячейки.КолВоПечати.УстановитьТекст(РезультатЗапроса);
КонецПроцедуры
Важный нюанс: использование события ПриВыводеСтроки с запросом к базе может замедлить работу списка. Для оптимизации рекомендуется использовать левое соединение в Запросе динамического списка, если конфигурация позволяет редактировать его схему (в 8.2 это делается через настройку источника данных).
Рассмотрим ситуацию, когда недостаточно просто знать число. Нужно сделать так, чтобы копии визуально отличались от оригинала. Мы можем динамически изменять макет печатной формы при каждом повторном выводе.
Если задача стоит критически остро (например, жесткий аудит безопасности), проанализируем использование специализированных утилит, таких как O&K Print Watch. Эти программы перехватывают все задания печати на уровне драйверов и сохраняют их в свою базу данных (часто SQL или XML).
В 1С можно настроить регламентное задание, которое будет раз в несколько минут считывать XML-файл отчета этой программы и обновлять данные в нашей базе. Это самый надежный способ, так как он учитывает даже те случаи, когда документ был напечатан не через кнопку "Печать", а через системный диалог выбора принтера (Ctrl+P).
Мы разобрали несколько подходов к решению задачи. Для большинства организаций будет достаточно Варианта 1 (создание регистра сведений и модификация модуля печати). Это решение легко поддерживать, оно не зависит от внешнего софта и дает достаточно точную информацию о действиях пользователей в системе 1С. Однако помните, что ни один программный метод не защитит от обычного ксерокса — для борьбы с ним используйте организационные меры и нумерованные бланки строгой отчетности.