Разработка и Конфигурация · 12 мин
Как обойти колонки табличной части в 1С
Как обойти колонки табличной части в 1С: перебор через метаданные, коллекцию колонок таблицы значений, обход строк и ячеек. Примеры кода, ошибки и проверка результата.
Обход колонок табличной части — типовая задача при разработке на платформе 1С:Предприятие. Она возникает, когда нужно универсально обработать данные без жёсткой привязки к именам реквизитов: построить динамический отчёт, выгрузить табличную часть в произвольную структуру, проверить заполненность всех полей или скопировать данные между объектами с похожим составом колонок.
Важно сразу разделить два разных объекта. Табличная часть объекта конфигурации (документа, справочника) — это коллекция строк, а состав её колонок описан в метаданных. Таблица значений — самостоятельный объект со своей коллекцией Колонки. Способы обхода для них отличаются, и путаница между ними — самая частая причина ошибок у начинающих разработчиков.
Ниже разобраны рабочие варианты обхода колонок: через метаданные табличной части, через коллекцию колонок таблицы значений, через элементы формы для управляемого интерфейса, а также построчный доступ к значениям ячеек. Каждый способ сопровождается примером кода и указанием, когда он применим.
Что именно нужно обойти: метаданные, колонки или значения
Прежде чем писать цикл, определите, какая из трёх задач стоит на самом деле. Первая — получить список колонок табличной части как они описаны в конфигураторе (имена, типы, синонимы). Это делается через объект метаданных и работает даже без открытого документа.
Вторая задача — перебрать колонки таблицы значений, полученной выгрузкой табличной части или построенной программно. Здесь используется коллекция Колонки, где каждый элемент — объект типа КолонкаТаблицыЗначений со свойствами Имя, ТипЗначения, Заголовок, Ширина.
Третья задача — пройтись по значениям ячеек в строках. В этом случае колонки обходят внутри цикла по строкам, обращаясь к значению через индексированное свойство Строка[ИмяКолонки]. Смешивать эти подходы в одном цикле без понимания структуры данных — прямой путь к ошибкам «Поле объекта не обнаружено».
Обход колонок через метаданные табличной части
Состав реквизитов табличной части хранится в дереве метаданных. Доступ к нему выполняется по полному пути: объект конфигурации → табличные части → реквизиты конкретной табличной части. Этот способ не требует экземпляра документа и подходит для универсальных процедур, работающих с любым объектом.
Пример перебора реквизитов табличной части «Товары» документа «РеализацияТоваровУслуг»:
ОбъектМетаданных = Метаданные.Документы.РеализацияТоваровУслуг;
ТабЧасть = ОбъектМетаданных.ТабличныеЧасти.Товары;
Для Каждого Реквизит Из ТабЧасть.Реквизиты Цикл
Сообщить(Реквизит.Имя + " | " + Реквизит.Синоним + " | " + Строка(Реквизит.Тип));
КонецЦикла;
У каждого реквизита доступны свойства Имя, Синоним, Тип, Комментарий. Тип можно анализировать дальше — например, проверять, содержит ли колонка ссылку на справочник, чтобы построить универсальную проверку заполнения.
Учтите: у табличной части есть стандартный реквизит НомерСтроки, который в коллекцию Реквизиты не входит. Если в обработке нужен и он, добавьте его в результирующий список вручную.
Обход колонок таблицы значений
Если табличная часть выгружена в таблицу значений методом Выгрузить(), состав колонок доступен через коллекцию Колонки. Этот вариант удобен, когда данные уже отобраны и нужно, например, построить по ним динамическую форму или текстовую выгрузку с заголовками.
ТЗ = ДокументОбъект.Товары.Выгрузить();
Для Каждого Колонка Из ТЗ.Колонки Цикл
Сообщить(Колонка.Имя + " | " + Колонка.Заголовок);
КонецЦикла;
Коллекция поддерживает поиск по имени — ТЗ.Колонки.Найти("Сумма"), что позволяет проверить наличие колонки перед обращением к ней. Это полезно в универсальных обработках, где структура входной таблицы заранее неизвестна.
Отличие от метаданных принципиально: в таблице значений при выгрузке появляются только те колонки, которые были в табличной части, плюс служебные, если выгрузка выполнялась с параметрами. Синонимов у колонок нет — вместо них свойство Заголовок, которое по умолчанию совпадает с именем.
Обход значений ячеек в строках табличной части
На практике чаще всего требуется не список имён колонок, а сами значения. Классический двойной цикл выглядит так: внешний цикл перебирает строки, внутренний — колонки, а доступ к ячейке выполняется через имя колонки в квадратных скобках.
МетаТЧ = ДокументОбъект.Метаданные().ТабличныеЧасти.Товары;
Для Каждого СтрокаТЧ Из ДокументОбъект.Товары Цикл
Для Каждого Реквизит Из МетаТЧ.Реквизиты Цикл
ЗначениеЯчейки = СтрокаТЧ[Реквизит.Имя];
// обработка значения
КонецЦикла;
КонецЦикла;
Такой подход безопасен: обращение по имени из метаданных гарантированно существует в строке. Обратное неверно — если имя колонки задано строковой константой и в конфигурации его переименуют, код упадёт с ошибкой. Поэтому универсальные обработки всегда берут имена из метаданных или коллекции колонок, а не «зашивают» их в код.
Для таблицы значений схема аналогична: СтрокаТЗ[Колонка.Имя]. Дополнительно у строки таблицы значений нет именованных свойств колонок в виде прямого обращения через точку в некоторых контекстах, поэтому квадратные скобки — надёжный универсальный вариант.
- 1Получите объект метаданных табличной части через Метаданные или Метаданные() объекта
- 2Переберите коллекцию Реквизиты для получения имён колонок
- 3Организуйте цикл по строкам табличной части
- 4Внутри цикла обращайтесь к значениям через Строка[ИмяКолонки]
- 5Проверьте результат на тестовом документе с заполненной табличной частью
Обход колонок табличного поля на форме
Отдельный случай — обход колонок табличной части, отображённой на управляемой форме. Здесь состав видимых колонок определяется элементами формы, а не метаданными: часть реквизитов может быть скрыта, порядок изменён, добавлены вычисляемые поля.
Для перебора элементов-колонок используют коллекцию Элементы формы или подчинённые элементы таблицы формы:
Для Каждого Элемент Из Элементы.Товары.ПодчиненныеЭлементы Цикл
Если ТипЗнч(Элемент) = Тип("ПолеФормы") Тогда
Сообщить(Элемент.ПутьКДанным);
КонецЕсли;
КонецЦикла;
Свойство ПутьКДанным содержит путь вида «Объект.Товары.Номенклатура», из которого извлекается имя колонки. Учитывайте, что на форме могут быть поля-оформления (картинки, флажки), не связанные с данными, — у них ПутьКДанным пустой, такие элементы нужно пропускать.
В обычных формах (толстый клиент, старые конфигурации) колонки табличного поля перебираются через ЭлементыФормы.Товары.Колонки. Если поддерживаете старую конфигурацию, проверьте режим совместимости, прежде чем выбирать синтаксис.
Выбор способа под конкретную задачу
Чтобы не перебирать варианты методом проб, ориентируйтесь на источник данных и цель обработки. Ниже — сопоставление типовых ситуаций и подходящих способов.
| Задача | Способ обхода | Ограничение |
|---|---|---|
| Получить состав колонок без данных | Метаданные, коллекция Реквизиты | Нет доступа к значениям |
| Обработать выгруженные данные | ТЗ.Колонки | Требуется предварительный Выгрузить() |
| Универсальная обработка любых документов | Метаданные + Строка[Имя] | Медленнее прямого обращения |
| Обойти видимые колонки на форме | ПодчиненныеЭлементы таблицы формы | Зависит от настроек формы |
Сравнение вариантов
Подходит для универсальных процедур и проверок структуры. Не даёт доступа к значениям напрямую.
Удобен для уже выгруженных данных и динамических отчётов. Требует памяти на копию таблицы.
Единственный способ узнать, что реально видит пользователь. Работает только в контексте формы.
Производительность и типичные ошибки
Двойной цикл «строки × колонки» на больших табличных частях (тысячи строк) работает заметно медленнее, чем обращение к конкретным колонкам по имени. Если обрабатывать нужно только две-три известные колонки, не стройте универсальный обход — обратитесь к ним напрямую.
Частые ошибки при обходе колонок:
- Обращение
СтрокаТЧ.ИмяКолонкис именем, которого нет в реквизитах, — возникает ошибка «Поле объекта не обнаружено». Проверяйте наличие через метаданные илиТЗ.Колонки.Найти(). - Попытка перебрать
Реквизитыу таблицы значений — у неё такой коллекции нет, толькоКолонки. - Использование
Выгрузить()внутри цикла по строкам — каждый вызов создаёт полную копию таблицы, что резко снижает производительность. - Изменение состава колонок таблицы значений внутри цикла по этим же колонкам — коллекция изменяется во время итерации, что приводит к пропускам или ошибкам.
Ещё один риск связан с правами: если у пользователя нет права просмотра отдельных реквизитов, обход через метаданные их всё равно покажет, а вот чтение значений в отдельных сценариях может быть ограничено на уровне RLS. Тестируйте универсальные обработки под целевой ролью, а не под полными правами.
Проверка результата
После реализации обхода убедитесь, что количество обработанных колонок совпадает с ожидаемым. Простой способ — вывести счётчик итераций внутреннего цикла и сравнить его с МетаТЧ.Реквизиты.Количество(). Расхождение означает, что часть колонок пропущена или обработана дважды.
Для проверки обхода значений откройте тестовый документ с заполненной табличной частью и выведите пары «имя колонки — значение» через Сообщить() или в табличный документ. Пустые значения Неопределено в таблице значений — признак того, что колонка существует, но данные в неё не выгружались или имеют составной тип.
Как проверить результат
Равно количеству реквизитов табличной части
Меньше — колонки пропущены, больше — задвоение обработки
Соответствуют данным документа
Неопределено или пустые строки там, где данные есть
Обработка завершается без ошибок доступа
Ошибки прав при чтении отдельных реквизитов
Что важно запомнить
Состав колонок табличной части берут из метаданных (Реквизиты), у таблицы значений — из коллекции Колонки, а видимые на форме поля — из подчинённых элементов таблицы формы. Доступ к значению ячейки универсально выполняется через Строка[ИмяКолонки]. Универсальные обходы медленнее прямых обращений и требуют проверки на копии базы.
Частые вопросы
Как узнать количество колонок табличной части программно?
Через метаданные: Метаданные.Документы.ИмяДокумента.ТабличныеЧасти.ИмяТЧ.Реквизиты.Количество(). Если данные выгружены в таблицу значений — ТЗ.Колонки.Количество(). Учтите, что стандартный реквизит НомерСтроки в эту коллекцию не входит.
Можно ли обойти колонки табличной части всех документов сразу?
Да. Переберите Метаданные.Документы, у каждого документа — коллекцию ТабличныеЧасти, а внутри неё — Реквизиты. Так строят универсальные обработки поиска данных по всей конфигурации.
Как проверить, существует ли колонка с нужным именем?
У таблицы значений используйте ТЗ.Колонки.Найти("ИмяКолонки") — метод вернёт колонку или Неопределено. Для табличной части объекта проверку выполняют через метаданные: МетаТЧ.Реквизиты.Найти("ИмяКолонки").
Почему обращение СтрокаТЧ.Колонка выдаёт ошибку, хотя колонка есть?
Чаще всего имя указано с опечаткой или реквизит переименовали в конфигураторе. Реже — код обращается к строке таблицы значений, куда эта колонка не выгружалась. Сравните имя с коллекцией метаданных или выведите список колонок ТЗ перед обращением.
Как обойти только видимые пользователю колонки на управляемой форме?
Переберите Элементы.ИмяТаблицы.ПодчиненныеЭлементы, отфильтруйте элементы типа ПолеФормы с непустым ПутьКДанным и проверьте свойство Видимость. Имя колонки извлекается из пути к данным после последней точки.
Что быстрее: обход через метаданные или прямое обращение к колонкам?
Прямое обращение к известным колонкам по имени всегда быстрее. Универсальный обход оправдан, когда состав колонок заранее неизвестен или обработка должна работать с разными объектами. Для массовых операций с фиксированными колонками универсальность не нужна.