При работе с документами товародвижения, такими как Перемещение товаров, часто возникает необходимость ограничить видимость данных для конкретного сотрудника. Типичная задача: пользователь склада №40 должен видеть только те документы, в которых его склад является либо отправителем, либо получателем. По умолчанию стандартные отборы в 1С работают по принципу «И», что скрывает нужные записи. Разберем подробно, как реализовать условие «ИЛИ» несколькими способами: от простой пользовательской настройки до программного кода и систем безопасности.
Рассмотрим самый простой вариант, который не требует изменения конфигурации. Платформа 1С:Предприятие 8 позволяет группировать условия отбора непосредственно в режиме «1С:Предприятие». Проанализируем последовательность действий:
Перемещение.Склад-отправитель и Склад-получатель.Теперь система будет выводить документ, если хотя бы одно из этих полей соответствует выбранному складу. Однако у этого метода есть минус: пользователь может случайно изменить или удалить эту настройку. Выясним, как закрепить такой фильтр программно.
Чтобы фильтрация работала автоматически при открытии формы и пользователь не мог её отключить, мы воспользуемся встроенным языком 1С. Разберем пример кода, который необходимо разместить в модуле формы списка в процедуре ПриСозданииНаСервере. Мы будем работать с объектом КомпоновщикНастроек и его коллекцией ФиксированныеНастройки.
Проанализируем пример реализации:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем склад текущего пользователя (например, из параметров сеанса или реквизитов)
ТекущийСклад = Справочники.Склады.НайтиПоКоду("40");
// Очищаем существующие фиксированные отборы, если это необходимо
Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Очистить();
// Создаем группу "ИЛИ"
ГруппаИЛИ = Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ГруппаОтбораКомпоновкиДанных"));
ГруппаИЛИ.ТипГруппы = ТипГруппыОтбораКомпоновкиДанных.ГруппаИли;
ГруппаИЛИ.Использование = Истина;
// Добавляем условие по Складу-отправителю
ЭлементОтправитель = ГруппаИЛИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтправитель.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("СкладОтправитель");
ЭлементОтправитель.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтправитель.ПравоеЗначение = ТекущийСклад;
ЭлементОтправитель.Использование = Истина;
// Добавляем условие по Складу-получателю
ЭлементПолучатель = ГруппаИЛИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементПолучатель.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("СкладПолучатель");
ЭлементПолучатель.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементПолучатель.ПравоеЗначение = ТекущийСклад;
ЭлементПолучатель.Использование = Истина;
КонецПроцедуры
Использование ФиксированныеНастройки гарантирует, что данный отбор будет накладываться поверх любых пользовательских фильтров и не будет виден в стандартном окне настроек, что исключает ошибки персонала.
Если документов в базе очень много (сотни тысяч), стандартные механизмы отбора компоновки могут работать медленно. В этом случае мы рекомендуем перевести динамический список в режим Произвольный запрос. Это позволит платформе более эффективно построить план SQL-запроса.
Посмотрим, как изменить текст запроса в свойствах динамического списка Список:
ВЫБРАТЬ
ДокументПеремещение.Ссылка,
ДокументПеремещение.Дата,
ДокументПеремещение.Номер,
ДокументПеремещение.СкладОтправитель,
ДокументПеремещение.СкладПолучатель
ИЗ
Документ.Перемещение КАК ДокументПеремещение
ГДЕ
(ДокументПеремещение.СкладОтправитель = &ПараметрСклад
ИЛИ ДокументПеремещение.СкладПолучатель = &ПараметрСклад)
После изменения текста запроса необходимо установить значение параметра при открытии формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Список.Параметры.УстановитьЗначениеПараметра("ПараметрСклад", ОбъектСклад);
КонецПроцедуры
Если задача заключается не только в удобстве интерфейса, но и в безопасности данных, проанализируем механизм RLS (Record Level Security). Это наиболее жесткий и надежный метод. Настройка выполняется в Конфигураторе для конкретной роли пользователя.
В шаблоне ограничений для документа Перемещение на чтение прописывается условие:
ГДЕ СкладОтправитель = #Параметр(1) ИЛИ СкладПолучатель = #Параметр(1)
Преимущество: Фильтрация будет работать везде: в списках, во всех отчетах и даже если другой программист попытается прочитать данные запросом в своей обработке. Пользователь никогда не увидит чужие документы, даже если очень захочет.
При использовании условия ИЛИ по двум разным полям, СУБД (например, MS SQL или PostgreSQL) может выполнять полное сканирование таблицы (Full Scan), что приведет к «тормозам» интерфейса. Чтобы этого избежать, проанализируем технические требования:
СкладОтправитель и СкладПолучатель в конфигураторе установлено свойство Индексировать.КритерийОтбора (например, «ПоСкладу»), включив в него оба реквизита. Это создаст в базе данных специальную индексную таблицу, позволяющую мгновенно получать документы по ссылке на склад.Выясним, какой метод выбрать? Если нужно быстро «сделать, чтобы работало» — используйте Группу ИЛИ в фиксированных настройках. Если требуется безопасность — настраивайте RLS. Если важна максимальная скорость на огромных объемах — оптимизируйте запрос и проверяйте индексы.