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

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

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

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

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

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

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

Как устроено свойство ВыделенныеСтроки

У табличного поля формы есть свойство ВыделенныеСтроки — коллекция, доступная для чтения и изменения. Именно она определяет, какие строки пользователь видит как выделенные. Чтобы выделить строку программно, в неё добавляют идентификатор нужной строки; чтобы снять выделение — удаляют идентификатор или очищают коллекцию целиком.

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

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

Выделение строк в табличной части и таблице значений

Самый распространённый сценарий — выделить строки в табличной части документа или в произвольной таблице значений на управляемой форме. Здесь идентификатор строки получают методом ПолучитьИдентификатор() у строки коллекции данных формы.

Пример: выделить все строки табличной части «Товары», где количество больше 10:

Элементы.Товары.ВыделенныеСтроки.Очистить();

Для Каждого СтрокаТовара Из Объект.Товары Цикл

Если СтрокаТовара.Количество > 10 Тогда

Элементы.Товары.ВыделенныеСтроки.Добавить(

СтрокаТовара.ПолучитьИдентификатор());

КонецЕсли;

КонецЦикла;

Обратите внимание на первую строку: очистка коллекции перед добавлением обязательна, если нужно заменить выделение, а не дополнить его. Без очистки ранее выделенные пользователем строки останутся подсвеченными, и результат будет отличаться от ожидаемого.

Если нужно выделить все строки без условия, цикл упрощается: перебираете коллекцию и добавляете идентификатор каждой строки. Для больших таблиц (тысячи строк) учитывайте, что массовое выделение выполняется на клиенте и может занять заметное время — в таких случаях лучше пересмотреть сценарий, например выделять только первые N найденных строк.

bsl
// Выделить все строки табличной части
Элементы.Товары.ВыделенныеСтроки.Очистить();
Для Каждого СтрокаТовара Из Объект.Товары Цикл
    Элементы.Товары.ВыделенныеСтроки.Добавить(СтрокаТовара.ПолучитьИдентификатор());
КонецЦикла;

Выделение строк в динамическом списке

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

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

Элементы.Список.ВыделенныеСтроки.Очистить();

Элементы.Список.ВыделенныеСтроки.Добавить(НужныйДокументСсылка);

Элементы.Список.ТекущаяСтрока = НужныйДокументСсылка;

Для регистров сведений ключ записи — это значение типа «РегистрСведенийКлючЗаписи», который строится по измерениям (и периоду для периодических регистров). Получить его можно через менеджер регистра методом СоздатьКлючЗаписи() со структурой значений ключевых полей.

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

Выделение в обычных формах

В обычных формах (режим обычного приложения) подход отличается. Табличное поле там связано с данными через свойство Данные или работает напрямую с таблицей значений, а выделение чаще управляется через свойство ВыделенныеСтроки самого элемента формы, но идентификаторами служат сами строки таблицы значений или их индексы.

Типовой пример для табличной части в обычной форме:

ЭлементыФормы.Товары.ВыделенныеСтроки.Очистить();

Для Каждого СтрокаТовара Из Товары Цикл

Если СтрокаТовара.Сумма > 0 Тогда

ЭлементыФормы.Товары.ВыделенныеСтроки.Добавить(СтрокаТовара);

КонецЕсли;

КонецЦикла;

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

Сравнение подходов

Управляемая форма, таблица значений

В ВыделенныеСтроки добавляют результат ПолучитьИдентификатор() строки коллекции данных формы.

Управляемая форма, динамический список

Добавляют ключ записи: ссылку для ссылочных списков или РегистрСведенийКлючЗаписи для регистров.

Обычная форма

Добавляют сами строки таблицы значений или табличной части, без промежуточных идентификаторов.

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

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

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

Эта пара приёмов — «прочитать выделенное» и «установить выделение» — часто используется вместе: например, обработка массово изменяет реквизит во всех выделенных пользователем строках, а после завершения восстанавливает выделение, чтобы пользователь видел, с чем работал.

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

Типичные ошибки и их диагностика

Первая ошибка — передача индекса строки вместо идентификатора в управляемой форме. Индекс (позиция в коллекции) и идентификатор — разные значения; после сортировки или удаления строк они расходятся. Всегда используйте ПолучитьИдентификатор().

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

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

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

Проверка результата и ограничения

Программно убедиться, что выделение сработало, можно через Элементы.Товары.ВыделенныеСтроки.Количество() — значение должно совпадать с числом строк, удовлетворяющих условию. Если количество нулевое при заведомо подходящих данных, проверьте тип передаваемого значения и контекст выполнения.

Визуальная проверка тоже информативна: выделенные строки подсвечиваются цветом, заданным стилем. Если строка выделена программно, но пользователь не видит подсветки, убедитесь, что у табличного поля не отключён режим множественного выделения (РежимВыделения) и не установлен режим выделения «Без выделения».

Ограничение по производительности: массовое добавление тысяч идентификаторов в ВыделенныеСтроки — клиентская операция, и на слабых машинах или в веб-клиенте она может ощутимо «подвешивать» форму. Для больших объёмов предпочтительнее альтернативы: условное оформление строк по признаку или отбор списка вместо выделения.

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

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

Количество() у ВыделенныеСтроки
Норма

Равно числу строк, подходящих под условие

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

Ноль или меньше ожидаемого — проверяйте тип идентификаторов и контекст

Визуальная подсветка на форме
Норма

Все нужные строки подсвечены, лишних нет

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

Подсвечены старые строки — забыли Очистить()

Поведение после сортировки
Норма

Выделение остаётся на тех же записях

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

Выделение «съехало» — использован индекс вместо идентификатора

Альтернативы выделению строк

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

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

Выделение оправдано, когда требуется именно интерактивность: пользователь должен увидеть отмеченные строки и продолжить с ними работу (скопировать, сгруппировать, передать в обработку). В остальных случаях условное оформление и отбор обычно удобнее и дешевле по ресурсам.

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

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

Нужно подсветить строки по условию надолго и без участия пользователяИспользуйте условное оформление списка или табличной части
Нужно показать только подходящие записиУстановите программный отбор динамического списка
Пользователь должен увидеть отмеченные строки и работать с ними дальшеЗаполните ВыделенныеСтроки идентификаторами или ключами записей
Нужно восстановить выделение после обновления формыСохраните идентификаторы перед обновлением и добавьте их обратно после

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

Почему ВыделенныеСтроки.Добавить() не даёт видимого эффекта?

Чаще всего причины три: передан индекс вместо идентификатора строки, запись скрыта отбором динамического списка, либо код выполняется до загрузки данных на форму. Проверьте Количество() у коллекции после добавления — если элемент добавился, но подсветки нет, проблема в отборе или визуальных настройках табличного поля.

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

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

Можно ли выделить строки в отчёте на СКД?

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

Как сохранить выделение при обновлении табличной части?

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

Работает ли программное выделение в веб-клиенте?

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

Чем ВыделенныеСтроки отличается от ТекущаяСтрока?

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

Итог

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

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