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