Как программно провести документ в обход установленной даты запрета изменения данных?

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

В процессе сопровождения и доработки конфигураций на платформе 1С:Предприятие 8.3 (особенно современных решений вроде УТ 11, ERP 2 или КА 2) разработчики часто сталкиваются с необходимостью программно записать или провести документ в периоде, который уже закрыт датой запрета редактирования. Стандартные методы записи объекта в таких случаях вызывают исключение или просто блокируют операцию.

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

Разбор механизма проверки даты запрета

Давайте проанализируем ситуацию: в типовых конфигурациях, построенных на базе Библиотеки стандартных подсистем (БСП), проверка даты запрета выполняется не в самом модуле объекта, а в подписках на события (например, ПередЗаписью или ПриЗаписи). Это означает, что даже если вы вызываете метод Записать() в коде, система автоматически инициирует проверку через глобальные обработчики.

Многие ошибочно полагают, что установка свойства ОбменДанными.Загрузка = Истина решит проблему. Действительно, во многих случаях это отключает прикладные проверки, но в подсистеме даты запрета часто прописано условие, которое игнорирует этот флаг, если проверка инициирована определенным образом. Поэтому нам требуются более специализированные инструменты.

Способ 1: Использование параметров сеанса (решение с форума)

Рассмотрим метод, который помог автору темы. Он основан на манипуляции параметром сеанса, который считывается механизмом БСП при проверке прав на изменение данных. Суть заключается в том, чтобы временно выставить флаг разрешения, выполнить запись и вернуть флаг в исходное состояние.

Этот код лучше всего размещать в модуле формы (если действие инициируется пользователем) или в серверной процедуре. Разберем пример реализации в обработчике ПередЗаписьюНаСервере:


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

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

Важный нюанс: обязательно используйте блок Попытка...Исключение или обработчик ПослеЗаписи, чтобы гарантировать возврат параметра ПропуститьПроверкуЗапретаИзменения в значение Ложь. В противном случае текущий сеанс пользователя до конца работы будет игнорировать любые даты запрета, что критически опасно для целостности данных.

Способ 2: Использование программного интерфейса БСП (рекомендуемый)

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

Проанализируем вызов метода из общего модуля ДатыЗапретаИзменения:


// Включаем игнорирование проверки
ДатыЗапретаИзменения.ПропуститьПроверкуЗапретаИзменения(Истина);

Попытка
    ОбъектДокумент.Записать(РежимЗаписиДокумента.Проведение);
Исключение
    // Обработка ошибки
КонецПопытки;

// Выключаем игнорирование проверки
ДатыЗапретаИзменения.ПропуститьПроверкуЗапретаИзменения(Ложь);

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

Способ 3: Манипуляция через «Дополнительные свойства» объекта

Иногда проверка в подписках на события настроена так, что она ищет определенный маркер прямо внутри записываемого объекта. Давайте посмотрим на пример использования структуры ДополнительныеСвойства. Это позволяет "протащить" указание об обходе проверки непосредственно в обработчик подписки.


ТекущийОбъект = СсылкаНаДокумент.ПолучитьОбъект();

// Ключ может называться "ПропуститьПроверкуЗапретаИзменения" 
// или "ОтказПриПроверкеДатыЗапрета" в зависимости от версии БСП
ТекущийОбъект.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения", Истина);

// Также полезно установить флаг загрузки, чтобы отключить другие прикладные проверки
ТекущийОбъект.ОбменДанными.Загрузка = Истина;

ТекущийОбъект.Записать();

Способ 4: Использование расширения (радикальный метод)

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

  1. Создаем новое расширение и снимаем флаг Безопасный режим (иначе УстановитьПривилегированныйРежим не сработает).
  2. Находим подписку на событие, отвечающую за дату запрета (обычно это что-то вроде ПроверитьДатуЗапретаПередЗаписьюДокумента).
  3. Добавляем обработчик &После или &Вместо, где принудительно устанавливаем Отказ = Ложь.

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

Риски и последствия обхода даты запрета

Давайте выясним, к чему может привести неосторожное использование данных методов. Проведение документа в закрытом периоде — это не просто "запись строчки в таблицу". Это влечет за собой каскад изменений в системе:

Поэтому, прежде чем применять программный обход, мы рекомендуем рассмотреть альтернативу: временное изменение настроек даты запрета для конкретного пользователя-администратора через интерфейс программы (раздел НСИ и Администрирование -> Настройки пользователей и прав), внесение правок и возврат настроек в исходное состояние.

Резюме

Мы рассмотрели несколько технических подходов к решению задачи. Наиболее стабильным и современным является использование ПараметрыСеанса.ПропуститьПроверкуЗапретаИзменения или вызов соответствующей функции модуля ДатыЗапретаИзменения в привилегированном режиме. Помните о необходимости возвращать состояние системы в исходное положение и всегда оценивайте риски для учета.

← На главную