К статье
Практический материал

Разработка и Конфигурация · 11 мин

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

Как программно получить выделенные строки динамического списка в 1С: свойство ВыделенныеСтроки, обход коллекции, получение данных строки, типичные ошибки и примеры кода.

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

Главная сложность в том, что динамический список — это не обычная таблица значений. У него нет прямого доступа к данным строк: платформа хранит только ключи записей и служебную информацию. Поэтому получить выделенные строки можно через свойство ВыделенныеСтроки элемента формы, а вот как извлечь из них полезные данные — зависит от типа основной таблицы списка.

Ниже разобраны рабочие способы: от простого перебора ссылок до получения значений произвольных колонок, а также ограничения, о которых часто забывают.

Где находится свойство ВыделенныеСтроки и что оно возвращает

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

Тип элементов массива зависит от основной таблицы динамического списка:

  • список справочника или документа — элементы массива имеют тип ссылки (СправочникСсылка, ДокументСсылка);
  • список регистра сведений — элементы имеют тип РегистрСведенийКлючЗаписи;
  • список регистра накопления или бухгалтерии — РегистрНакопленияКлючЗаписи, РегистрБухгалтерииКлючЗаписи;
  • динамический список без основной таблицы (произвольный запрос) — тип зависит от полей запроса, часто это строки с ключевыми полями.

Если пользователь ничего не выделил, массив пуст. Текущая строка при этом не считается выделенной автоматически — за неё отвечает отдельное свойство ТекущаяСтрока. Это частая причина ошибок: разработчик ждёт, что одиночный клик попадёт в выделенные строки, но это не так.

Простой перебор выделенных строк для ссылочных списков

Самый распространённый сценарий — список документов или справочников. Здесь элементы массива ВыделенныеСтроки уже являются ссылками, поэтому код получается коротким. Пример команды формы списка, которая собирает выделенные документы в массив:

&НаКлиенте

Процедура ОбработатьВыделенные(Команда)

Выделенные = Элементы.Список.ВыделенныеСтроки;

Если Выделенные.Количество() = 0 Тогда

ПоказатьПредупреждение(, "Не выделено ни одной строки.");

Возврат;

КонецЕсли;

ОбработатьНаСервере(Выделенные);

КонецПроцедуры

&НаСервереБезКонтекста

Процедура ОбработатьНаСервере(МассивСсылок)

Для Каждого Ссылка Из МассивСсылок Цикл

// Ссылка уже готова к использованию

ДокОбъект = Ссылка.ПолучитьОбъект();

// ... дальнейшая обработка

КонецЦикла;

КонецПроцедуры

Обратите внимание на проверку пустого массива. Без неё команда молча «отработает» вхолостую, и пользователь не поймёт, произошло что-то или нет. Также полезно учитывать, что массив выделенных строк передаётся на сервер без ограничений — это обычные сериализуемые ссылки.

Порядок действий для списка документов
  1. 1
    Добавьте команду формы и кнопку в командную панель списка
  2. 2
    В клиентском обработчике получите Элементы.Список.ВыделенныеСтроки
  3. 3
    Проверьте, что массив не пуст, и сообщите пользователю об отсутствии выделения
  4. 4
    Передайте массив в серверную процедуру и обработайте ссылки
  5. 5
    После обработки вызовите Элементы.Список.Обновить(), чтобы отразить изменения

Получение значений колонок выделенных строк

Часто нужны не сами ссылки, а значения конкретных полей: номер документа, контрагент, сумма. У динамического списка нет метода «получить данные строки по ключу», как у таблицы значений. Есть несколько обходных путей.

Запросом по массиву ссылок

Наиболее надёжный способ — передать массив ссылок в запрос и выбрать нужные поля. Это гарантированно вернёт актуальные данные из базы, а не то, что отображается в списке (после изменения объекта другим пользователем список может быть не обновлён):

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Реализация.Ссылка КАК Ссылка,

| Реализация.Номер КАК Номер,

| Реализация.Контрагент КАК Контрагент,

| Реализация.СуммаДокумента КАК Сумма

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| Реализация.Ссылка В (&МассивСсылок)";

Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);

Выборка = Запрос.Выполнить().Выбрать();

Через данные текущей строки

Если нужны поля только одной текущей строки, можно использовать Элементы.Список.ТекущиеДанные — там доступны все поля, выведенные в список. Но для множественного выделения этот путь не работает: ТекущиеДанные отражает только строку с курсором.

Выделенные строки в списке регистра сведений

Для регистров элементы массива ВыделенныеСтроки — это ключи записей, а не ссылки. Получить данные записи можно через менеджер регистра:

Для Каждого КлючЗаписи Из Выделенные Цикл

МенеджерЗаписи = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Период = КлючЗаписи.Период;

МенеджерЗаписи.Номенклатура = КлючЗаписи.Номенклатура;

МенеджерЗаписи.Прочитать();

Если МенеджерЗаписи.Выбран() Тогда

// работаем с МенеджерЗаписи.Цена и другими ресурсами

КонецЕсли;

КонецЦикла;

Состав полей ключа зависит от структуры регистра: для периодического регистра сведений это Период и измерения, для подчинённого регистратору — ещё и Регистратор. Узнать точный состав можно через свойства объекта ключа в отладчике или в синтакс-помощнике по типу РегистрСведенийКлючЗаписи.

Динамический список с произвольным запросом

Если у списка отключён флаг «Основная таблица» и задан произвольный текст запроса, поведение ВыделенныеСтроки меняется. Ключом строки становится набор значений полей, указанных в запросе, и платформа не всегда может однозначно идентифицировать запись.

