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