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

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

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

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

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

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

Как устроено выделение строки в управляемой форме

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

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

Выделение одной строки через ТекущаяСтрока

Базовый сценарий: найти строку по условию и установить на неё курсор. Поиск выполняется по коллекции данных, а не по элементу формы:

// Позиционирование на строке с нужным товаром

ПараметрыОтбора = Новый Структура("Номенклатура", ИскомаяНоменклатура);

НайденныеСтроки = Объект.Товары.НайтиСтроки(ПараметрыОтбора);

Если НайденныеСтроки.Количество() > 0 Тогда

Элементы.Товары.ТекущаяСтрока = НайденныеСтроки[0].ПолучитьИдентификатор();

Иначе

Сообщить("Строка с указанной номенклатурой не найдена");

КонецЕсли;

Если строка известна по индексу (например, нужно выделить третью строку), используют обращение по индексу коллекции с последующим получением идентификатора:

Если Объект.Товары.Количество() >= 3 Тогда

СтрокаДанных = Объект.Товары[2]; // индексация с нуля

Элементы.Товары.ТекущаяСтрока = СтрокаДанных.ПолучитьИдентификатор();

КонецЕсли;

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

bsl
Элементы.Товары.ТекущаяСтрока = СтрокаДанных.ПолучитьИдентификатор();

Выделение строки после добавления

Самый частый практический случай — пользователь или код добавляет строку, и курсор должен встать на неё, чтобы сразу начать ввод. Метод Добавить() возвращает добавленную строку, поэтому идентификатор берётся напрямую:

НоваяСтрока = Объект.Товары.Добавить();

НоваяСтрока.Номенклатура = ПодобраннаяНоменклатура;

Элементы.Товары.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();

Элементы.Товары.ТекущийЭлемент = Элементы.ТоварыКоличество; // фокус в колонку

Установка ТекущийЭлемент дополнительно переводит фокус ввода в конкретную колонку — это удобно при подборе, когда после выделения строки пользователь должен сразу ввести количество. Без этого фокус останется на первой редактируемой колонке или вне таблицы.

Позиционирование после подбора из другой формы

При обработке выбора из формы подбора строки добавляются пакетно. Чтобы выделить первую из добавленных, запомните количество строк до добавления, а после — возьмите строку по этому индексу:

ИндексПервойНовой = Объект.Товары.Количество();

// ... добавление строк из выборки ...

Если Объект.Товары.Количество() > ИндексПервойНовой Тогда

Элементы.Товары.ТекущаяСтрока =

Объект.Товары[ИндексПервойНовой].ПолучитьИдентификатор();

КонецЕсли;

Выделение нескольких строк через ВыделенныеСтроки

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

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

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

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

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

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

КонецЕсли;

КонецЦикла;

Чтобы множественное выделение было видно и работало, у таблицы формы должен быть включён соответствующий режим выделения (свойство РежимВыделения — «Множественный»). В типовых формах документов он обычно включён по умолчанию. Если режим одиночный, в коллекции останется максимум одна строка.

Позиционирование в динамическом списке и обычных формах

Если таблица формы отображает динамический список (например, список документов), то ТекущаяСтрока принимает не идентификатор, а ключ строки — ссылку на объект:

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

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

Обычные формы (8.2 и ранее приложения)

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

ЭлементыФормы.Товары.ТекущаяСтрока = Объект.Товары[ИндексСтроки];

Смешивать подходы нельзя: код обычной формы в управляемой форме не скомпилируется осмысленно, так как ЭлементыФормы там отсутствует.

Сравнение вариантов

ТекущаяСтрока + ПолучитьИдентификатор()

Управляемая форма, табличная часть или таблица значений. Универсальный способ, работает везде в тонком и веб-клиенте.

ВыделенныеСтроки

Когда нужно подсветить несколько строк одновременно. Требует множественного режима выделения.

ТекущаяСтрока = Ссылка

Только для динамических списков. Не сработает, если отбор исключает строку.

Условное оформление вместо выделения

Если цель — постоянная подсветка по условию, а не разовое позиционирование. Не перемещает курсор.

Проверка результата и типовые ошибки

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

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

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

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

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

Элементы.Товары.ТекущиеДанные после выделения
Норма

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

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

Неопределено или данные другой строки — идентификатор неверный

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

Совпадает с числом строк, которые должны быть подсвечены

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

1 или 0 при множественном выделении — проверьте РежимВыделения таблицы

Повторный запуск кода после изменения данных
Норма

Выделяется актуальная строка, найденная заново

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

Выделяется старая позиция — идентификатор закэширован

Когда выделение не нужно: альтернативы

Если цель — не переместить курсор, а привлечь внимание пользователя, программное выделение часто избыточно. Условное оформление формы подсвечивает строки по условию постоянно и не зависит от идентификаторов. Метод Активизировать() у элемента формы переводит фокус на таблицу без смены текущей строки. А для сообщений об ошибках заполнения платформа сама умеет привязывать сообщение к строке табличной части через Сообщение.УстановитьДанные() и путь к данным — пользователь перейдёт к строке кликом по сообщению.

Итог

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

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

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

Почему присваивание ТекущаяСтрока не даёт видимого эффекта?

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

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

В обработчике ПриОткрытии найдите нужную строку методом НайтиСтроки по ключевым полям и присвойте её идентификатор свойству Элементы.ИмяТаблицы.ТекущаяСтрока. Если документ только что создан и табличная часть пуста, позиционировать нечего — добавьте проверку Количество() > 0.

Можно ли выделить строку, не перемещая туда курсор редактирования?

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

Чем отличается ПолучитьИдентификатор() от НомерСтроки?

НомерСтроки — это видимый порядковый номер (1, 2, 3...), который меняется при удалении и сортировке строк. Идентификатор — служебный ключ строки в коллекции формы, именно его принимает свойство ТекущаяСтрока. Присваивание номера строки вместо идентификатора — частая причина выделения не той строки.

Работает ли этот способ в веб-клиенте и мобильном клиенте?

Присваивание ТекущаяСтрока и работа с ВыделенныеСтроки поддерживаются в тонком, толстом и веб-клиенте управляемого приложения. В мобильной платформе поведение таблиц имеет особенности, и визуальное позиционирование там следует проверять на целевом устройстве.

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

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