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

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

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

Разбираемся в причинах: почему ТекущаяСтрока возвращает «странные» значения

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

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

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

Разница между идентификатором и индексом

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

  1. Идентификатор строки: Свойство ТекущаяСтрока. Служит для однозначного поиска строки в коллекции данных. Не зависит от порядка отображения или физического расположения в массиве.
  2. Индекс строки: Порядковый номер строки в массиве данных (начиная с 0). Именно индекс нужен для математических операций, таких как получение «предыдущей» (Индекс - 1) или «следующей» (Индекс + 1) строки.
  3. Номер строки: Свойство НомерСтроки (если оно есть у объекта данных, например, в табличных частях документов). Часто совпадает с визуальным номером, но не всегда удобен для программного обращения по индексу.

Решение 1: Получение индекса на клиенте

Если нам нужно узнать индекс текущей строки непосредственно в клиентском коде (например, при изменении поля), мы можем воспользоваться методом Индекс(). Важно понимать, у какого объекта вызывать этот метод.

Рассмотрим типичную ошибку: попытка вызвать метод Индекс() у элемента формы. Проанализируем правильный подход:


&НаКлиенте
Процедура МояТаблицаПриИзменении(Элемент)
    
    // Элемент — это таблица на форме (визуальный объект)
    // Нам нужно обратиться к данным, которые за ней стоят
    ТекущиеДанные = Элементы.МояТаблица.ТекущиеДанные;
    
    Если ТекущиеДанные <> Неопределено Тогда
        // Вызываем метод Индекс у РЕКВИЗИТА формы (ДанныеФормыКоллекция)
        ИндексСтроки = Объект.МояТаблица.Индекс(ТекущиеДанные);
        Сообщить("Текущий индекс строки: " + ИндексСтроки);
    КонецЕсли;

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

В данном примере Объект.МояТаблица — это сама коллекция данных. Метод Индекс() принимает в качестве параметра объект строки (который мы получаем через ТекущиеДанные) и возвращает её физическое положение в массиве.

Решение 2: Получение индекса на сервере

Часто бизнес-логика требует перехода на сервер. Однако стоит помнить, что на сервере свойство ТекущиеДанные у элемента формы недоступно. Чтобы получить индекс на сервере, нам нужно передать туда идентификатор строки.

Разберем по шагам алгоритм получения индекса на сервере:


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

Такой подход универсален и позволяет точно определить положение строки в исходных данных, независимо от того, какие идентификаторы присвоила им платформа.

Работа с соседними строками: Предыдущая и Следующая

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

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


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

Обратите внимание: использование конструкции ДанныеТЗ[Индекс] работает только в том случае, если мы уверены, что индекс находится в границах массива. Именно поэтому мы добавили проверки ТекущийИндекс > 0 и сравнение с Количество() - 1. Это защитит ваш код от критических ошибок при обращении к несуществующим элементам.

Важные нюансы при работе с визуальными фильтрами

Нужно учитывать, что метод Индекс() всегда возвращает положение строки в исходной коллекции данных. Если пользователь на форме применил поиск через «Ctrl+F» или установил отбор через контекстное меню, визуальный порядок строк изменится.

Если ваша задача требует получения строки, которая находится выше именно на экране (с учетом всех фильтров и сортировок), то стандартными средствами ДанныеФормыКоллекция это сделать крайне сложно, так как коллекция данных на сервере «не знает» о визуальных манипуляциях пользователя на клиенте. В 99% случаев бизнес-логики требуется именно индекс в данных, а не визуальный порядок, поэтому описанные выше методы являются общепринятым стандартом.

Подведем итоги

Для корректной работы с позиционированием в таблицах управляемых форм мы рекомендуем придерживаться следующих правил:

Применяя эти знания, вы сможете избежать «плавающих» ошибок, связанных с обновлением таблиц, и обеспечите надежную работу логики вашего программного продукта.

← На главную