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

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

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

Разбор типичной ошибки обращения к метаданным

Первоначальная попытка кода, которая приводит к ошибке, обычно выглядит так:


Для каждого Реквизит из Источник.Метаданные().ТабличныеЧасти.Реквизиты Цикл
    // Код обработки
КонецЦикла;

Разберем причину неудачи. Свойство ТабличныеЧасти возвращает объект типа КоллекцияОбъектовМетаданных. Эта коллекция содержит в себе описания всех табличных частей, определенных для данного объекта (документа, справочника и т.д.). У самой коллекции нет свойства Реквизиты. Это свойство есть только у конкретного элемента данной коллекции — то есть у конкретной табличной части.

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

Решение 1: Обращение к конкретной табличной части

Если нам заранее известно имя табличной части, к которой мы хотим обратиться, мы можем указать её напрямую. Рассмотрим пример, где мы получаем данные реквизитов для табличной части с именем Товары:


// Обращаемся к конкретной табличной части по имени
МетаданныеТЧ = Источник.Метаданные().ТабличныеЧасти.Товары;

Для каждого Реквизит Из МетаданныеТЧ.Реквизиты Цикл
    Сообщить("Имя реквизита: " + Реквизит.Имя);
    Сообщить("Тип реквизита: " + Строка(Реквизит.Тип));
КонецЦикла;

В данном случае Реквизит.Тип возвращает объект ОписаниеТипов, который при приведении к строке покажет все допустимые типы данных для этого поля.

Решение 2: Универсальный обход всех табличных частей и их реквизитов

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

  1. Внешним циклом перебираем все табличные части объекта через коллекцию ТабличныеЧасти.
  2. Для каждой найденной табличной части запускаем внутренний цикл по её коллекции Реквизиты.

Посмотрим на программную реализацию этого метода:


// Перебор всех табличных частей объекта
Для Каждого ТекущаяТЧ Из Источник.Метаданные().ТабличныеЧасти Цикл
    
    Сообщить("--- Анализируем табличную часть: " + ТекущаяТЧ.Имя + " ---");
    
    // Перебор всех пользовательских реквизитов в текущей ТЧ
    Для Каждого ТекущийРеквизит Из ТекущаяТЧ.Реквизиты Цикл
        
        ТекстСообщения = СтрШаблон("Поле: %1, Тип: %2", 
            ТекущийРеквизит.Имя, 
            ТекущийРеквизит.Тип);
        Сообщить(ТекстСообщения);
        
    КонецЦикла;
    
КонецЦикла;

Важные нюансы работы с метаданными ТЧ

При работе с метаданными важно помнить о нескольких технических особенностях, которые расширяют возможности разработчика:

1. Стандартные реквизиты. Обратите внимание, что в коллекции Реквизиты находятся только те поля, которые были созданы вручную в конфигураторе. Однако у каждой табличной части есть системные поля, такие как НомерСтроки. Если вам нужно получить доступ к ним, используйте коллекцию СтандартныеРеквизиты.

2. Работа с типами данных. Свойство Реквизит.Тип — это не просто строка, а объект ОписаниеТипов. С его помощью можно проверять наличие определенных типов. Например, выясним, может ли реквизит хранить ссылку на справочник контрагентов:


Если ТекущийРеквизит.Тип.СодержитТип(Тип("СправочникСсылка.Контрагенты")) Тогда
    Сообщить("Это поле может содержать ссылку на контрагента");
КонецЕсли;

3. Получение значений данных по имени из метаданных. Если вы получили имя реквизита из метаданных в виде строки, вы можете динамически обращаться к значениям в строках табличной части объекта. Рассмотрим пример:


// Предположим, у нас есть строка данных ТЧ
Для Каждого СтрокаДанных Из Источник.Товары Цикл
    ИмяПоля = "Количество"; // Имя получено из метаданных
    Значение = СтрокаДанных[ИмяПоля]; 
    // Теперь в переменной Значение лежит реальное число из строки
КонецЦикла;

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

Рекомендации по отладке

Выясним причину, почему иногда сложно сразу написать правильный путь к свойству. В 1С объекты метаданных имеют сложную иерархию. Чтобы не ошибиться в синтаксисе, рекомендуем активно использовать Отладчик.

Разберем, как это сделать: установите точку останова в коде, вызовите окно «Вычислить выражение» (Shift+F9) и введите Источник.Метаданные(). Раскрывая дерево свойств, вы наглядно увидите, какие коллекции вложены друг в друга. Это позволит безошибочно определить, где заканчивается коллекция табличных частей и начинается описание конкретного реквизита.

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

← На главную