Как получить имя колонки (свойство) при переборе строки таблицы значений?

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

При разработке на платформе 1С:Предприятие программисты часто сталкиваются с необходимостью универсальной обработки данных. Типичная ситуация: у нас есть объект ТаблицаЗначений, и мы хотим перебрать все её колонки для каждой строки, чтобы выполнить определенные действия (например, найти значения типа УникальныйИдентификатор для синхронизации данных). Однако стандартный обход строки через цикл Для каждого выдает только значения, «теряя» имена колонок. Разберем подробно, почему так происходит и как правильно решить эту задачу.

Анализ проблемы: почему цикл по строке не возвращает имена колонок?

Рассмотрим ситуацию, в которой оказался автор темы. При использовании конструкции Для каждого Реквизит Из СтрокаТЗ Цикл, переменная Реквизит будет принимать только значения ячеек этой строки. Это происходит потому, что объект СтрокаТаблицыЗначений в 1С не является коллекцией пар «Ключ-Значение» (как, например, Структура или Соответствие). Это объект, который предоставляет доступ к данным, но сам по себе при итерации ведет себя как простой набор значений.

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

Способ 1. Обход через коллекцию колонок таблицы (рекомендуемый)

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


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

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

Способ 2. Использование индекса при обходе строки

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


Для каждого СтрокаТЗ Из ТЗ Цикл
    Индекс = 0;
    Для каждого Значение Из СтрокаТЗ Цикл
        // Получаем имя колонки по текущему индексу
        ИмяКолонки = ТЗ.Колонки[Индекс].Имя;
        
        Если ТипЗнч(Значение) = Тип("УникальныйИдентификатор") Тогда
            // Выполняем действия
        КонецЕсли;
        
        Индекс = Индекс + 1;
    КонецЦикла;
КонецЦикла;

Важное замечание: Мы рекомендуем использовать первый способ (обход по именам), так как он более читаем и менее подвержен ошибкам, если структура таблицы будет программно изменяться в процессе работы.

Способ 3. Преобразование строки в структуру

Если вам удобнее работать с объектом, который изначально содержит пары «Имя-Значение», можно преобразовать строку таблицы значений в Структуру. В современных конфигурациях на базе БСП (Библиотека стандартных подсистем) для этого есть готовые методы, но мы разберем, как это сделать вручную. Рассмотрим пример:


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

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

Использование метода ЗаполнитьЗначенияСвойств позволяет быстро переложить данные из СтрокаТаблицыЗначений в Структуру. Это особенно полезно, если в дальнейшем данные строки нужно передать в функцию, ожидающую структуру параметров.

Оптимизация производительности при работе с большими таблицами

Выясним важный технический нюанс. Если ваша таблица содержит десятки тысяч строк, обращение к коллекции ТЗ.Колонки внутри вложенного цикла может замедлить работу. Чтобы оптимизировать код, выполним предварительное кэширование имен колонок. Разберем по шагам:

  1. Создадим массив и заранее выгрузим в него имена всех колонок.
  2. В основном цикле по строкам будем перебирать этот массив строк, а не объект метаданных колонок.

// Шаг 1: Кэширование имен колонок
МассивИменКолонок = Новый Массив;
Для каждого Колонка Из ТЗ.Колонки Цикл
    МассивИменКолонок.Добавить(Колонка.Имя);
КонецЦикла;

// Шаг 2: Основной цикл
Для каждого СтрокаТЗ Из ТЗ Цикл
    Для каждого ИмяКолонки Из МассивИменКолонок Цикл
        ТекущееЗначение = СтрокаТЗ[ИмяКолонки];
        // Обработка значения...
    КонецЦикла;
КонецЦикла;

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

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

В обсуждении на форуме возникла путаница в терминах. Посмотрим на принципиальное различие:

Если вы работаете с ТабличнойЧастью на форме, проще всего сначала выгрузить её в ТаблицуЗначений методом Выгрузить(), а затем использовать способы, описанные выше.

Заключение

Мы проанализировали несколько подходов к получению свойств строки. Подведем итог: самый правильный путь — это итерация по коллекции имен колонок таблицы с последующим обращением к строке по этому имени через квадратные скобки []. Это обеспечивает гибкость, универсальность и высокую скорость работы вашего кода.

← На главную