Как автоматически устанавливать дату запрета изменения данных в 1С?

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

Часто перед разработчиками и администраторами систем 1С встает задача автоматической актуализации даты запрета изменения данных. Например, необходимо, чтобы дата запрета ежедневно смещалась на вчерашний день, предотвращая редактирование документов задним числом. Рассмотрим, почему попытка реализовать такую логику через подписки на события является технической ошибкой и как правильно решить эту задачу в конфигурациях 1C (в частности, в Управление торговлей 10.3).

Почему подписки на события не подходят для этой задачи

Проанализируем архитектурное устройство платформы 1С. Подписка на событие предназначенa для перехвата событий конкретных прикладных объектов метаданных — таких как справочники, документы, бизнес-процессы или наборы записей регистров.

Среди доступных событий для подписок присутствуют:

  1. ПередЗаписью и ПриЗаписи
  2. ОбработкаПроведения и ОбработкаУдаленияПроведения
  3. ПриУстановкеНовогоНомера и ПриКопировании
  4. ОбработкаЗаполнения и ОбработкаПроверкиЗаполнения
  5. ПередУдалением

Все эти события относятся исключительно к объектной модели данных. События старта системы, такие как ПриНачалеРаботыСистемы или события модуля сеанса, являются событиями контекста сеанса пользователя. Для них платформенно не предусмотрен механизм подписок на события. Кроме того, попытка менять даты запрета при проведении документов внутри подписок на проведение не только нецелесообразна, но и приведет к блокировкам таблиц и существенному замедлению работы системы.

Вариант 1. Настройка регламентного задания (Рекомендуемый способ)

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

Разберем по шагам алгоритм создания такого решения:

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

Пример кода для программной установки границы запрета изменения данных в конфигурации Управление торговлей 10.3:


Процедура УстановитьДатуЗапретаИзменения() Экспорт
    
    ВчерашняяДата = НачалоДня(ТекущаяДата() - 86400);
    
    // В УТ 10.3 границы запрета хранятся в регистре сведений "ГраницыЗапретаИзмененияДанных"
    МенеджерЗаписи = РегистрыСведений.ГраницыЗапретаИзмененияДанных.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.ГраницаЗапретаИзменений = ВчерашняяДата;
    
    Попытка
        МенеджерЗаписи.Записать();
    Исключение
        ЗаписьЖурналаРегистрации("Установка даты запрета",
            УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

Вариант 2. Проверка и установка даты при старте системы

Если требуется менять дату непосредственно при запуске программы первым вошедшим пользователем, используем глобальный модуль приложения или модуль управляемого приложения в процедуре ПриНачалеРаботыСистемы().

Рассмотрим порядок реализации этого подхода:

  1. При запуске сеанса считываем текущую записанную дату запрета из регистра сведений.
  2. Сравниваем ее с требуемым значением (вчерашней датой).
  3. Если дата устарела, перезаписываем значение в регистре.

Рассмотрим пример реализации проверки в модуле приложения:


Процедура ПриНачалеРаботыСистемы()
    
    #Если Клиент Тогда
        ОбновитьДатуЗапретаПриНеобходимости();
    #КонецЕсли

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

Процедура ОбновитьДатуЗапретаПриНеобходимости()
    
    ТребуемаяДата = НачалоДня(ТекущаяДата() - 86400);
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ТОП 1
        |   ТекРегистр.ГраницаЗапретаИзменений КАК ГраницаЗапрета
        |ИЗ
        |   РегистрСведений.ГраницыЗапретаИзмененияДанных КАК ТекРегистр";
        
    РезультатЗапроса = Запрос.Выполнить();
    
    Если РезультатЗапроса.Пустой() Тогда
        ВыполнитьОбновление = Истина;
    Иначе
        Выборка = РезультатЗапроса.Выбрать();
        Выборка.Следующий();
        ВыполнитьОбновление = (Выборка.ГраницаЗапрета < ТребуемаяДата);
    КонецЕсли;
    
    Если ВыполнитьОбновление Тогда
        // Вызов серверной процедуры записи новой даты
        УстановитьНовуюДатуЗапрета(ТребуемаяДата);
    КонецЕсли;
    
КонецПроцедуры

Важные технические нюансы

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

  1. Режим работы базы (Файловый / Клиент-серверный): В серверном режиме регламентное задание выполняется фоновым процессом 1C:Enterprise Server строго по расписанию. В файловом режиме регламентные задания запускаются только при наличии активного сеанса программы или специально выделенного технологического сеанса.
  2. Пользователи, работающие ночью: Если пользователь не закрывает программу на ночь, проверка в ПриНачалеРаботыСистемы() для него не сработает в полночь, так как повторного входа не происходит. В таких случаях регламентное задание является более надежным выбором.
  3. Ограничение прав (RLS) в УТ 10.3: Обратите внимание, что для пользователей с полными правами дата запрета изменений в Управление торговлей 10.3 по умолчанию может не применяться, если в настройках параметров учета не включено ограничение прав доступа на уровне записей (RLS).
← На главную