При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с задачей ограничения видимости данных для определенных категорий пользователей. В конфигурации 1С:Бухгалтерия 3.0 типичным примером является необходимость скрыть документы (реализации, счета, поступления) по конкретному контрагенту от менеджеров или рядовых бухгалтеров. Однако простая попытка установить отбор программно часто приводит к ошибке: «Параметры Отбора, Сортировки, Группировки или список отображаемых полей заданы неверно. Причина: Невозможно применить фиксированные настройки. Пересекаются элементы отбора». В этой статье мы детально разберем причины этой ситуации и рассмотрим несколько способов решения — от программного исправления кода до использования штатных механизмов БСП.
Прежде чем приступать к исправлению кода, давайте разберем механизм работы динамического списка. Ошибка «Пересекаются элементы отбора» возникает в тех случаях, когда платформа 1С пытается одновременно применить два разных условия к одному и тому же полю в секции ФиксированныеНастройки.
Ситуация развивается следующим образом: пользователь ранее открывал форму списка и вручную устанавливал фильтр по контрагенту. 1С сохраняет эти настройки в системном хранилище. При следующем открытии формы система восстанавливает эти «пользовательские» настройки. Если в этот же момент в процедуре ПриСозданииНаСервере ваш программный код пытается установить свой «фиксированный» отбор на то же поле Контрагент, возникает конфликт. Платформа не может решить, какой из отборов приоритетнее, если они заданы в разных структурах, но затрагивают одно поле.
Если мы хотим жестко ограничить список документов программным способом через расширение, нам необходимо сначала очистить все существующие отборы по этому полю, которые могли быть сохранены ранее или установлены системой автоматически. Рассмотрим правильный алгоритм реализации в процедуре ПриСозданииНаСервереПосле.
Для корректной работы мы должны обратиться к свойству Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор. Проанализируем пример кода, который решает проблему:
&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// 1. Находим нужного контрагента (лучше использовать предопределенные или настройки)
КонтрагентСсылка = Справочники.Контрагенты.НайтиПоКоду("00-000006");
Если КонтрагентСсылка.Пустая() Тогда
Возврат;
КонецЕсли;
// 2. Очищаем старые фиксированные отборы по полю "Контрагент", чтобы избежать пересечения
ПолеОтбора = Новый ПолеКомпоновкиДанных("Контрагент");
Индекс = 0;
Пока Индекс < Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Количество() Цикл
Элемент = Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы[Индекс];
Если Элемент.ЛевоеЗначение = ПолеОтбора Тогда
Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Удалить(Элемент);
Иначе
Индекс = Индекс + 1;
КонецЕсли;
КонецЦикла;
// 3. Устанавливаем новый фиксированный отбор
НовыйЭлемент = Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйЭлемент.ЛевоеЗначение = ПолеОтбора;
НовыйЭлемент.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
НовыйЭлемент.ПравоеЗначение = КонтрагентСсылка;
НовыйЭлемент.Использование = Истина;
НовыйЭлемент.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
КонецПроцедуры
В данном примере мы используем РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный. Это критически важный момент: пользователь не увидит этот отбор в стандартном окне настроек списка и не сможет его отключить или изменить, что и требуется для ограничения прав.
Иногда использование ФиксированныеНастройки бывает избыточным или неудобным (например, если мы хотим оставить пользователю возможность видеть, что фильтр применен). В этом случае можно работать с коллекцией ПользовательскиеНастройки. Разберем ситуацию: если мы программно заполняем пользовательскую настройку, платформа сама заботится о визуализации.
Однако помните, что пользовательские настройки имеют самый низкий приоритет при конфликтах. Если задача — именно безопасность (чтобы менеджер не мог увидеть документы директора), используйте только первый вариант или штатный механизм RLS.
Использование программных отборов в формах списков — это «косметическая» мера. Если пользователь создаст отчет «Оборотно-сальдовая ведомость» или «Карточка субконто», он все равно увидит все документы по скрытому контрагенту. Чтобы ограничить доступ на уровне всей базы данных, правильно использовать ограничение доступа на уровне записей (RLS).
Рассмотрим, как настроить это в 1С:Бухгалтерия 3.0 по шагам:
Преимущество этого метода: данные будут скрыты везде — в списках, в отчетах, в результатах глобального поиска и даже при подборе в других документах. Система просто «вырезает» эти записи из SQL-запроса на уровне платформы.
Если штатный RLS кажется вам слишком тяжеловесным (он может замедлять работу базы при огромном количестве записей), можно применить программный метод модификации текста запроса динамического списка через расширение. Выясним, как это сделать системно.
В расширении можно перехватить событие ПриСозданииНаСервере или использовать возможности Библиотеки стандартных подсистем (БСП). Многие списки в Бухгалтерии 3.0 инициализируются через общие модули. Мы можем программно изменить текст запроса динамического списка, добавив туда условие ГДЕ Контрагент <> &СкрытыйКонтрагент.
Проанализируем пример модификации текста запроса:
&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
ТекстЗапроса = Список.ТекстЗапроса;
// Добавляем условие непосредственно в текст SQL-подобного запроса 1С
Если СтрНайти(ТекстЗапроса, "ГДЕ") > 0 Тогда
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ГДЕ", "ГДЕ Контрагент <> &СкрытыйКонтрагент И ");
Иначе
ТекстЗапроса = ТекстЗапроса + " ГДЕ Контрагент <> &СкрытыйКонтрагент";
КонецЕсли;
Список.ТекстЗапроса = ТекстЗапроса;
Список.Параметры.УстановитьЗначениеПараметра("СкрытыйКонтрагент", Справочники.Контрагенты.НайтиПоКоду("00-000006"));
КонецПроцедуры
Этот метод более надежен, чем простая установка отбора, так как он меняет саму структуру выборки данных для данной формы. Однако он требует аккуратности при работе с динамическими списками, использующими произвольный запрос.
Мы проанализировали ситуацию с ограничением доступа к документам и выяснили, что ошибка пересечения отборов — это лишь следствие конфликта программных и сохраненных настроек платформы.
Подведем итог:
ФиксированныеНастройки.Отбор перед добавлением своего элемента.Помните, что безопасность данных — это комплексная задача, и ограничение только в экранной форме часто бывает недостаточным, если пользователь обладает минимальными знаниями по формированию стандартных отчетов 1С.