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

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

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

Метод 1. Обход на основе текущей строки формы

Если задача выполняется в контексте формы и нам нужно начать обработку со строки, на которой в данный момент установлен курсор, мы проанализируем использование идентификаторов и индексов. Важно помнить, что в управляемых формах свойство ТекущаяСтрока возвращает не индекс (0, 1, 2...), а внутренний идентификатор строки.

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

  1. Получим уникальный идентификатор строки из элемента формы.
  2. Найдем саму строку в данных объекта по этому идентификатору.
  3. Определим числовой индекс строки в коллекции.
  4. Запустим цикл от найденного индекса до конца таблицы.

Посмотрим на пример кода, который реализует эту логику:


// Определяем идентификатор строки, выбранной пользователем
ИдентификаторТекущейСтроки = Элементы.ГрафикПлатежей.ТекущаяСтрока;

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

Метод 2. Поиск строки по установленному флагу (Булево)

Часто пользователь не просто ставит курсор, а отмечает строку флажком (реквизит типа Булево). В этом случае нам сначала нужно выяснить, где именно стоит эта отметка. Проанализируем ситуацию: если мы точно знаем, что флаг установлен только в одной строке, мы можем использовать метод НайтиСтроки().

Рассмотрим подробнее реализацию этого подхода:


ПараметрыОтбора = Новый Структура("Выбрать", Истина);
НайденныеСтроки = Объект.ГрафикПлатежей.НайтиСтроки(ПараметрыОтбора);

Если НайденныеСтроки.Количество() > 0 Тогда
    // Берем первую найденную строку с флагом
    СтартоваяСтрока = НайденныеСтроки[0];
    НачальныйИндекс = Объект.ГрафикПлатежей.Индекс(СтартоваяСтрока);
    
    // Обходим таблицу с этой позиции до самого конца
    Для Индекс = НачальныйИндекс По Объект.ГрафикПлатежей.Количество() - 1 Цикл
        ТекущаяСтрока = Объект.ГрафикПлатежей[Индекс];
        ТекущаяСтрока.Сумма = Объект.НоваяСтоимость;
    КонецЦикла;
КонецЕсли;

Этот способ гораздо эффективнее и "красивее", чем попытки перебора всей таблицы с обратной стороны, которые изначально рассматривались автором вопроса. Метод НайтиСтроки работает быстро, так как использует внутренние механизмы платформы.

Важные нюансы работы с индексами и сортировкой

Выясним причину, по которой иногда программный обход может работать не так, как ожидает пользователь. Сортировка в списке — это критический момент. Если пользователь нажал на заголовок колонки "Дата" в таблице на экране, визуальный порядок строк изменился. Однако в программном объекте Объект.ГрафикПлатежей порядок строк остается первоначальным (в каком порядке они были добавлены).

Если вам принципиально важно соблюсти тот порядок, который видит пользователь с учетом его ручной сортировки, рекомендуем использовать метод Выгрузить() в Таблицу Значений, применить к ней аналогичную сортировку и только потом выполнять обход. Но в большинстве бизнес-задач достаточно обхода по физическому индексу в коллекции данных.

Оптимизация и стабильность кода

Рассмотрим несколько советов, которые помогут сделать ваш код более профессиональным:

  1. Использование идентификаторов: Никогда не полагайтесь на то, что идентификатор строки равен ее индексу. При удалении или перемещении строк индексы меняются, а идентификаторы внутри сеанса остаются стабильными. Всегда используйте метод Индекс(), чтобы получить актуальную позицию.
  2. Изменение состава таблицы: Если внутри цикла вы планируете удалять строки, обход нужно делать строго с конца (с максимального индекса до начального). Если вы просто меняете значения в колонках (как Сумма или Цена), обход "сверху вниз" от выбранной строки — идеальный вариант.
  3. Серверный контекст: Старайтесь выносить тяжелые расчеты в табличной части на сервер (например, в процедуру &НаСервере). На сервере метод НайтиСтроки и прямой доступ к индексам коллекции Объект.ГрафикПлатежей работают максимально быстро.

Подводя итог, можно сказать, что наиболее верным способом решения задачи является связка метода Индекс() и классического цикла Для ... По .... Это делает код читаемым, понятным для коллег и легким в отладке.

← На главную