Как правильно получить нужную строку табличной части в 1С?

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

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

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

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

  1. Индексация в коллекции начинается с 0. Первая строка имеет индекс 0, вторая — индекс 1, третья — индекс 2. При вызове метода Получить(2) платформа возвращает элемент с индексом 2, то есть третью по порядку строку.
  2. Системный реквизит НомерСтроки начинается с 1. Это визуальный и учетный номер строки, который видит пользователь в таблице.
  3. Идентификатор строки на форме не является индексом. В управляемой форме свойство Объект.ТабличнаяЧасть имеет тип ДанныеФормыКоллекция. Метод НайтиПоИдентификатору() принимает уникальный внутренний ключ строки формы, который генерируется динамически и не равен ее порядковому номеру или индексу.

Способ 1. Получение строки по ее индексу

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


НужныйНомерСтроки = 2;
Индекс = НужныйНомерСтроки - 1;

// Проверяем, существует ли строка с таким индексом
Если Объект.ТабличнаяЧасть.Количество() > Индекс Тогда
    Строка = Объект.ТабличнаяЧасть.Получить(Индекс);
    // Альтернативный вариант через квадратные скобки:
    // Строка = Объект.ТабличнаяЧасть[Индекс];
    
    ЗначениеРеквизита = Строка.Номенклатура;
КонецЕсли;

Важно: прямое обращение через Получить(Индекс) или [Индекс] без предварительной проверки общего количества строк в коллекции при выходе за границы диапазона вызовет исключение «Индекс находится за границами массива».

Способ 2. Поиск строки по системному реквизиту «НомерСтроки»

Рассмотрим вариант, когда необходимо найти строку именно по значению реквизита НомерСтроки. Для этого используем метод НайтиСтроки() с передачей структуры отбора:


ПараметрыОтбора = Новый Структура("НомерСтроки", 2);
НайденныеСтроки = Объект.ТабличнаяЧасть.НайтиСтроки(ПараметрыОтбора);

Если НайденныеСтроки.Количество() > 0 Тогда
    Строка = НайденныеСтроки[0];
    ЗначениеРеквизита = Строка.Сумма;
КонецЕсли;

Учитываем, что системный реквизит НомерСтроки у вновь добавленных или перемещенных строк в памяти может пересчитываться только в момент записи объекта или специального обновления таблицы.

Способ 3. Работа с идентификаторами строк и установка фокуса на форме

Разберем ситуацию, когда требуется программно активировать нужную строку в интерфейсе или найти элемент формы по его уникальному идентификатору:


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

В обычном приложении для позиционирования курсора в табличном поле используется прямое присвоение строки свойству ТекущаяСтрока элемента управления (ЭлементыФормы.ТабличнаяЧасть.ТекущаяСтрока = Строка;).

Способ 4. Определение индекса текущей или предыдущей строки

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


ТекущиеДанные = Элементы.ТабличнаяЧасть.ТекущиеДанные;

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

Таким образом, для безошибочной работы со строками табличных частей всегда учитываем: доступ по позиции в коллекции выполняется по индексу (от 0 до Количество() - 1), поиск по реквизитам выполняется через НайтиСтроки(), а работа с методами идентификаторов применяется для интерфейсных элементов управляемой формы.

← На главную