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