К статье
Практический материал

Разработка и Конфигурация · 10 мин

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

Способы получить все реквизиты справочника 1С: через метаданные, запрос и консоль кода. Примеры на встроенном языке, типичные ошибки и проверка результата.

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

Правильный подход — обращаться к объекту метаданных справочника. Через него доступны имена, синонимы, типы и длины всех реквизитов без привязки к конкретной конфигурации. Дополнительно реквизиты можно получить через запрос с обходом по полям или через построитель запроса, если нужна не только структура, но и данные.

Ниже разобраны основные способы: перебор метаданных, получение реквизитов объекта, работа через запрос и построитель, а также особенности стандартных и табличных частей. Примеры приведены на встроенном языке 1С и подходят для версий платформы 8.3.

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

Основной и самый надёжный способ — коллекция реквизитов объекта метаданных. Каждый справочник в дереве метаданных имеет свойство Реквизиты, которое содержит описания всех реквизитов, созданных в конфигураторе. Перебор коллекции выполняется обычным циклом:

МетаСпр = Метаданные.Справочники.Номенклатура;

Для Каждого Реквизит Из МетаСпр.Реквизиты Цикл

Сообщить(Реквизит.Имя + " | " + Реквизит.Синоним + " | " + Реквизит.Тип);

КонецЦикла;

У каждого элемента коллекции доступны свойства: Имя — идентификатор реквизита, Синоним — представление для пользователя, Тип — описание типов значения, Длина и Точность для строк и чисел. Если реквизит составного типа, уточнить состав можно через Реквизит.Тип.Типы(), который вернёт массив допустимых типов.

Если имя справочника заранее неизвестно и приходит параметром, обращайтесь по строке: Метаданные.Справочники[ИмяСправочника]. Перед обращением стоит проверить существование объекта через Метаданные.Справочники.Найти(ИмяСправочника) — иначе при опечатке в имени код завершится ошибкой.

bsl
МетаСпр = Метаданные.Справочники.Найти(ИмяСправочника);
Если МетаСпр <> Неопределено Тогда
    Для Каждого Реквизит Из МетаСпр.Реквизиты Цикл
        Сообщить(Реквизит.Имя);
    КонецЦикла;
КонецЕсли;

Стандартные реквизиты справочника

Реквизиты, заданные в конфигураторе, — не полный список. У каждого справочника есть стандартные реквизиты, которые платформа создаёт автоматически: Ссылка, Код, Наименование, Владелец (для подчинённых), Родитель (для иерархических), ПометкаУдаления, Предопределенный и другие. Они хранятся в отдельной коллекции СтандартныеРеквизиты.

Для Каждого СтандРеквизит Из МетаСпр.СтандартныеРеквизиты Цикл

Сообщить(СтандРеквизит.Имя);

КонецЦикла;

Набор стандартных реквизитов зависит от настроек справочника. Если справочник не подчинённый, реквизита Владелец в коллекции не будет; если отключена иерархия — не будет Родителя. Поэтому универсальный код должен перебирать коллекцию, а не обращаться к конкретным именам напрямую.

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

Реквизиты табличных частей

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

Для Каждого ТЧ Из МетаСпр.ТабличныеЧасти Цикл

Сообщить("Табличная часть: " + ТЧ.Имя);

Для Каждого Реквизит Из ТЧ.Реквизиты Цикл

Сообщить(" " + Реквизит.Имя + " (" + Реквизит.Тип + ")");

КонецЦикла;

КонецЦикла;

У табличных частей тоже есть стандартные реквизиты — как минимум НомерСтроки и Ссылка. При выгрузке данных это учитывают, чтобы не смешивать поля шапки и строк табличной части в одну плоскую структуру.

Получение реквизитов через запрос

Когда нужны не только имена, но и значения реквизитов, используют запрос. Простой вариант — выбрать все поля конструкцией ВЫБРАТЬ *, однако в явном виде список реквизитов из такого запроса не извлечь. Для анализа структуры результата служит коллекция колонок результата запроса:

Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1 * ИЗ Справочник.Номенклатура");

Результат = Запрос.Выполнить().Выгрузить();

Для Каждого Колонка Из Результат.Колонки Цикл

Сообщить(Колонка.Имя + " | " + Колонка.ТипЗначения);

КонецЦикла;

Этот способ удобен тем, что возвращает сразу типы значений в виде объекта ОписаниеТипов и учитывает виртуальные поля. Минус — запрос фактически обращается к базе данных, что на больших таблицах даёт лишнюю нагрузку, поэтому ограничение ПЕРВЫЕ 1 обязательно.

Сравнение способов

Метаданные.Реквизиты

Подходит для анализа структуры без обращения к данным; не включает стандартные реквизиты в основной коллекции

Запрос ВЫБРАТЬ *

Даёт полный набор полей с типами значений, но требует обращения к базе

Построитель запроса

