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

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

Как установить текущую строку в табличной части управляемой формы 1С

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

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

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

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

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

В обычных формах табличное поле позиционировалось через значение строки: ЭлементыФормы.Товары.ТекущаяСтрока = СтрокаТабличнойЧасти;. В управляемой форме этот приём не работает, потому что данные и их визуальное представление разделены. Элемент формы «ТаблицаФормы» оперирует идентификаторами строк коллекции данных формы, а не самими строками.

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

Установка текущей строки по известной строке данных

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

&НаКлиенте

Процедура УстановитьТекущуюСтроку(СтрокаДанных)

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

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

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

Важно: если код выполняется на сервере (в директиве &НаСервере), присвоение тоже сработает — состояние элемента передастся на клиент при возврате управления. Но если строка добавляется и позиционируется в клиентской процедуре, серверный вызов не нужен вовсе.

Порядок действий
  1. 1
    Получите строку данных коллекции (поиск, добавление, обход)
  2. 2
    Вызовите у строки метод ПолучитьИдентификатор()
  3. 3
    Присвойте результат свойству Элементы.<ИмяТаблицы>.ТекущаяСтрока
  4. 4
    Проверьте визуально: таблица прокрутилась и строка выделена

Позиционирование по номеру строки или индексу

Если известен только номер строки (например, последняя строка табличной части), сначала получите строку данных по индексу, а затем её идентификатор:

&НаКлиенте

Процедура ПерейтиКПоследнейСтроке()

Товары = Объект.Товары;

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

ПоследняяСтрока = Товары[Товары.Количество() - 1];

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

КонецЕсли;

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

Обратите внимание: индексация коллекции начинается с нуля, поэтому последняя строка имеет индекс Количество() - 1. Номер строки (свойство НомерСтроки) на единицу больше индекса и не используется для позиционирования — он нужен только для отображения и обращения к данным.

Установка текущей строки по условию поиска

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

&НаКлиенте

Процедура ПозиционироватьНаТовар(ИскомаяНоменклатура)

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

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

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

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

КонецЕсли;

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

Метод НайтиСтроки возвращает массив всех строк, удовлетворяющих отбору. Если дублей быть не должно, берите первый элемент; если дубли возможны, дополнительно проверьте другие колонки в цикле. Когда совпадений нет, массив пуст — обязательно проверяйте Количество(), иначе обращение к НайденныеСтроки[0] вызовет ошибку.

Позиционирование после добавления новой строки

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

&НаКлиенте

Процедура ДобавитьИПозиционировать(Команда)

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

НоваяСтрока.Номенклатура = ПредопределенноеЗначение("Справочник.Номенклатура.ПустаяСсылка");

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

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

Если нужно не просто выделить строку, а начать её редактирование (как при нажатии Insert), используйте метод Элементы.Товары.ИзменитьСтроку() после установки текущей строки — таблица перейдёт в режим редактирования текущей ячейки.

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

Установка текущей строки при открытии формы

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

&НаКлиенте

Процедура ПриОткрытии(Отказ)

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

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

КонецЕсли;

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

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

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

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

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

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

Третья группа ошибок связана с контекстом: свойство ТекущаяСтрока недоступно на сервере вне контекста формы (например, в модуле объекта или общем модуле). Позиционирование возможно только в модуле формы, где есть доступ к коллекции Элементы.

Типичные ошибки
01
Присвоение ТекущаяСтрока индекса или номера строки вместо идентификатора — позиционирование срабатывает на неправильной строке или не срабатывает вовсе
02
Обращение к НайденныеСтроки[0] без проверки Количество() — ошибка индекса при пустом результате поиска
03
Использование имени реквизита данных вместо имени элемента формы — ошибка 'Поле объекта не обнаружено'
04
Попытка позиционирования в модуле объекта или общем модуле — там нет доступа к элементам формы
05
Позиционирование на строке внутри свёрнутой ветки дерева — строка выделена, но не видна пользователю

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

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

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

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

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

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

Совпадает с идентификатором целевой строки

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

Неопределено, 0 или чужой идентификатор

Визуальное состояние таблицы
Норма

Нужная строка видна и выделена

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

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

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

Код не выполняет присвоение, ошибок нет

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

Ошибка обращения по индексу или падение при открытии формы

FAQ

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

Нет. Свойство принимает идентификатор строки коллекции данных формы, который не совпадает с номером. Чтобы перейти к строке с номером 5, получите её по индексу 4 и вызовите ПолучитьИдентификатор(), затем присвойте результат.

Почему присвоение выполняется без ошибки, но строка не выделяется?

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

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

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

Работает ли позиционирование на сервере?

Да, в серверных процедурах модуля формы присвоение Элементы.Таблица.ТекущаяСтрока допустимо — состояние передаётся на клиент при возврате. Но вне контекста формы (модуль объекта, общие модули) доступа к элементам нет, и позиционирование невозможно.

Как получить текущую строку, а не установить её?

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

Что делать, если таблица — это дерево значений?

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

Итог

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

Текущая строка табличной части управляемой формы задаётся через Элементы.<ИмяТаблицы>.ТекущаяСтрока, и значением должен быть идентификатор строки, полученный методом ПолучитьИдентификатор(). Не путайте идентификатор с индексом и номером строки, проверяйте результат поиска на пустоту и помните об особенностях динамических списков и деревьев.