Как ограничить печать документа или этикетки одной копией в 1С:Предприятие

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

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

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

В чем сложность стандартного механизма печати?

Если мы просто выводим сформированный макет на экран пользователя с помощью метода Показать(), система предоставляет пользователю полный доступ к стандартному командному интерфейсу платформы. Пользователь может:

  1. Изменить количество копий в стандартном диалоговом окне печати Windows.
  2. Сохранить документ во внешний файл (PDF, Excel) через меню «Файл — Сохранить как» и печатать его неограниченное количество раз напрямую из операционной системы.
  3. Скопировать содержимое табличного документа в буфер обмена.

Для предотвращения этих действий нам понадобится комплексный подход, состоящий из ограничения прав платформы, прямой отправки макета на принтер и фиксации события печати в базе данных.


Шаг 1. Блокировка интерактивных действий пользователя (свойство «Вывод»)

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

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


// Создаем табличный документ для формирования этикетки
ТабДок = Новый ТабличныйДокумент;

// Заполняем параметры макета и выводим области
// ... (код формирования макета)

// Блокируем стандартные интерактивные функции платформы
ТабДок.Вывод = ИспользованиеВывода.Запретить;

Когда свойство Вывод установлено в значение ИспользованиеВывода.Запретить, у пользователя при просмотре табличного документа на экране кнопки «Печать», «Предварительный просмотр» и «Сохранить» в главном меню программы станут неактивными.

Важное примечание: Если вам требуется ограничить права пользователя глобально во всей системе, лучшим решением будет снять флажок с роли пользователя в Конфигураторе для права «Вывод». В этом случае пользователь вообще не сможет сохранять файлы из 1С на диск, если в коде явно не прописано обратное (ИспользованиеВывода.Разрешить).


Шаг 2. Прямая печать на принтер без вывода на экран

Чтобы исключить возможность ручного изменения количества копий, мы должны полностью отказаться от показа табличного документа на экране монитора. Программа должна отправить документ напрямую на принтер.

Рассмотрим, как реализовать моментальную отправку на печать одной копии:


// Настраиваем параметры печати табличного документа
ТабДок.ИмяПринтера = "Zebra_TLP2844"; // Указываем точное имя принтера в системе
ТабДок.КоличествоКопий = 1;          // Жестко ограничиваем тираж одной копией

// Отправляем документ на печать без вывода диалогового окна Windows
ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);

Параметр РежимИспользованияДиалогаПечати.НеИспользовать гарантирует, что система не покажет стандартное окно настроек принтера, в котором пользователь мог бы вручную исправить цифру «1» в поле «Количество копий».


Шаг 3. Фиксация факта печати в регистре сведений

Для того чтобы система «помнила» о том, что документ уже распечатывался, нам понадобится создать в конфигураторе независимый непериодический Регистр сведений. Назовем его ИсторияПечатиДокументов.

Настроим структуру регистра следующим образом:

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


&НаСервере
Функция ДокументУжеРаспечатан(СсылкаНаДокумент)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ИсторияПечати.ДокументСсылка КАК ДокументСсылка
        |ИЗ
        |   РегистрСведений.ИсторияПечатиДокументов КАК ИсторияПечати
        |ГДЕ
        |   ИсторияПечати.ДокументСсылка = &ДокументСсылка";
        
    Запрос.УстановитьПараметр("ДокументСсылка", СсылкаНаДокумент);
    
    РезультатЗапроса = Запрос.Выполнить();
    Возврат Не РезультатЗапроса.Пустой();
    
КонецФункции

&НаСервере
Процедура ЗафиксироватьФактПечати(СсылкаНаДокумент)
    
    МенеджерЗаписи = РегистрыСведений.ИсторияПечатиДокументов.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.ДокументСсылка = СсылкаНаДокумент;
    МенеджерЗаписи.Пользователь = Пользователи.ТекущийПользователь();
    МенеджерЗаписи.ДатаПечати = ТекущаяДата();
    
    // Записываем информацию в базу данных
    МенеджерЗаписи.Записать(Истина);
    
КонецПроцедуры

Теперь объединим проверку и печать в один общий обработчик нажатия кнопки на клиенте:


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

Шаг 4. Решение проблемы «первого блина комом» (замятие бумаги)

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

Рассмотрим два основных архитектурных решения этой проблемы:

Метод А. Санкция супервизора (старшего смены)

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


&НаСервереБезКонтекста
Функция ПроверитьПарольАдминистратора(ВведенныйПароль)
    // Проверка соответствия пароля ответственного лица в базе данных
    // Возвращает Истина, если авторизация успешна
КонецФункции

Метод Б. Вывод водяного знака «ДУБЛИКАТ»

Если бизнес-процесс допускает повторную печать, но требует обязательной визуальной идентификации копии, мы можем программно модифицировать макет при повторном обращении. Если запись в регистре найдена, мы выводим на этикетку фоновую надпись или крупный текст «ДУБЛИКАТ» или «КОПИЯ №...». Это позволит использовать наклеенную этикетку повторно, но защитит от подлога оригинального документа.


Шаг 5. Системное администрирование: закрытие аппаратных лазеек

Опытные пользователи могут попытаться обойти ограничения 1С на уровне операционной системы Windows. Проанализируем эти уязвимости и перекроем их:

  1. Виртуальные принтеры (PDF, XPS): Если в системе установлены виртуальные принтеры (например, «Microsoft Print to PDF»), пользователь может направить «одну копию» туда, получить PDF-файл, а затем печатать его на физическом принтере этикеток бесконечное количество раз.
    Решение: Системный администратор на уровне групповых политик (GPO) домена Active Directory или настроек терминального сервера должен удалить все виртуальные принтеры из профиля пользователя, оставив доступ только к одному физическому принтеру этикеток.
  2. Печать скриншотов: Снятие снимка экрана с последующей печатью картинки.
    Решение: Полный отказ от интерактивного вывода макета на экран (что мы уже реализовали в Шаге 2 с помощью метода Напечатать()). Если макет не отображается на мониторе, сделать его снимок невозможно.

Шаг 6. Альтернативный подход: проверка уникальности на этапе сканирования

Многие ведущие специалисты по автоматизации учета рекомендуют переносить логику контроля уникальности с момента печати на момент использования (сканирования) штрихкода.

Рассмотрим, как работает эта схема:

  1. При формировании этикетки в штрихкод закладывается уникальный идентификатор (например, GUID строки или ID документа + порядковый номер распечатки).
  2. Пользователь может распечатать несколько копий этой этикетки (например, в случае брака).
  3. Когда кладовщик сканирует штрихкод при отгрузке товара, система выполняет поиск этого идентификатора в регистре использованных кодов.
  4. Если код сканируется впервые, документ успешно проводится, а код заносится в базу как «погашенный».
  5. При попытке отсканировать вторую физическую копию этой же этикетки система выдает критическую ошибку: «Этот штрихкод уже был использован ранее в документе №ХХХ!».

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

← На главную