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

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

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

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

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

Задача получить список реквизитов документа возникает при разработке обменов, печатных форм, отчётов и универсальных обработок. В зависимости от ситуации нужен либо быстрый просмотр состава объекта в конфигураторе, либо программное получение реквизитов через объект «Метаданные», либо выборка значений реквизитов конкретного документа запросом. Каждый способ решает свою задачу и имеет ограничения.

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

Что входит в состав реквизитов документа

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

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

Просмотр реквизитов в конфигураторе без программирования

Если нужно просто посмотреть состав документа, откройте конфигуратор, найдите в дереве объектов ветку «Документы» и разверните нужный вид документа. Внутри будут узлы «Реквизиты» и «Табличные части». Двойной клик по реквизиту открывает палитру свойств с типом, длиной, признаками обязательности и индексирования.

Для быстрого поиска по всей конфигурации удобна команда «Правка → Глобальный поиск» (Ctrl+Shift+F) по имени реквизита. Если конфигурация закрыта для редактирования (типовая на поддержке), просмотр состава всё равно доступен — ограничение касается только изменения объектов.

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

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

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

МетаДок = Метаданные.Документы.РеализацияТоваровУслуг;

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

Сообщить("Стандартный: " + Реквизит.Имя);

КонецЦикла;

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

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

КонецЦикла;

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

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

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

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

КонецЦикла;

КонецЦикла;

Если имя документа заранее неизвестно (универсальная обработка), объект метаданных получают по ссылке на конкретный документ: МетаДок = СсылкаНаДокумент.Метаданные();. Это безопаснее, чем обращение по строковому имени, и работает для любого вида документов.

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

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

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

Когда нужны не описания, а данные, есть два рабочих варианта. Первый — чтение через объект: получить ДокументОбъект методом Ссылка.ПолучитьОбъект() и обращаться к реквизитам по именам. Способ простой, но загружает в память весь объект со всеми табличными частями, что медленно при пакетной обработке.

Второй вариант — запрос. Он быстрее и позволяет выбрать только нужные поля:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| РеализацияТоваровУслуг.Номер,

| РеализацияТоваровУслуг.Дата,

| РеализацияТоваровУслуг.Контрагент,

| РеализацияТоваровУслуг.СуммаДокумента

|ИЗ

| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

|ГДЕ

| РеализацияТоваровУслуг.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);

Выборка = Запрос.Выполнить().Выбрать();

Для универсального кода, где состав полей неизвестен заранее, текст запроса собирают динамически, перебирая реквизиты метаданных и подставляя их имена в секцию ВЫБРАТЬ. При составном типе реквизита обращение к полям ссылочного значения («через точку») может вернуть NULL для несовпадающих типов — это нормальное поведение платформы.

Выбор способа под задачу

Разные сценарии требуют разных инструментов, и неверный выбор оборачивается лишней работой или проблемами производительности.

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

Конфигуратор

Подходит для разового просмотра состава объекта. Не даёт данных и не работает в режиме Предприятие.

Метаданные в коде

Для универсальных обработок, обменов и динамических форм. Возвращает только описание структуры, без значений.

ДокументОбъект

Простое чтение значений одного документа. Медленный при массовой обработке, грузит всё целиком.

Запрос

Быстрая выборка значений нужных полей у множества документов. Требует знания имён полей или динамической сборки текста.

Маршрут решения

Как выбрать действие

Нужно один раз посмотреть, какие реквизиты есть у документаОткройте объект в конфигураторе, узлы «Реквизиты» и «Табличные части»
Пишете универсальную обработку для любых документовОбходите коллекции СтандартныеРеквизиты, Реквизиты и ТабличныеЧасти через Метаданные
Нужно выгрузить значения реквизитов тысяч документовИспользуйте запрос с явным перечнем полей, не ПолучитьОбъект()
Нужны и структура, и значения (например, выгрузка в XML)Сначала получите состав через метаданные, затем читайте значения по именам реквизитов

Типичные ошибки и ограничения

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

Вторая группа ошибок связана с правами и контекстом. Пользователь без прав на документ не получит данные ни запросом, ни объектом — платформа вернёт пустой результат или ошибку доступа. На клиенте (тонкий клиент без вызова сервера) объект Метаданные доступен, но запросы и ПолучитьОбъект() выполняются только на сервере.

Типичные ошибки
01
Забыть про СтандартныеРеквизиты — в выгрузку не попадут Номер, Дата и Проведен
02
Игнорировать табличные части — реквизиты строк товаров останутся за пределами списка
03
Использовать ПолучитьОбъект() в цикле по тысячам документов — резкое падение производительности
04
Обращаться к реквизиту по синониму вместо имени — синоним может меняться и дублироваться
05
Не учитывать составной тип — обращение «через точку» к полю несовпадающего типа даёт NULL

Проверка результата и практические приёмы

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

Полезный приём для отладки — выгрузить описание реквизитов в таблицу значений с колонками «Имя», «Синоним», «Тип», «Обязательный» и показать её пользователю или сохранить в файл. Такой список удобно согласовывать с постановщиком задачи перед разработкой обмена.

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

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

Полнота списка
Норма

Число прикладных реквизитов совпадает с конфигуратором

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

Реквизиты «потерялись» — проверьте, не забыты ли стандартные или табличные части

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

Строка(Реквизит.Тип) показывает ожидаемый тип или перечень типов

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

Тип не определён или пустой — проверьте составной тип через Тип.Типы()

Значения запроса
Норма

Запрос вернул строки с заполненными полями

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

Пустой результат — проверьте параметр Ссылка и права доступа

Итог

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

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

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

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

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

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

Да, через внешнюю обработку с кодом обхода метаданных или через функцию «Все функции → Стандартные → Структура хранения базы данных» при включённом режиме технического специалиста. Прав на конфигуратор для этого не требуется.

Почему в коллекции Реквизиты нет полей «Номер» и «Дата»?

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

Как узнать тип реквизита, если он составной?

Свойство Тип возвращает объект «ОписаниеТипов». Метод Типы() вернёт массив всех типов, входящих в состав, а свойства КвалификаторыСтроки и КвалификаторыЧисла — длину и точность для примитивных типов.

Что быстрее: запрос или ПолучитьОбъект() для чтения реквизитов?

Запрос. Он читает только указанные поля напрямую из таблицы, тогда как ПолучитьОбъект() загружает документ целиком со всеми табличными частями и создаёт полноценный объект в памяти. Для массовой обработки разница по времени может быть многократной.

Как выгрузить список реквизитов всех документов конфигурации сразу?

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