Позволяет и прочитать состав полей, и динамически сформировать запрос по ним; сложнее в коде

Использование построителя запроса

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

Построитель = Новый ПостроительЗапроса("ВЫБРАТЬ * ИЗ Справочник.Номенклатура");

Построитель.ЗаполнитьНастройки();

Для Каждого Поле Из Построитель.ДоступныеПоля Цикл

Сообщить(Поле.Имя + " | " + Поле.ТипЗначения);

КонецЦикла;

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

Реквизиты конкретного объекта в режиме предприятия

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

МетаОбъект = СсылкаНаЭлемент.Метаданные();

Для Каждого Реквизит Из МетаОбъект.Реквизиты Цикл

Значение = СсылкаНаЭлемент[Реквизит.Имя];

Сообщить(Реквизит.Имя + " = " + Значение);

КонецЦикла;

Обращение к значению реквизита по имени выполняется через квадратные скобки — это ключевой приём универсального кода. Учтите: чтение реквизитов через ссылку вызывает обращение к базе на каждый элемент, поэтому в циклах по большому числу элементов эффективнее один запрос, выбирающий нужные поля пакетно.

Типичные ошибки и проверка результата

Самая частая ошибка — ожидание, что коллекция Реквизиты содержит Код и Наименование. Их там нет: это стандартные реквизиты, и код молча «теряет» ключевые поля. Вторая типичная проблема — обращение к Метаданные.Справочники.Имя по строке без проверки существования, что приводит к падению обработки при переименовании объекта в конфигурации.

Ещё одна ошибка — игнорирование функциональных опций. Если реквизит отключён функциональной опцией, он остаётся в метаданных, но в интерфейсе и ряде механизмов недоступен. Для проверки используйте ПолучитьФункциональнуюОпцию или проверку через объект метаданных функциональной опции.

Типичные ошибки
01
Перебор только коллекции Реквизиты без СтандартныеРеквизиты — в выгрузку не попадают Код и Наименование
02
Обращение к справочнику по имени без Метаданные.Справочники.Найти — ошибка выполнения при опечатке или переименовании
03
Чтение значений реквизитов через ссылку в цикле — резкое падение производительности
04
Игнорирование реквизитов табличных частей при полной выгрузке структуры

Проверить результат просто: выведите список полученных реквизитов и сравните его с закладкой «Данные» в конфигураторе для этого справочника. Количество и имена должны совпадать с учётом стандартных реквизитов и табличных частей.

Контрольные точки

Как проверить результат

Список реквизитов из кода
Норма

Совпадает с закладкой «Данные» в конфигураторе

Тревожный признак

Отсутствуют поля — вероятно, не перебраны стандартные реквизиты или табличные части

Типы реквизитов
Норма

Составные типы показывают все допустимые значения

Тревожный признак

Выводится только первый тип составного реквизита

Производительность
Норма

Один запрос на пакет элементов

Тревожный признак

Обращение к базе на каждый элемент в цикле

Частые вопросы

Как получить реквизиты справочника, если известно только его имя в виде строки?

Используйте индексированное обращение: Метаданные.Справочники[ИмяСправочника]. Перед этим желательно проверить существование через Метаданные.Справочники.Найти(ИмяСправочника), чтобы избежать ошибки выполнения при неверном имени.

Почему в коллекции Реквизиты нет полей Код и Наименование?

Это стандартные реквизиты, которые платформа хранит в отдельной коллекции СтандартныеРеквизиты объекта метаданных. Для полного списка полей перебирайте обе коллекции.

Можно ли получить список реквизитов без программирования?

Да. В конфигураторе откройте справочник и перейдите на закладку «Данные» — там перечислены все реквизиты и табличные части. Также список полей виден в консоли запросов при выборе таблицы справочника.

Как узнать тип значения конкретного реквизита?

Через метаданные: Реквизит.Тип возвращает объект ОписаниеТипов. Для составного типа метод Типы() вернёт массив всех допустимых типов, а свойства Длина и Точность уточнят параметры строк и чисел.

Учитываются ли дополнительные реквизиты (БСП) в коллекции Реквизиты?

Нет. Дополнительные реквизиты и сведения из библиотеки стандартных подсистем хранятся в отдельных таблицах и не входят в метаданные справочника. Их получают через механизмы БСП, например через наборы свойств в справочнике наборов дополнительных реквизитов.

Что быстрее: метаданные или запрос с ВЫБРАТЬ *?

Метаданные. Обращение к коллекции Реквизиты не затрагивает базу данных и выполняется мгновенно. Запрос используют, когда помимо структуры нужны сами значения или типы в виде ОписаниеТипов результата.

Итог

Что важно запомнить

Все реквизиты справочника получают через Метаданные.Справочники.Имя.Реквизиты, стандартные поля — через СтандартныеРеквизиты, реквизиты табличных частей — отдельно. Для данных используйте запрос, для массовой обработки избегайте чтения реквизитов через ссылку в цикле.