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