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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

Почему свойство ТекущаяСтрока не совпадает с номером строки

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

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

  1. Он формируется платформой автоматически при добавлении строки в коллекцию формы.
  2. Работает как автоинкрементный счетчик: если добавить 5 строк, затем удалить их или вызвать метод Очистить(), а потом добавить еще одну строку, её идентификатор начнется со следующего числа (например, 6).
  3. Сбросить этот счетчик в рамках открытой формы программно нельзя. Счетчик идентификаторов обнуляется только при полном закрытии и повторном создании контекста формы.

Именно поэтому попытка использовать значение Элементы.Таблица.ТекущаяСтрока как порядковый номер строки приводит к логическим ошибкам.

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

Рассмотрим, как правильно получить данные выбранной строки в клиентском контексте. Для этого у элемента формы существует свойство ТекущиеДанные.

Посмотрим на пример клиентского кода:


&НаКлиенте
Процедура ОбработатьВыделеннуюСтроку()
    СтрокаДанных = Элементы.ТабличнаяЧасть.ТекущиеДанные;
    
    Если СтрокаДанных = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Если это табличная часть документа, порядковый номер хранится в реквизите НомерСтроки
    ПорядковыйНомер = СтрокаДанных.НомерСтроки;
КонецПроцедуры

Важно помнить: свойство ТекущиеДанные возвращает объект ДанныеФормыЭлементКоллекции. В этом объекте на клиенте доступны только те реквизиты, которые добавлены в колонки таблицы формы, либо для которых у соответствующего реквизита установлен флаг Использовать всегда.

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


&НаКлиенте
Процедура ПолучитьДанныеКонкретнойСтроки(ИдентификаторСтроки)
    СтрокаДанных = Элементы.ТабличнаяЧасть.ДанныеСтроки(ИдентификаторСтроки);
    Если СтрокаДанных <> Неопределено Тогда
        // Обработка данных строки
    КонецЕсли;
КонецПроцедуры

Как получить текущую строку на сервере через идентификатор

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

Разберем по шагам, как это работает:

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

Посмотрим на пример серверного метода:


&НаСервере
Процедура ОбработатьСтрокуНаСервере()
    ИдентификаторСтроки = Элементы.Товары.ТекущаяСтрока;
    
    Если ИдентификаторСтроки = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    СтрокаДанных = Объект.Товары.НайтиПоИдентификатору(ИдентификаторСтроки);
    
    Если СтрокаДанных <> Неопределено Тогда
        // Для стандартной табличной части документа
        Номер = СтрокаДанных.НомерСтроки;
    КонецЕсли;
КонецПроцедуры

Как определить порядковый номер в произвольной коллекции (ТаблицаЗначений)

Если таблица формы связана не с табличной частью документа, а с реквизитом формы типа «ТаблицаЗначений», то реквизит НомерСтроки у таких строк отсутствует по умолчанию.

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


&НаСервере
Процедура ОпределитьНомерСтрокиТЗ()
    Идентификатор = Элементы.ТаблицаТЗ.ТекущаяСтрока;
    СтрокаТЗ = Объект.ТаблицаТЗ.НайтиПоИдентификатору(Идентификатор);
    
    Если СтрокаТЗ <> Неопределено Тогда
        ИндексСтроки = Объект.ТаблицаТЗ.Индекс(СтрокаТЗ); // Индекс от 0 до N-1
        ПорядковыйНомер = ИндексСтроки + 1;
    КонецЕсли;
КонецПроцедуры

Как программно позиционировать курсор на строке таблицы

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

Рассмотрим, как правильно установить фокус на нужную строку:


// Находим или выбираем строку в коллекции
СтрокаКоллекции = Объект.Товары[0]; // Например, первая строка

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

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

← На главную