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