Разработка и Конфигурация · 12 мин
Как получить выделенные строки табличной части в 1С
Как получить выделенные строки табличной части в 1С 8.3 через ВыделенныеСтроки, обработать их на сервере и в обычных формах. Примеры кода, ошибки и FAQ.
Задача получить строки, которые пользователь выделил в табличной части документа или в динамическом списке, возникает почти в каждой доработке: массовая обработка товаров, печать по выбранным позициям, перенос строк в другой документ. В управляемых формах 1С 8.3 для этого служит свойство ВыделенныеСтроки элемента формы, связанного с таблицей, а в обычных формах — аналогичное свойство табличного поля.
Ключевая тонкость: ВыделенныеСтроки возвращает не сами данные строк, а их идентификаторы (для таблиц значений и табличных частей — значения типа Число, для динамических списков — ссылки или ключи записей). Поэтому почти всегда требуется второй шаг — получить данные строки по идентификатору через НайтиПоИдентификатору(). Если пропустить этот шаг и попытаться обратиться к колонкам идентификатора, возникнет ошибка.
Ниже разобраны рабочие примеры для управляемых и обычных форм, обработка на клиенте и на сервере, особенности динамических списков и типовые ошибки, из-за которых код «не видит» выделенные строки.
Как устроено свойство ВыделенныеСтроки
У элемента формы типа «Таблица» есть свойство ВыделенныеСтроки — коллекция, содержащая идентификаторы всех строк, которые пользователь выделил мышью (с Ctrl, Shift или через «Выделить все»). Коллекция доступна только на клиенте, потому что выделение — состояние интерфейса, а не данных.
Тип элементов коллекции зависит от источника данных таблицы:
- Табличная часть объекта (например,
Объект.Товары) — идентификаторы строк, целые числа. Данные получают черезНайтиПоИдентификатору(). - Таблица значений или дерево значений как реквизит формы — тоже числовые идентификаторы, метод тот же.
- Динамический список — ссылки (для списков документов и справочников) или значения типа
КлючЗаписиРегистраСведений. Их можно использовать напрямую.
Если ни одна строка не выделена, коллекция пустая. Если выделена одна строка, она же обычно является и текущей (ТекущаяСтрока), но полагаться на это нельзя: текущая строка существует и без выделения.
Получение выделенных строк табличной части в управляемой форме
Типовой сценарий: на форме документа есть табличная часть «Товары» и кнопка, которая должна обработать только выделенные позиции. Обработчик команды объявляется с директивой &НаКлиенте, потому что ВыделенныеСтроки доступны только там.
&НаКлиенте
Процедура ОбработатьВыделенные(Команда)
Выделенные = Элементы.Товары.ВыделенныеСтроки;
Если Выделенные.Количество() = 0 Тогда
ПоказатьПредупреждение(, "Не выделено ни одной строки.");
Возврат;
КонецЕсли;
Для Каждого Идентификатор Из Выделенные Цикл
СтрокаТЧ = Объект.Товары.НайтиПоИдентификатору(Идентификатор);
Если СтрокаТЧ = Неопределено Тогда
Продолжить;
КонецЕсли;
// Работа с данными строки
Сообщить("Строка " + СтрокаТЧ.НомерСтроки + ": " + СтрокаТЧ.Номенклатура);
КонецЦикла;
КонецПроцедуры
Обратите внимание на проверку СтрокаТЧ = Неопределено: если данные формы изменились (например, строка была удалена в другом обработчике), идентификатор может «повиснуть». Проверка защищает от падения кода.
Если колонки табличной части на форме называются иначе, чем в метаданных, НайтиПоИдентификатору всё равно вернёт объект данных с исходными именами полей — обращаться нужно по именам реквизитов объекта, а не по именам колонок формы.
- 1Добавьте команду формы и кнопку в командную панель таблицы
- 2Создайте обработчик с директивой &НаКлиенте
- 3Получите Элементы.<Таблица>.ВыделенныеСтроки
- 4Проверьте, что коллекция не пустая
- 5В цикле получите данные через НайтиПоИдентификатору()
- 6Проверьте результат на реальных данных: выделите 2–3 строки с Ctrl
Передача выделенных строк на сервер
Серверные методы часто нужны, когда обработка требует запросов к базе: провести документы, создать записи, выполнить массовый пересчёт. Но ВыделенныеСтроки существует только на клиенте, поэтому идентификаторы сначала собирают в массив и передают в серверную процедуру.
&НаКлиенте
Процедура ЗаполнитьЦены(Команда)
Идентификаторы = Новый Массив;
Для Каждого Ид Из Элементы.Товары.ВыделенныеСтроки Цикл
Идентификаторы.Добавить(Ид);
КонецЦикла;
Если Идентификаторы.Количество() > 0 Тогда
ЗаполнитьЦеныНаСервере(Идентификаторы);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьЦеныНаСервере(Идентификаторы)
Для Каждого Ид Из Идентификаторы Цикл
СтрокаТЧ = Объект.Товары.НайтиПоИдентификатору(Ид);
Если СтрокаТЧ <> Неопределено Тогда
СтрокаТЧ.Цена = ПолучитьЦену(СтрокаТЧ.Номенклатура);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Такой подход работает и в формах с директивой &НаСервереБезКонтекста: там вместо Объект.Товары используют РеквизитФормыВЗначение("Объект"), но тогда идентификаторы строк формы не совпадут с индексами объекта — надёжнее оставить контекстный серверный вызов или передавать сами данные строк.
Выделенные строки в динамическом списке
Для динамических списков (журналы документов, списки справочников) ВыделенныеСтроки возвращает сразу полезные значения — ссылки на объекты. Искать данные по идентификатору не нужно:
&НаКлиенте
Процедура ПечатьВыделенных(Команда)
Для Каждого Ссылка Из Элементы.Список.ВыделенныеСтроки Цикл
// Ссылка — уже готовая ссылка на документ
КонецЦикла;
КонецПроцедуры
Для регистров сведений элементом коллекции будет КлючЗаписиРегистраСведений, а для списка с группировками могут попадаться служебные ключи строк группировки — их следует отфильтровывать проверкой типа значения.
Если список построен на произвольном запросе с основной таблицей, ссылки возвращаются корректно. Если основная таблица не указана, состав выделенных строк может быть сложным (структуры с полями), и обработку придётся строить индивидуально.
Сравнение вариантов
Все выделенные пользователем строки. Подходит для массовых операций. Требует включённого множественного выделения.
Одна активная строка. Подходит для команд над одной записью, но игнорирует множественное выделение.
Данные текущей строки без поиска по идентификатору. Удобно для чтения, но не даёт остальных выделенных строк.
Настройка множественного выделения и типичные ограничения
Чтобы пользователь мог выделить несколько строк, у элемента таблицы должно быть установлено свойство РежимВыделения = Множественный. В типовых формах оно обычно включено, но в самописных формах его легко забыть — тогда ВыделенныеСтроки всегда будет содержать максимум один элемент.
Дополнительные ограничения, о которых стоит помнить:
- Свойство недоступно в серверных процедурах и в толстом клиенте обычного приложения вне контекста табличного поля.
- В режиме только просмотр таблицы выделение работает, но модифицировать строки нельзя.
- При отборе или перерисовке списка выделение может сбрасываться — собирайте идентификаторы до операций, меняющих данные формы.
- Для иерархических динамических списков в выделении могут оказаться строки групп — проверяйте тип значения.
Обычные формы: табличное поле
В обычных формах (режим обычного приложения, 8.2/8.3) синтаксис отличается: работа идёт через элемент ТабличноеПоле, а сами данные строк доступны через ВыделенныеСтроки сразу как строки табличной части:
Процедура КнопкаОбработать(Элемент)
Для Каждого Строка Из ЭлементыФормы.Товары.ВыделенныеСтроки Цикл
Сообщить(Строка.Номенклатура);
КонецЦикла;
КонецПроцедуры
Здесь ВыделенныеСтроки возвращает коллекцию строк данных, а не идентификаторов, поэтому НайтиПоИдентификатору не нужен. Множественное выделение включается свойством табличного поля «Множественный выбор» либо оно разрешено по умолчанию в зависимости от настроек.
Проверка результата и отладка
Быстрый способ убедиться, что механизм работает: временно вывести количество и содержимое выделенных строк. В управляемой форме достаточно такого фрагмента:
Для Каждого Ид Из Элементы.Товары.ВыделенныеСтроки Цикл
СтрокаТЧ = Объект.Товары.НайтиПоИдентификатору(Ид);
Сообщить("Ид=" + Ид + ", строка №" + СтрокаТЧ.НомерСтроки);
КонецЦикла;
Проверяйте три сценария: одна выделенная строка, несколько строк через Ctrl и выделение всех строк через Ctrl+A. Отдельно проверьте случай без выделения — пользователь должен получить понятное сообщение, а не тихий выход или ошибку.
Как проверить результат
Совпадает с числом визуально выделенных строк
Всегда 0 или 1 — проверьте режим выделения таблицы
Возвращает строку с ожидаемыми данными
Возвращает Неопределено — идентификатор устарел или взята не та коллекция
Изменены только выделенные строки
Изменены все строки — потерян фильтр по идентификаторам
Частые вопросы
Чем ВыделенныеСтроки отличается от ТекущаяСтрока?
ТекущаяСтрока — это одна активная строка, на которой стоит курсор; она существует всегда, даже без выделения. ВыделенныеСтроки — коллекция всех строк, выделенных пользователем, их может быть несколько или ни одной. Для массовых операций используйте ВыделенныеСтроки, для команд над одной записью — ТекущиеДанные.
Почему ВыделенныеСтроки возвращает числа, а не строки с данными?
Потому что для табличных частей и таблиц значений платформа передаёт числовые идентификаторы строк данных формы, а не сами данные. Чтобы получить данные, вызовите НайтиПоИдентификатору(Ид) у коллекции (например, Объект.Товары). В динамических списках вместо чисел возвращаются ссылки или ключи записей.
Можно ли получить выделенные строки на сервере?
Нет, свойство доступно только в клиентском контексте, так как выделение — состояние интерфейса. Соберите идентификаторы в массив на клиенте и передайте его параметром в серверную процедуру, где уже выполните поиск строк и обработку.
Почему коллекция всегда содержит только одну строку?
Скорее всего, у элемента таблицы формы режим выделения установлен в «Одиночный». Откройте свойства таблицы в редакторе формы и установите «Множественный». После этого пользователь сможет выделять строки с Ctrl и Shift, и все они попадут в коллекцию.
Как обработать выделенные строки, если документ ещё не записан?
Для операций внутри формы (пересчёт, заполнение цен) записывать документ не обязательно — данные доступны в реквизите Объект. Но если обработка подразумевает проведение, создание связанных документов или запись в регистры, сначала принудительно запишите документ и проверьте результат записи, иначе получите ошибку ссылки.
Работает ли ВыделенныеСтроки в мобильном клиенте и веб-клиенте?
Да, свойство поддерживается во всех клиентах управляемого приложения. Различие в том, что на сенсорных устройствах множественное выделение может требовать специального жеста или режима, поэтому для мобильных сценариев стоит дополнительно проверять, что в коллекции действительно несколько строк.
Что важно запомнить
ВыделенныеСтроки — клиентская коллекция идентификаторов выделенных строк. Для табличной части данные получают через НайтиПоИдентификатору(), для динамического списка идентификаторы — это ссылки. Проверяйте пустую коллекцию, включайте множественный режим выделения и передавайте на сервер только массив идентификаторов.