Как в 1С программно получить выделенные элементы в списке и передать их в другой динамический список?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В разработке на платформе 1С:Предприятие 8.3 часто возникает задача создания связанных интерфейсов. Типичный пример: пользователь выбирает одну или несколько строк в основном списке (например, справочнике контрагентов), и программа должна мгновенно отобразить связанные данные в другом списке (например, договоры или контактные лица этого контрагента). Разберем по шагам, как это реализовать эффективно и профессионально.

Различие между текущей строкой и выделенными строками

Прежде чем приступать к коду, проанализируем разницу в объектах платформы, которые отвечают за выбор пользователя. Часто начинающие разработчики путают эти понятия, что приводит к логическим ошибкам в работе интерфейса.

  1. ТекущаяСтрока (Items.ИмяСписка.CurrentRow): Это свойство указывает на идентификатор строки, на которой в данный момент находится фокус (курсор). Важно понимать, что даже если пользователь выделил мышкой десять строк, ТекущаяСтрока будет только одна — та, на которой стоит «рамка» фокуса.
  2. ВыделенныеСтроки (Items.ИмяСписка.SelectedRows): Это коллекция (массив), содержащая идентификаторы всех строк, которые в данный момент подсвечены синим цветом. Если в свойствах таблицы разрешено множественное выделение, этот массив может содержать много элементов. Если выделена только одна строка, массив будет состоять из одного элемента.

Для решения нашей задачи (передача параметра в динамический список) выбор свойства зависит от логики: если мы хотим показывать данные только для «активного» элемента, используем ТекущиеДанные. Если хотим обрабатывать группу выделенных объектов — работаем с ВыделенныеСтроки.

Использование события ПриАктивизацииСтроки

Основным механизмом отслеживания действий пользователя в списке является событие ПриАктивизацииСтроки. Рассмотрим подробнее, как правильно его настроить. Это событие вызывается платформой каждый раз, когда пользователь перемещает курсор по списку с помощью клавиатуры или мыши.

Однако здесь кроется важный нюанс: это событие «очень частое». Оно срабатывает не только при клике, но и при обновлении списка, при открытии формы и даже при некоторых изменениях данных. Поэтому код внутри него должен быть максимально «легким».

Посмотрим на пример базовой реализации:


&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
    
    // Получаем текущие данные строки
    ТекущаяСтрокаДанных = Элемент.ТекущиеДанные;
    
    // Обязательная проверка на Неопределено (если список пуст)
    Если ТекущаяСтрокаДанных = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Передаем ссылку в параметр другого динамического списка
    // Предположим, второй список называется "СписокДоговоры"
    Попытка
        СписокДоговоры.Параметры.УстановитьЗначениеПараметра("Владелец", ТекущаяСтрокаДанных.Ссылка);
    Исключение
        // Обработка исключения, если параметра нет в запросе
    КонецПопытки;
    
КонецПроцедуры

Оптимизация работы интерфейса через обработчик ожидания

Проанализируем ситуацию: если пользователь быстро листает список стрелками на клавиатуре, событие ПриАктивизацииСтроки будет вызываться десятки раз в секунду. Если в каждом вызове мы будем заставлять систему пересчитывать сложный динамический список, интерфейс начнет «тормозить».

Выясним причину: серверные вызовы при установке параметров списка требуют времени. Чтобы оптимизировать этот процесс, применим методику «ПодключитьОбработчикОжидания». Суть в том, что мы не будем обновлять данные мгновенно, а подождем 0.2–0.3 секунды, пока пользователь не остановится на нужной строке.

Реализуем этот механизм по шагам:


&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
    // Каждый раз при смене строки мы сбрасываем старый таймер и взводим новый
    ОтключитьОбработчикОжидания("ОбновитьЗависимыйСписок");
    ПодключитьОбработчикОжидания("ОбновитьЗависимыйСписок", 0.3, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьЗависимыйСписок()
    
    // Здесь мы уже спокойно получаем данные
    Данные = Элементы.Список.ТекущиеДанные;
    
    Если Данные <> Неопределено Тогда
        // Установка параметра динамического списка
        СписокДоговоры.Параметры.УстановитьЗначениеПараметра("Владелец", Данные.Ссылка);
    КонецЕсли;
    
КонецПроцедуры

Работа с множественным выделением

Если задача стоит в том, чтобы передать во второй список сразу несколько выбранных элементов, нам понадобится свойство ВыделенныеСтроки. Важно помнить, что в запросе динамического списка-приемника в этом случае должно использоваться условие с оператором В.

Рассмотрим пример запроса в динамическом списке СписокДоговоры:


ВЫБРАТЬ
    Договоры.Ссылка,
    Договоры.Наименование
ИЗ
    Справочник.ДоговорыКонтрагентов КАК Договоры
ГДЕ
    Договоры.Владелец В (&МассивВладельцев)

Теперь напишем код на клиенте, который будет собирать массив ссылок из выделенных строк:


&НаКлиенте
Процедура ОбработатьВыделение()
    
    МассивСсылок = Новый Массив;
    
    // Обходим коллекцию идентификаторов выделенных строк
    Для Каждого ИдентификаторСтроки Из Элементы.Список.ВыделенныеСтроки Цикл
        
        // Получаем данные конкретной строки по идентификатору
        ДанныеСтроки = Элементы.Список.ДанныеСтроки(ИдентификаторСтроки);
        
        Если ДанныеСтроки <> Неопределено Тогда
            МассивСсылок.Добавить(ДанныеСтроки.Ссылка);
        КонецЕсли;
        
    КонецЦикла;
    
    // Передаем массив в параметр списка
    Если МассивСсылок.Количество() > 0 Тогда
        СписокДоговоры.Параметры.УстановитьЗначениеПараметра("МассивВладельцев", МассивСсылок);
    Иначе
        // Если ничего не выделено, можно передать пустой массив или специальное значение
        СписокДоговоры.Параметры.УстановитьЗначениеПараметра("МассивВладельцев", Новый Массив);
    КонецЕсли;
    
КонецПроцедуры

Важные замечания по безопасности и производительности

Разберем несколько критических моментов, которые помогут избежать ошибок:

Таким образом, мы рассмотрели полный цикл решения задачи: от понимания механизмов выделения до оптимизации производительности интерфейса. Использование этих подходов позволит создавать отзывчивые и надежные формы в ваших конфигурациях.

← На главную