В практике автоматизации на базе 1С:Управление производственным предприятием (УПП) 1.3 часто возникают задачи, когда бизнес-процесс требует жесткой связки между физическим действием (печатью документа) и учетным событием (проведением документа в бухгалтерском или налоговом учете). Типичный пример: кладовщик на складе печатает форму ТОРГ-13 при перемещении товаров, и в этот момент документ должен «отразиться» в бухгалтерии.
Основная сложность здесь заключается в трех аспектах: необходимость предварительного просмотра (чтобы не тратить бумагу зря), недостаток прав у складского персонала для работы с регламентированным учетом и архитектурные особенности платформы 1С 8.2. Разберем пошагово, как реализовать этот механизм корректно и безопасно.
Проанализируем ситуацию, описанную автором. Если при нажатии кнопки «Печать» форма сразу отправляется на принтер, минуя экран, значит, в программном коде используется метод Напечатать(). У объекта ТабличныйДокумент есть два ключевых метода для вывода:
Напечатать(РежимИспользованияДиалогаПечати) — отправляет данные на принтер. Если параметр установлен в Ложь, печать начинается мгновенно.Показать(Заголовок, ЗакрыватьПриВыборе) — открывает стандартное окно просмотра 1С, где пользователь может проверить данные, изменить количество копий или выбрать принтер.Рассмотрим подробнее, как изменить логику вывода в вашей собственной печатной форме.
Выясним причину отсутствия окна просмотра. В типовых конфигурациях на обычных формах (таких как УПП 1.3) печать чаще всего реализована через общую форму ПечатьДокументов или через прямой вызов метода Показать(). Если вы создали свою кнопку на форме документа, ваш код должен выглядеть примерно так:
Процедура ОсновныеДействияФормыПечать(Кнопка)
// 1. Пробуем провести документ перед печатью
Если Не ПровестиДокументВПривилегированномРежиме() Тогда
Возврат; // Если проведение не удалось, печать не открываем
КонецЕсли;
// 2. Формируем печатную форму
ТабДок = СформироватьТОРГ13(); // Ваша функция формирования макета
// 3. Выводим на экран для предварительного просмотра
ТабДок.Показать("Печать ТОРГ-13: " + ЭтотОбъект.Ссылка);
КонецПроцедуры
Использование метода Показать() вместо Напечатать() полностью решает проблему «неудобства пользователей», так как они получают стандартный интерфейс просмотра перед отправкой задания на принтер.
Проанализируем ситуацию с правами. Бухгалтеры часто против того, чтобы давать кладовщикам полные права на Бухгалтерский и Налоговый учет. Однако проведение документа ПеремещениеТоваров требует наличия прав на запись в соответствующие регистры бухгалтерии. Вместо того чтобы временно «выдавать роли» пользователю (что является небезопасным и сложным в реализации методом), мы воспользуемся механизмом Привилегированного режима.
Привилегированный режим позволяет выполнять операции с данными без проверки прав доступа (RLS) текущего пользователя. Это идеальное решение для нашей задачи: кладовщик инициирует печать, а система «под капотом» от имени системы проводит документ в БУ/НУ.
Рассмотрим пример реализации проведения в модуле объекта или в общем модуле с флагом «Сервер»:
Функция ПровестиДокументВПривилегированномРежиме() Экспорт
// Устанавливаем режим, игнорирующий права пользователя
УстановитьПривилегированныйРежим(Истина);
// Проверяем, нужно ли проводить
Если ЭтотОбъект.Проведен И ЭтотОбъект.ОтражатьВБухгалтерскомУчете Тогда
Возврат Истина; // Уже проведен
КонецЕсли;
// Устанавливаем нужные флаги учета
ЭтотОбъект.ОтражатьВБухгалтерскомУчете = Истина;
ЭтотОбъект.ОтражатьВНалоговомУчете = Истина;
Попытка
// Записываем с проведением
ЭтотОбъект.Записать(РежимЗаписиДокумента.Проведение);
Возврат Истина;
Исключение
Сообщить("Ошибка при автоматическом проведении: " + ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
// Отключаем режим (хотя он сам отключится при выходе из процедуры)
УстановитьПривилегированныйРежим(Ложь);
КонецФункции
Посмотрим на ситуацию шире. В УПП 1.3 существует универсальный механизм печати. Чтобы ваша печатная форма выглядела «родной», лучше возвращать ТабличныйДокумент в процедуру УниверсальныеМеханизмы.ПечатьДокумента. Разберем, как совместить проведение и вызов типового окна.
В модуле объекта документа ПеремещениеТоваров в процедуре Печать добавим логику проверки проведения:
Процедура Печать(ИмяМакета, КоличествоЭкземпляров = 1, НаПринтер = Ложь, НепосредственнаяПечать = Ложь) Экспорт
// Если выбрана наша форма ТОРГ-13
Если ИмяМакета = "ТОРГ13_Своя" Тогда
// Автоматическое проведение перед формированием макета
Если Не ЭтотОбъект.Проведен Тогда
Если Не ПровестиДокументВПривилегированномРежиме() Тогда
Возврат; // Прерываем, если не удалось провести (например, нет остатков)
КонецЕсли;
КонецЕсли;
// Формируем документ
ТабДок = СформироватьТОРГ13();
// Используем типовой механизм для вывода
УниверсальныеМеханизмы.ПечатьДокумента(ТабДок, КоличествоЭкземпляров, НаПринтер, "ТОРГ-13", НепосредственнаяПечать);
КонецЕсли;
КонецПроцедуры
Разберем несколько критических моментов, которые могут возникнуть при использовании такого подхода:
Если Не ЭтотОбъект.Проведен Тогда.... Если документ уже проведен, не нужно пытаться перепроводить его при каждом нажатии кнопки «Печать». Это создаст лишнюю нагрузку на сервер и может привести к конфликтам блокировок, если другой пользователь в этот момент открыл документ.ЭтотОбъект.Записать(РежимЗаписиДокумента.Проведение) в контексте формы может потребовать предварительного прочтения объекта из базы (ЭтотОбъект.Прочитать()), если форма была открыта долгое время.Подводя итог, мы выяснили, что для реализации задачи необходимо:
ПривилегированныйРежим для обхода ограничений RLS у кладовщиков.Показать() или использовать УниверсальныеМеханизмы.ПечатьДокумента для обеспечения предварительного просмотра.Такой подход позволяет соблюсти требования бухгалтерии по своевременному отражению операций и сохранить удобство работы складского персонала в интерфейсе 1С 8.2.