Как программно установить дату запрета редактирования в 1С:Управление торговлей 10.3?

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

В конфигурации «Управление торговлей», редакция 10.3, границы запрета изменения данных хранятся в специальном регистре сведений ГраницыЗапретаИзмененияДанных. Разберем по шагам, как правильно организовывать программную установку и изменение этих дат, какие ошибки часто допускают разработчики и как гарантировать, что новые ограничения применятся без перезапуска сеанса пользователя.

Анализ прямого обхода регистра и его узкие места

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


Выборка = РегистрыСведений.ГраницыЗапретаИзмененияДанных.Выбрать();
Пока Выборка.Следующий() Цикл
    МенеджерЗаписи = Выборка.ПолучитьМенеджерЗаписи();
    МенеджерЗаписи.Прочитать();
    Если Выборка.Пользователь.Наименование = "Менеджеры" Тогда
        МенеджерЗаписи.ГраницаЗапретаИзменений = ТекущаяДата() - 86400;    
    ИначеЕсли Выборка.Пользователь.Наименование = "Бухгалтера" Тогда
        МенеджерЗаписи.ГраницаЗапретаИзменений = ТекущаяДата() - (86400 * 30);
    ИначеЕсли Выборка.Пользователь.Наименование = "Обмен данными" Тогда
        МенеджерЗаписи.ГраницаЗапретаИзменений = ТекущаяДата() - (86400 * 14);
    КонецЕсли;
    МенеджерЗаписи.Записать();
КонецЦикла;

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

  1. Кэширование в параметрах сеанса: При проведении документов система проверяет запрет не из регистра напрямую, а через ПараметрыСеанса.ГраницыЗапретаИзмененияДанных. Запись в регистр не обновляет параметр в запущенных сеансах пользователей автоматически. До перезапуска программы ограничения не вступят в силу.
  2. Сравнение по наименованию: Поиск по строке Выборка.Пользователь.Наименование = "Бухгалтера" крайне ненадёжен. Если администратор переименует группу или допустит опечатку, условие перестанет срабатывать. Правильнее использовать предопределенные элементы, поиск по коду или прямые ссылки.
  3. Избыточная нагрузка: Перебор регистра через Выбрать() и создание ПолучитьМенеджерЗаписи() на каждой итерации создают ненужную нагрузку на СУБД и могут спровоцировать блокировки.
  4. Разрезы регистра: Регистр ГраницыЗапретаИзмененияДанных содержит не только измерение Пользователь, но и измерение Организация. Если границы устанавливаются в разрезе организаций, это нужно обязательно учитывать при записи.

Правильный способ записи через набор записей и обновление сеанса

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

Рассмотрим пример кода для записи даты запрета конкретному пользователю или группе пользователей:


// Устанавливаем границу запрета для конкретного пользователя или группы
НаборЗаписей = РегистрыСведений.ГраницыЗапретаИзмененияДанных.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Пользователь.Установить(СсылкаНаПользователяИлиГруппу);

// Если граница устанавливается в целом (без разреза по организациям)
НаборЗаписей.Отбор.Организация.Установить(Справочники.Организации.ПустаяСсылка());

Запись = НаборЗаписей.Добавить();
Запись.Пользователь = СсылкаНаПользователяИлиГруппу;
Запись.Организация = Справочники.Организации.ПустаяСсылка();
Запись.ГраницаЗапретаИзменений = ТекущаяДата() - 86400; // Например, вчерашний день

НаборЗаписей.Записать();

// Обязательно обновляем параметры сеанса
ПолныеПрава.УстановитьПараметрГраницыЗапретаИзмененияДанных();

Вызов процедуры ПолныеПрава.УстановитьПараметрГраницыЗапретаИзмененияДанных() пересчитывает актуальные границы и записывает их в ПараметрыСеанса.ГраницыЗапретаИзмененияДанных, благодаря чему изменения применяются мгновенно.

Альтернативные варианты решения

В зависимости от архитектурных требований задачи можно выбрать один из следующих подходов:

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