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