Как зафиксировать количество нажатий на кнопку «Печать» и вести историю версий в управляемых формах 1С?

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

В процессе разработки в среде 1С:Предприятие 8.3 часто возникает задача контроля за бумажным документооборотом. Одной из таких задач является фиксация факта печати документа: кто, когда и сколько раз выводил форму на экран или принтер. Это необходимо для того, чтобы на самом печатном листе отображался номер версии (например, «Версия печати №5»), что позволяет отличить актуальный документ от устаревших копий.

В этой статье мы подробно разберем несколько подходов к реализации этой задачи — от простых манипуляций с формой до профессиональной архитектуры с использованием модулей менеджера и регистров сведений.

Постановка задачи и выбор стратегии

Рассмотрим стандартную ситуацию: в конфигурации есть документ, и нам нужно при каждом нажатии на кнопку Печать выполнять следующие действия:

  1. Увеличить счетчик количества распечаток.
  2. Зафиксировать текущего пользователя и дату/время события.
  3. Вывести эти данные в макет печатной формы (в «подвал» или «шапку»).
  4. Обеспечить актуальность данных на форме документа, если она открыта.

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

Вариант 1. Реализация логики в модуле менеджера (рекомендуемый подход)

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

Рассмотрим пример кода в модуле менеджера, где мы будем не только формировать табличный документ, но и фиксировать факт обращения к нему:


Процедура Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт

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

КонецПроцедуры

Метод ЗафиксироватьВерсиюПечати должен быть реализован либо внутри модуля менеджера, либо в общем модуле. Выясним, где лучше хранить эти данные.

Вариант 2. Где хранить историю: Табличная часть vs Регистр сведений

Существует два основных способа хранения истории печати:

Способ А. Табличная часть документа.

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

Способ Б. Регистр сведений (Профессиональный).

Создадим непериодический регистр сведений ИсторияПечатиДокументов со следующей структурой:

Разберем пример процедуры записи в такой регистр:


Процедура ЗафиксироватьВерсиюПечати(СсылкаНаДокумент)
    
    // Определяем следующий номер версии
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ МАКСИМУМ(ИсторияПечати.НомерПорядковый) КАК МаксНомер 
    |ИЗ РегистрСведений.ИсторияПечатиДокументов КАК ИсторияПечати 
    |ГДЕ ИсторияПечати.Объект = &Объект";
    Запрос.УстановитьПараметр("Объект", СсылкаНаДокумент);
    
    Результат = Запрос.Выполнить().Выгрузить();
    НовыйНомер = ?(Результат.Количество() > 0, Результат[0].МаксНомер + 1, 1);
    
    // Записываем данные
    МенеджерЗаписи = РегистрыСведений.ИсторияПечатиДокументов.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Объект = СсылкаНаДокумент;
    МенеджерЗаписи.НомерПорядковый = НовыйНомер;
    МенеджерЗаписи.Пользователь = ПараметрыСеанса.ТекущийПользователь;
    МенеджерЗаписи.ДатаПечати = ТекущаяДата();
    МенеджерЗаписи.Записать();
    
    // Оповещаем систему об изменении данных объекта
    ОповеститьОбИзменении(СсылкаНаДокумент);
    
КонецПроцедуры

Вариант 3. Обновление формы после печати

Одна из проблем, с которой сталкиваются новички: после нажатия на кнопку Печать данные в базе обновились (счетчик увеличился), но на самой открытой форме документа пользователь по-прежнему видит старое значение (например, «Версия 4» вместо «Версия 5»).

Для решения этой задачи проанализируем механизм оповещений в 1С. После записи в регистр или ТЧ на сервере, клиентское приложение должно узнать, что данные изменились. Рассмотрим пошагово:

  1. В серверном коде вызываем ОповеститьОбИзменении(Ссылка).
  2. В модуле управляемой формы документа используем обработчик события ОбработкаОповещения.

&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия = "Запись_ИсторияПечати" И Параметр = Объект.Ссылка Тогда
        // Перечитываем данные с сервера, чтобы обновить форму
        Прочитать(); 
    КонецЕсли;
КонецПроцедуры

Нюанс: Просмотр или реальная печать?

Важно понимать техническое ограничение платформы 1С. Метод ТабДок.Показать() открывает окно предварительного просмотра. Пользователь может закрыть его, не отправляя документ на принтер, но счетчик в нашей реализации уже сработает. Платформа не предоставляет гарантированного обратного события от драйвера принтера «Документ успешно напечатан на бумаге».

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

Дополнительный контроль через штрихкодирование

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

Проанализируем решение: в регистр сведений можно записывать GUID (уникальный идентификатор) каждой конкретной распечатки. Этот GUID выводится на макет в виде штрихкода. В будущем, сканируя штрихкод на бумаге, система точно скажет: «Это была распечатка от 12:05 пользователем Ивановым, она является 3-й по счету».

Итоги и рекомендации

  1. Не используйте свою кнопку «Печать», если можно переопределить стандартную команду в модуле менеджера. Это сохранит единообразие интерфейса.
  2. Используйте Регистр Сведений для хранения логов. Это не нагружает объект документа и позволяет строить отчеты по активности пользователей.
  3. Не забывайте про ОповеститьОбИзменении, иначе пользователи будут жаловаться, что «номер версии на экране не меняется».
  4. Учитывайте статус документа. Проанализируем логику: стоит ли увеличивать номер версии, если печатается черновик (непроведенный документ)? Обычно рекомендуется фиксировать только печать проведенных документов, а для черновиков выводить надпись «КОПИЯ» или «ЧЕРНОВИК» без инкремента счетчика.

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

← На главную