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

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

Работа с табличными данными — одна из самых частых задач разработчика в среде 1С — есть инструменты для отладки и анализа кода 1С. Будь то расчет итогов в документе, заполнение цен или обработка данных внешней таблицы значений, нам необходимо четко понимать, как обращаться к строкам и колонкам. В этой статье мы подробно разберем, как реализовать двойной цикл для обхода ячеек, как получить доступ к конкретному документу и какие нюансы клиент-серверного взаимодействия стоит учитывать.

Различие между Таблицей значений и Табличной частью

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

Универсальный перебор строк и колонок (двойной цикл)

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


// Предположим, ТаблицаДанных уже заполнена на сервере
Для Каждого ТекущаяСтрока Из ТаблицаДанных Цикл
    Для Каждого ТекущаяКолонка Из ТаблицаДанных.Колонки Цикл
        // Обращаемся к значению через имя колонки
        ЗначениеЯчейки = ТекущаяСтрока[ТекущаяКолонка.Имя];
        
        // Здесь можно выполнять расчеты
        Сообщить("В строке " + ТаблицаДанных.Индекс(ТекущаяСтрока) + 
                 " в колонке " + ТекущаяКолонка.Имя + 
                 " находится значение: " + ЗначениеЯчейки);
    КонецЦикла;
КонецЦикла;

В этом примере внешний цикл перебирает строки, а внутренний — коллекцию колонок этой таблицы. Это позволяет коду оставаться гибким: если в таблицу добавят новую колонку (например, "Январь" или "Декабрь"), код продолжит работать без изменений.

Обращение к ячейкам по индексам

Иногда нам не нужно перебирать всё, а требуется обратиться к конкретной ячейке. Важно помнить, что в 1С индексация всегда начинается с 0. Выясним, как прочитать значение в строке номер i и колонке y:

  1. Через индекс строки и имя колонки: Значение = Таблица[ИндексСтроки].ИмяКолонки;
  2. Через индекс строки и индекс колонки: Значение = Таблица[ИндексСтроки][ИндексКолонки];

Если мы хотим реализовать задачу суммирования нечетных строк, нам поможет оператор остатка от деления %. Обратите внимание: для пользователя первая строка имеет номер 1 (нечетная), но в коде это индекс 0 (четный). Поэтому логику условий нужно проектировать внимательно.


СуммаНечетных = 0;
Для Индекс = 0 По ТаблицаДанных.Количество() - 1 Цикл
    // Проверяем "человеческий" номер строки (Индекс + 1)
    Если (Индекс + 1) % 2 <> 0 Тогда 
        СуммаНечетных = СуммаНечетных + ТаблицаДанных[Индекс].Сумма;
    КонецЕсли;
КонецЦикла;

Как обратиться к конкретному документу и его таблице

Часто возникает вопрос: как "прописать путь" к таблице документа? — для этого подойдёт настройка правил заполнения табличных частей без программирования. Если вы находитесь внутри модуля формы самого документа, то всё просто: используйте путь Объект.ИмяВашейТабличнойЧасти. Однако, если вы пишете внешнюю обработку или отчет, алгоритм будет другим. Разберем его по шагам:

  1. Найти ссылку на документ: Это можно сделать через запрос, поиском по номеру Документы.Продажи.НайтиПоНомеру("001", ДатаПоиска) или выбрав ссылку через реквизит формы.
  2. Получить объект: Ссылка доступна только для чтения. Чтобы изменять данные (добавлять строки, менять значения), нужно вызвать метод ПолучитьОбъект().
  3. Обработать данные: Выполнить циклы по табличной части объекта.
  4. Записать изменения: Вызвать Объект.Записать(), чтобы сохранить результат в базе.

Пример получения данных из конкретного документа:


// Находим ссылку (для примера возьмем первую попавшуюся)
СсылкаНаДок = Документы.РеализацияТоваровУслуг.Выбрать().Следующий(); 

Если СсылкаНаДок Тогда
    ДокОбъект = СсылкаНаДок.ПолучитьОбъект();
    
    // Перебираем строки табличной части "Товары"
    Для Каждого СтрокаТовар Из ДокОбъект.Товары Цикл
        // Доступ к колонкам напрямую по имени
        ТекущаяЦена = СтрокаТовар.Цена;
        СтрокаТовар.Сумма = ТекущаяЦена * СтрокаТовар.Количество;
    КонецЦикла;
    
    // Сохраняем документ
    ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
КонецЕсли;

Оптимизация: Использование метода Итог()

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

Пример: ВсегоПоДокументу = Объект.Товары.Итог("Сумма");

Важные правила клиент-серверного взаимодействия

Посмотрим на типичную ошибку начинающих (поможет отладка и написание кода в режиме Предприятия): попытка работать с типом ТаблицаЗначений на клиенте. В управляемых формах &НаКлиенте вы работаете с типом ДанныеФормыКоллекция. Если вам требуются специфические методы ТЗ (например, Свернуть() или НайтиСтроки()), вам необходимо передать данные на сервер:

Резюмируем: Для простого перебора колонок используйте вложенный цикл по коллекции Колонки. Для доступа к строкам используйте коллекцию табличной части. Всегда помните об индексации с нуля и старайтесь выполнять тяжелые расчеты на стороне сервера, используя объектную модель документа.

← На главную