Как ограничить редактирование документов по истечении срока с даты создания в 1С:Документооборот?

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

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

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

Особенности архитектуры 1С:Документооборот и ограничения RLS

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

  1. Тип метаданных: В конфигурации «1С:Документооборот» внутренние, входящие и исходящие документы хранятся не в документах, а в справочниках (например, Справочник.ВнутренниеДокументы, Справочник.ВходящиеДокументы). Из-за этого стандартная подсистема БСП «Даты запрета изменения» в типовом варианте для них не предназначена.
  2. Ограничения языка RLS: В шаблонах RLS невозможно использовать функцию получения текущего системного времени. RLS работает исключительно на уровне запросов СУБД с полями таблиц базы данных и параметрами сеанса.
  3. Проблема параметров сеанса: Если передавать текущую дату через параметр сеанса (&ТекущаяДата), значение фиксируется один раз при старте сеанса. Если пользователь не перезапускает программу в течение нескольких дней, дата в сеансе устаревает, и проверка прав начинает работать некорректно.
  4. Производительность: Динамические вычисления разницы дат в условиях RLS блокируют использование индексов базы данных, что приводит к полному сканированию таблиц (Full Table Scan) и резкому замедлению открытия списков.

Способ 1. Блокировка на уровне формы (ПриОткрытии)

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

Посмотрим на пример кода в обработчике формы. Число 86400 — это количество секунд в одних сутках (24 часа × 60 минут × 60 секунд), так как при вычитании дат в платформе 1С результат получается в секундах:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    
    КоличествоДнейБлокировки = 5; // Срок в днях
    СрокВСекундах = КоличествоДнейБлокировки * 86400;
    
    // Сравниваем разницу дат с допустимым порогом
    Если (ТекущаяДата() - Объект.ДатаСоздания) > СрокВСекундах Тогда
        ЭтаФорма.ТолькоПросмотр = Истина;
    КонецЕсли;

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

Ограничения способа: Установка свойства ТолькоПросмотр = Истина защищает документ только от ручного редактирования в открытой форме. Данные по-прежнему можно будет перезаписать через групповое изменение реквизитов, внешние обработки, HTTP/SOAP-сервисы или бизнес-процессы.

Способ 2. Надежный контроль на сервере через подписку на событие ПередЗаписью

Для гарантированной защиты данных от изменения любым способом создадим подписку на событие ПередЗаписью для объектов справочников документов.

Разберем по шагам реализацию этого механизма:

  1. В дереве метаданных (или в расширении конфигурации) создадим подписку на событие.
  2. В качестве источников укажем СправочникОбъект.ВнутренниеДокументы, СправочникОбъект.ВходящиеДокументы, СправочникОбъект.ИсходящиеДокументы.
  3. В качестве события выберем ПередЗаписью.
  4. В общем серверном модуле пропишем алгоритм проверки с использованием ТекущаяДатаСеанса(), чтобы избежать расхождений часовых поясов сервера и клиента.

Рассмотрим код обработчика подписки:


Процедура ПроверитьСрокРедактированияДокументаПередЗаписью(Источник, Отказ) Экспорт
    
    // Если объект новый, дата создания только устанавливается, запрет не нужен
    Если Источник.ЭтоНовый() Тогда
        Возврат;
    КонецЕсли;
    
    // Пропускаем проверку для пользователей с полными правами или администраторов
    Если РольДоступна("ПолныеПрава") Или РольДоступна("Администратор") Тогда
        Возврат;
    КонецЕсли;
    
    КоличествоДнейБлокировки = 5;
    СрокВСекундах = КоличествоДнейБлокировки * 86400;
    
    // Проверяем срок с момента создания документа
    Если (ТекущаяДатаСеанса() - Источник.ДатаСоздания) > СрокВСекундах Тогда
        Отказ = Истина;
        ВызватьИсключение "Истек допустимый срок редактирования документа (" 
            + Строка(КоличествоДнейБлокировки) + " дн.). Изменение запрещено.";
    КонецЕсли;

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

Способ 3. Регламентное задание и статус закрытия (рекомендуемый для высоконагруженных баз)

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

  1. Добавляем у документа реквизит (или используем дополнительный реквизит) ЗакрытОтИзменений с типом Булево.
  2. Создаем регламентное задание, запускаемое по ночам, которое находит все документы старше заданного срока и устанавливает флаг ЗакрытОтИзменений = Истина.
  3. В формах и подписках проверяем только значение этого флага без необходимости динамического вычисления дат. Также этот флаг можно использовать в стандартных политиках доступа «1С:Документооборот» и матрицах состояний.

Реализация через Расширение конфигурации

Чтобы не снимать типовую конфигурацию с поддержки, все вышеперечисленные проверки рекомендуется выносить в Расширение конфигурации. Для этого обработчик ПередЗаписью в модуле объекта перехватывается с помощью аннотации &Перед:


&Перед("ПередЗаписью")
Процедура Расш_ПередЗаписью(Отказ)
    
    Если ЭтоНовый() Тогда
        Возврат;
    КонецЕсли;
    
    Если Не РольДоступна("ПолныеПрава") И (ТекущаяДатаСеанса() - ДатаСоздания) > (5 * 86400) Тогда
        Отказ = Истина;
        Сообщить("Срок редактирования документа истек. Обратитесь к администратору.");
    КонецЕсли;

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

Такой подход обеспечивает сохранение целостности конфигурации и легкое обновление версии 1С:Документооборот в будущем.

← На главную