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

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

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

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

Почему стандартная «Дата запрета изменения» не решает задачу?

Разберем типичную ошибку начинающих администраторов. Часто в качестве решения предлагают использовать стандартный механизм «Дата запрета изменения данных». Выясним причину, почему это не сработает в нашей ситуации:

Для полного сокрытия данных у разработчика есть два основных пути: использование механизма ограничения доступа на уровне записей (RLS) или программная фильтрация данных. Рассмотрим каждый подробнее.

Способ 1. Программное ограничение доступа (Через расширения конфигурации)

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

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

Шаг 1. Фильтрация динамических списков

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


&НаСервереБезКонтекста
Функция ПолучитьДатуОграничения()
    // Например, скрываем все документы старше 365 дней для роли "ОграниченныйДоступ"
    Если РольДоступна("ОграниченныйДоступ") Тогда
        Возврат ДобавитьМесяц(ТекущаяДата(), -12);
    КонецЕсли;
    Возврат Дата(1, 1, 1);
КонецФункции

&НаСервере
Процедура ПередЗаполнениемФормыПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    ГраницаДаты = ПолучитьДатуОграничения();
    Если ЗначениеЗаполнено(ГраницаДаты) Тогда
        // Накладываем жесткий отбор на динамический список документов
        НовыйОтбор = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Дата");
        НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.БольшеИлиРавно;
        НовыйОтбор.ПравоеЗначение = ГраницаДаты;
        НовыйОтбор.Использование = Истина;
        НовыйОтбор.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
    КонецЕсли;
КонецПроцедуры

При таком подходе пользователь просто не увидит документы за старый период в общем списке. Настройка Недоступный гарантирует, что пользователь не сможет вручную отключить этот отбор через стандартные настройки списка.

Шаг 2. Блокировка открытия форм документов

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

Разберем по шагам логику проверки в модуле формы документа:


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

&НаСервереБезКонтекста
Функция ПроверитьОграничениеДоступаНаСервере(СсылкаНаДокумент)
    Если РольДоступна("ОграниченныйДоступ") Тогда
        ДатаДокумента = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаДокумент, "Дата");
        ГраницаДаты = ДобавитьМесяц(ТекущаяДата(), -12);
        Если ДатаДокумента < ГраницаДаты Тогда
            Возврат Истина; // Доступ запрещен
        КонецЕсли;
    КонецЕсли;
    Возврат Ложь; // Доступ разрешен
КонецФункции

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

Способ 2. Использование механизма RLS (Ограничение на уровне записей)

Если требуется гарантированная безопасность данных, при которой пользователи не смогут получить доступ к старой информации даже через внешние отчеты или консоль запросов, необходимо использовать механизм RLS (Row-Level Security).

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

Шаг 1. Инициализация параметра сеанса

Для динамического расчета границы доступа (например, скользящий период в 365 дней) не рекомендуется использовать жесткие запросы в самом шаблоне RLS, так как это снизит производительность. Правильнее использовать параметры сеанса.

Создадим параметр сеанса ГраницаДоступаПоДате с типом Дата. Пропишем его заполнение в модуле сеанса при запуске системы:


Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
    Если РольДоступна("ОграниченныйДоступ") Тогда
        // Рассчитываем границу доступа: текущая дата минус один год
        ПараметрыСеанса.ГраницаДоступаПоДате = ДобавитьМесяц(ТекущаяДата(), -12);
    Иначе
        // Для остальных пользователей ограничений нет
        ПараметрыСеанса.ГраницаДоступаПоДате = Дата(1, 1, 1);
    EndIf;
КонецПроцедуры

Шаг 2. Настройка шаблона RLS для роли

Перейдем в настройки роли ограниченного доступа. Для каждого документа, к которому нужно закрыть доступ, на вкладке «Шаблоны ограничений» добавим новое ограничение на право Чтение. Запрос ограничения будет выглядеть следующим образом:


ГДЕ Дата >= &ПараметрыСеанса.ГраницаДоступаПоДате
   ИЛИ НЕ &ПараметрыСеанса.ГраницаДоступаПоДате = ДАТАВРЕМЯ(1, 1, 1)

Этот шаблон гарантирует, что СУБД будет отдавать пользователю только те строки таблиц, которые соответствуют разрешенному периоду.

Важный подводный камень RLS: Регистры и Отчеты

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

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

Влияние на производительность и выбор решения

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

Подведем итог и выберем оптимальный подход:

  1. Используйте программный метод (Расширения + фильтрация динамических списков), если: вам нужно быстро и без потери производительности скрыть информацию от обычных пользователей в интерфейсе копии базы, и при этом у них нет прямого доступа к консоли отчетов или универсальным выгрузкам данных.
  2. Используйте RLS, если: требуется строгая безопасность данных (например, база передается сторонним аудиторам), исключающая любую возможность извлечения информации за прошлые годы, несмотря на возможные задержки при формировании тяжелых отчетов.
← На главную