Практические рекомендации:

  • включайте в выборку поле-ссылку (например, Ссылка основной таблицы запроса) — тогда в ВыделенныеСтроки попадут именно ссылки;
  • если ссылки в запросе нет, ключ строки может быть неопределённого типа, и надёжной интерпретации не будет — пересмотрите запрос;
  • для запросов с группировками и соединениями нескольких таблиц выделение может возвращать ключи, которые невозможно однозначно связать с объектом — в таких случаях лучше выводить в список поле-идентификатор и работать через него.

Проверить, что именно приходит в массиве, проще всего в отладчике: поставьте точку останова в обработчике команды и посмотрите тип первого элемента ВыделенныеСтроки при выделенной строке.

Маршрут решения

Как выбрать подход

Список документов или справочников, нужны сами объектыИспользуйте ВыделенныеСтроки напрямую — это готовые ссылки
Нужны значения произвольных колонок спискаПередайте массив ссылок в запрос и выберите нужные поля
Список регистра сведенийИспользуйте ключи записей и СоздатьМенеджерЗаписи с Прочитать()
Произвольный запрос без основной таблицыДобавьте в запрос поле-ссылку и работайте через него

Типичные ошибки и ограничения

Первая группа ошибок связана с путаницей между текущей и выделенными строками. Свойства ТекущаяСтрока и ВыделенныеСтроки независимы: строка с курсором может не входить в выделение, и наоборот. Если команда должна работать «хотя бы с одной строкой», логично использовать ТекущаяСтрока как запасной вариант, когда массив выделенных пуст.

Вторая группа — попытки обратиться к данным строки напрямую, как к таблице значений: Список.НайтиПоИдентификатору() для динамического списка не вернёт данные строки в привычном виде. Динамический список хранит данные на сервере и подгружает их порциями, поэтому прямого доступа к коллекции строк у него нет.

Третья группа — игнорирование производительности. Если пользователь выделит несколько тысяч строк, пообъектная обработка с ПолучитьОбъект() и Записать() в цикле может занять заметное время и заблокировать сеанс. Для массовых операций используйте транзакции разумного размера, фоновые задания или пакетные запросы.

Типичные ошибки
01
Ожидание, что текущая строка автоматически входит в ВыделенныеСтроки — команда не срабатывает при одиночном клике
02
Попытка прочитать колонки строки из ключа записи регистра — там только измерения и период, ресурсы нужно читать через менеджер записи
03
Обработка объектов по данным, отображаемым в списке, без перечитывания из базы — риск работы с устаревшими значениями
04
Отсутствие проверки пустого массива — пользователь не понимает, почему команда ничего не сделала
05
Обновление списка до завершения серверной обработки — выделение сбрасывается и строки теряются

Проверка результата и обновление списка

После обработки выделенных строк список нужно обновить, чтобы пользователь увидел изменения: Элементы.Список.Обновить(). Учтите, что обновление сбрасывает выделение, поэтому массив ссылок нужно сохранить до вызова серверной процедуры, а не читать ВыделенныеСтроки после неё.

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

Контрольные точки

Как проверить результат

Состав массива ВыделенныеСтроки
Норма

Типы элементов соответствуют основной таблице (ссылки или ключи записей)

Тревожный признак

Элементы неопределённого типа — у списка произвольный запрос без поля-ссылки

Поведение команды без выделения
Норма

Появляется понятное предупреждение

Тревожный признак

Команда молча завершается или падает с ошибкой

Данные после обработки
Норма

Список обновлён, изменения видны, выделение сброшено осознанно

Тревожный признак

Список не обновлён или обработаны не те строки

Частые вопросы

Можно ли получить выделенные строки на сервере без клиентского вызова?

Нет. Выделение — это состояние интерфейса клиента, на сервере оно недоступно. Стандартный приём: клиентская процедура читает Элементы.Список.ВыделенныеСтроки и передаёт массив в серверную процедуру параметром.

Почему в ВыделенныеСтроки попадает только одна строка, хотя выделено несколько?

Проверьте режим выделения таблицы формы: у элемента формы есть свойство РежимВыделения. Если установлено «Одиночный», множественное выделение невозможно. Для множественного выбора нужно значение «Множественный».

Как выделить строки программно?

Свойство ВыделенныеСтроки доступно не только для чтения: ему можно присвоить массив ключей записей, и соответствующие строки будут выделены визуально. Это удобно для восстановления выделения после обновления списка.

Что делать, если выделено несколько тысяч строк?

Не обрабатывайте их пообъектно в одном клиентском вызове. Передайте массив на сервер и выполните обработку в фоновом задании с индикацией прогресса, либо пакетами с транзакциями. Иначе сеанс пользователя будет заблокирован на всё время операции.

Работает ли ВыделенныеСтроки в обычных формах?

В обычных формах динамических списков нет — там используются табличные поля с другими механизмами (например, свойство ВыделенныеСтроки табличного поля, но данные доступны напрямую из источника). Материал статьи относится к управляемым формам.

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

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

Итог

Что важно запомнить

Выделенные строки динамического списка читаются через Элементы.Список.ВыделенныеСтроки и содержат ключи записей: ссылки для справочников и документов, ключи записей для регистров. Значения колонок получайте запросом по массиву ссылок, всегда проверяйте пустое выделение и не путайте выделенные строки с текущей строкой. После обработки обновляйте список, сохранив массив заранее.