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