В процессе администрирования и разработки в системе «1С:Предприятие» нередко возникает задача: ограничить определенной группе пользователей доступ к историческим данным. Например, при создании копии базы для аудиторов или стажеров необходимо сделать так, чтобы они видели документы только за последний год, а всё, что было создано ранее (с 2012 года), оставалось скрытым. При этом физическое удаление данных — слишком трудоемкий процесс, который может нарушить целостность базы и актуальность остатков.
В этой статье мы подробно разберем, почему стандартные механизмы не всегда подходят для этой задачи, проанализируем различные варианты реализации и пошагово рассмотрим наиболее эффективные способы решения проблемы.
Разберем типичную ошибку начинающих администраторов. Часто в качестве решения предлагают использовать стандартный механизм «Дата запрета изменения данных». Выясним причину, почему это не сработает в нашей ситуации:
Для полного сокрытия данных у разработчика есть два основных пути: использование механизма ограничения доступа на уровне записей (RLS) или программная фильтрация данных. Рассмотрим каждый подробнее.
Если конфигурация сильно переписана или вы не хотите вмешиваться в стандартные роли, лучшим решением будет использование программного кода. Чтобы сохранить возможность легкого обновления системы, мы рекомендуем реализовывать данный функционал через расширения конфигурации.
Программное ограничение строится на двух рубежах обороны: фильтрации списков документов и блокировке открытия самих форм.
Рассмотрим подробнее, как скрыть документы прошлых лет в интерфейсе. Нам необходимо перехватить событие создания формы списка на сервере и принудительно наложить отбор на динамический список. Посмотрим на пример кода, который можно поместить в расширение для формы списка нужных документов:
&НаСервереБезКонтекста
Функция ПолучитьДатуОграничения()
// Например, скрываем все документы старше 365 дней для роли "ОграниченныйДоступ"
Если РольДоступна("ОграниченныйДоступ") Тогда
Возврат ДобавитьМесяц(ТекущаяДата(), -12);
КонецЕсли;
Возврат Дата(1, 1, 1);
КонецФункции
&НаСервере
Процедура ПередЗаполнениемФормыПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ГраницаДаты = ПолучитьДатуОграничения();
Если ЗначениеЗаполнено(ГраницаДаты) Тогда
// Накладываем жесткий отбор на динамический список документов
НовыйОтбор = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Дата");
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.БольшеИлиРавно;
НовыйОтбор.ПравоеЗначение = ГраницаДаты;
НовыйОтбор.Использование = Истина;
НовыйОтбор.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
КонецЕсли;
КонецПроцедуры
При таком подходе пользователь просто не увидит документы за старый период в общем списке. Настройка Недоступный гарантирует, что пользователь не сможет вручную отключить этот отбор через стандартные настройки списка.
Скрытия списков недостаточно, ведь пользователь может попытаться открыть документ по прямой ссылке из другой формы или через отчет. Проанализируем ситуацию: чтобы предотвратить несанкционированное чтение, необходимо перехватить событие открытия формы самого документа.
Разберем по шагам логику проверки в модуле формы документа:
&НаКлиенте
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
// Вызываем серверную функцию для проверки прав и даты документа
Если ПроверитьОграничениеДоступаНаСервере(Объект.Ссылка) Тогда
Отказ = Истина;
ПоказатьПредупреждение(, "Доступ к документам прошлых периодов для вашей учетной записи ограничен!");
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПроверитьОграничениеДоступаНаСервере(СсылкаНаДокумент)
Если РольДоступна("ОграниченныйДоступ") Тогда
ДатаДокумента = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаДокумент, "Дата");
ГраницаДаты = ДобавитьМесяц(ТекущаяДата(), -12);
Если ДатаДокумента < ГраницаДаты Тогда
Возврат Истина; // Доступ запрещен
КонецЕсли;
КонецЕсли;
Возврат Ложь; // Доступ разрешен
КонецФункции
Преимущества программного метода: простота реализации, отсутствие влияния на общую производительность запросов к базе данных, легкость отладки.
Если требуется гарантированная безопасность данных, при которой пользователи не смогут получить доступ к старой информации даже через внешние отчеты или консоль запросов, необходимо использовать механизм RLS (Row-Level Security).
При использовании RLS платформа автоматически модифицирует любой запрос к СУБД, добавляя к нему условие фильтрации. Рассмотрим подробнее, как правильно настроить это ограничение, избежав типичных ошибок («криво наложилось»).
Для динамического расчета границы доступа (например, скользящий период в 365 дней) не рекомендуется использовать жесткие запросы в самом шаблоне RLS, так как это снизит производительность. Правильнее использовать параметры сеанса.
Создадим параметр сеанса ГраницаДоступаПоДате с типом Дата. Пропишем его заполнение в модуле сеанса при запуске системы:
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
Если РольДоступна("ОграниченныйДоступ") Тогда
// Рассчитываем границу доступа: текущая дата минус один год
ПараметрыСеанса.ГраницаДоступаПоДате = ДобавитьМесяц(ТекущаяДата(), -12);
Иначе
// Для остальных пользователей ограничений нет
ПараметрыСеанса.ГраницаДоступаПоДате = Дата(1, 1, 1);
EndIf;
КонецПроцедуры
Перейдем в настройки роли ограниченного доступа. Для каждого документа, к которому нужно закрыть доступ, на вкладке «Шаблоны ограничений» добавим новое ограничение на право Чтение. Запрос ограничения будет выглядеть следующим образом:
ГДЕ Дата >= &ПараметрыСеанса.ГраницаДоступаПоДате
ИЛИ НЕ &ПараметрыСеанса.ГраницаДоступаПоДате = ДАТАВРЕМЯ(1, 1, 1)
Этот шаблон гарантирует, что СУБД будет отдавать пользователю только те строки таблиц, которые соответствуют разрешенному периоду.
Проанализируем критически важный нюанс работы RLS, о котором часто забывают начинающие разработчики. Если вы настроите ограничение доступа по дате только для документов, вы решите задачу лишь частично.
<Объект не найден>, но суммы и проводки будут доступны для анализа.Период на сами регистры остатков, система не сможет корректно рассчитать остатки на начало разрешенного периода. Для вычисления текущих остатков платформе необходимо просуммировать все движения с момента начала ведения учета. Запретив чтение старых записей регистров, вы получите неверные (нулевые или искаженные) остатки в отчетах.Решение: Для регистров накопления и бухгалтерии накладывайте ограничение RLS только на чтение детальных записей (оборотов), но оставляйте доступ к получению итоговых остатков. Это реализуется разделением прав на «Чтение» и «Просмотр» в настройках ролей на уровне регистров в конфигураторе.
Выясним причину, почему авторы обсуждения на форуме часто склоняются к программному методу вместо RLS. Использование ограничений на уровне записей (особенно в старых версиях платформы и на переписанных конфигурациях типа УПП) накладывает существенную нагрузку на СУБД. Каждый запрос неявно дополняется сложными соединениями и условиями ГДЕ, что снижает общую скорость работы базы данных.
Подведем итог и выберем оптимальный подход: