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

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

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

Способ 1. Обращение к реквизитам по строковому имени в цикле

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

Рассмотрим пример, когда нам нужно обойти строку табличной части и получить значения реквизитов с именами "День1", "День2" и так далее до "День31":


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

Важный нюанс: На практике разработчики часто используют ведущие нули в именах реквизитов для правильной сортировки в конфигураторе (например, "День01", "День02"). В этом случае обычное сложение строки с числом не сработает. Нам потребуется функция Формат, чтобы привести число к двухзначному виду.

Проанализируем улучшенный вариант кода:


Для сч = 1 По 31 Цикл
    // Параметр ЧВН= добавляет ведущий ноль, ЧЦ=2 ограничивает длину
    ИмяРеквизита = "День" + Формат(сч, "ЧЦ=2; ЧВН="); 
    Значение = СтрокаТЧ[ИмяРеквизита];
    // Работа с данными...
КонецЦикла;

Способ 2. Универсальный перебор через объект Метаданные

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

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


// Получаем метаданные нужной табличной части документа
МетаданныеТЧ = Метаданные.Документы.НачислениеЗарплаты.ТабличныеЧасти.Начисления;

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

Этот метод удобен тем, что мы можем программно анализировать типы данных. Например, если нам нужно суммировать только числовые показатели, мы можем добавить проверку ТипДанных.СодержитТип(Тип("Число")). Для отображения и расчета сумм в интерактивном режиме пригодится инструмент для организации итогов в подвале табличных частей.

Способ 3. Перебор элементов на форме

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

Посмотрим, как перебрать визуальные колонки таблицы на форме:


// "ГруппаКолонок" или сама таблица
КоллекцияЭлементов = Элементы.ТабличнаяЧастьСостав.ПодчиненныеЭлементы;

Для каждого ЭлементКолонка Из КоллекцияЭлементов Цикл
    Если ТипЗнч(ЭлементКолонка) = Тип("ПолеФормы") Тогда
        // Управляем свойствами отображения
        ЭлементКолонка.Видимость = Истина;
        ЭлементКолонка.ТолькоПросмотр = Ложь;
    КонецЕсли;
КонецЦикла;

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

Способ 4. Использование выгрузки в Таблицу Значений

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

Рассмотрим пример использования метода Выгрузить():


// Выгружаем всю ТЧ в таблицу значений
ТЗ = Объект.Состав.Выгрузить();

// Теперь мы можем перебирать колонки таблицы значений
Для каждого Колонка Из ТЗ.Колонки Цикл
    Имя = Колонка.Имя;
    // Мы можем быстро получить массив значений всей колонки
    МассивЗначений = ТЗ.ВыгрузитьКолонку(Имя);
КонецЦикла;

Преимущество: Работа с ТЗ.Колонки часто происходит быстрее, чем постоянное обращение к Метаданные, особенно в больших циклах обработки данных.

Ограничения и важные нюансы

Выясним причины возможных ошибок при массовой работе с реквизитами:

  1. Ограничения СУБД: При проектировании табличных частей стоит помнить, что общее количество полей в одной физической таблице базы данных (особенно в MS SQL Server) ограничено (около 1024 колонок). Если ваша табличная часть приближается к этому числу реквизитов (например, "День" с 1 по 1000), платформа может выдать критическую ошибку при реструктуризации базы.
  2. Безопасное обращение: При обращении через СтрокаТЧ[ИмяРеквизита] всегда нужно быть уверенным, что такой реквизит существует. Если есть сомнения, лучше предварительно проверить наличие колонки через метод Найти у коллекции колонок (если используется ТЗ) или через метаданные.
  3. Метод ЗаполнитьЗначенияСвойств: Если ваша цель — просто скопировать данные из одной строки в другую (или в другой объект с такими же именами полей), не нужно писать цикл. Используйте встроенную функцию ЗаполнитьЗначенияСвойств(Приемник, Источник). Она автоматически сопоставит имена всех реквизитов и перенесет значения, что значительно ускорит работу кода и уменьшит вероятность ошибок.

Проанализировав все способы, можно сделать вывод: выбор метода зависит от конкретной задачи. Для работы с известными именами ("День1", "День2") используйте индексацию строкой. Для универсальных механизмов — Метаданные. А для управления интерфейсом — коллекцию ПодчиненныеЭлементы формы.

← На главную