При автоматизации рутинных операций в конфигурации «1С:Управление торговлей», редакция 10.3 (обычное приложение) часто возникает задача ежедневно смещать дату запрета изменения данных — например, на вчерашний день. Однако при прямой записи нового значения в регистр сведений РегистрСведений.ГраницыЗапретаИзмененияДанных пользователи замечают, что документы прошлых периодов всё равно остаются доступными для редактирования, либо при входе менеджеров/кассиров система выдаёт ошибку «Нарушение прав доступа!».
Рассмотрим подробно, почему запись в регистр сведений не даёт моментального эффекта, как устроена система проверки дат запрета в 1С и какими способами корректно решить эту задачу.
Проанализируем архитектуру механизма запрета изменения данных в 1С:УТ 10.3. Проблема кроется в трех ключевых факторах:
ПараметрыСеанса.ГраницыЗапретаИзмененияДанных. Прямое изменение набора записей регистра не обновляет данные в уже открытых сеансах и даже в текущем сеансе до специального вызова процедуры переинициализации.ГраницыЗапретаИзмененияДанных. При попытке выполнить код перезаписи регистра в процедуре ПриНачалеРаботыСистемы под неполными правами система генерирует ошибку Нарушение прав доступа! на методе НаборЗаписей.Записать().Чтобы программно изменить дату запрета и применить её для всех пользователей без ошибок доступа, разберем по шагам правильный алгоритм.
УстановитьПривилегированныйРежим(Истина) или в привилегированном общем модуле. Это позволит изменить регистр из-под любого пользователя при входе.НачалоДня(). Фрагмент вида ТекущаяДата() - 86400 отнимает ровно 24 часа с сохранением текущего времени, что может вызывать ошибки при проверке документов за текущие сутки.ПолныеПрава.УстановитьПараметрГраницыЗапретаИзмененияДанных().Посмотрим на пример правильного кода для модуля обычного приложения или общего модуля:
УстановитьПривилегированныйРежим(Истина);
// Вычисляем границу запрета — начало вчерашнего дня
ГраницаЗапретаИзменений = НачалоДня(ТекущаяДата() - 86400);
// Создаем и заполняем набор записей
НаборЗаписей = РегистрыСведений.ГраницыЗапретаИзмененияДанных.СоздатьНаборЗаписей();
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество() > 0 Тогда
ИзмененияЕсть = Ложь;
Для Каждого Запись Из НаборЗаписей Цикл
Если Запись.ГраницаЗапретаИзменений <> ГраницаЗапретаИзменений Тогда
Запись.ГраницаЗапретаИзменений = ГраницаЗапретаИзменений;
ИзмененияЕсть = Истина;
КонецЕсли;
КонецЦикла;
Если ИзмененияЕсть Тогда
НаборЗаписей.Записать();
// Обязательно обновляем параметры сеанса!
ПолныеПрава.УстановитьПараметрГраницыЗапретаИзмененияДанных();
КонецЕсли;
КонецЕсли;
УстановитьПривилегированныйРежим(Ложь);
Выполнение кода записи даты запрета при каждом входе пользователя в процедуре ПриНачалеРаботыСистемы не всегда является оптимальным решением, так как это создает избыточную нагрузку на базу данных при массовом входе сотрудников.
Рекомендуется вынести эту логику в регламентное задание, которое будет выполняться на сервере или в фоновом сеансе ежедневно в 00:00. Регламентное задание выполняется под техническими правами, корректно обновит записи в регистре РегистрСведений.ГраницыЗапретаИзмененияДанных, а пользователи при входе в новый рабочий день автоматически получат актуализированные ПараметрыСеанса.