Разработка и Конфигурация · 13 мин
Как вытащить дополнительные реквизиты в 1С запросом
Как получить дополнительные реквизиты и сведения в запросе 1С: соединение с табличными частями, виртуальные таблицы, примеры запросов и типичные ошибки.
Дополнительные реквизиты и дополнительные сведения в типовых конфигурациях 1С хранятся не в самом объекте, а в отдельных таблицах: реквизиты — в табличной части «ДополнительныеРеквизиты» объекта, сведения — в регистре сведений «ДополнительныеСведения». Поэтому простое обращение к полю объекта в запросе не сработает — значение придётся доставать соединением с этими таблицами.
Главная сложность в том, что у одного объекта может быть много дополнительных реквизитов, и каждый хранится отдельной строкой. Если нужно вывести несколько реквизитов в одну строку результата, потребуется либо несколько соединений (по одному на каждый реквизит), либо группировка с агрегацией. Ниже разобраны оба подхода с готовыми текстами запросов.
Материал применим к конфигурациям на базе БСП (Управление торговлей, ERP, Комплексная автоматизация, ЗУП, Бухгалтерия предприятия 3.0 и другие), где механизм дополнительных реквизитов и сведений реализован единообразно.
Где физически хранятся дополнительные реквизиты и сведения
Прежде чем писать запрос, нужно понять, какая из двух сущностей вам нужна — их часто путают. Дополнительный реквизит хранится в табличной части самого объекта (например, Справочник.Номенклатура.ДополнительныеРеквизиты) и состоит из полей «Свойство» и «Значение». Дополнительное сведение хранится в регистре сведений ДополнительныеСведения с измерением «Объект», измерением «Свойство» и ресурсом «Значение».
Ключевая разница для запроса: табличная часть привязана к конкретному виду объектов (номенклатура, контрагенты, партнёры), а регистр сведений универсален — в нём поле «Объект» имеет составной тип и может ссылаться на разные справочники и документы. Поэтому при соединении с регистром важно дополнительно отфильтровать по типу объекта, иначе соединение может «схлопнуть» строки разных сущностей.
Определить, реквизит это или сведение, можно в пользовательском режиме: откройте карточку объекта, найдите нужное поле, затем перейдите в «Администрирование → Общие настройки → Дополнительные реквизиты и сведения». Там видно, в каком наборе находится свойство и к какой группе относится.
Получение ссылки на свойство для отбора в запросе
Чтобы отобрать значения конкретного реквизита, нужно знать ссылку на свойство — элемент плана видов характеристик «ДополнительныеРеквизитыИСведения». Самый надёжный способ — найти свойство по наименованию или по имени, заданному разработчиком, и передать его в запрос параметром.
Пример кода, который получает ссылку на свойство по заголовку:
ЗапросСвойства = Новый Запрос;
ЗапросСвойства.Текст =
"ВЫБРАТЬ
| ДопРеквизиты.Ссылка КАК Свойство
|ИЗ
| ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДопРеквизиты
|ГДЕ
| ДопРеквизиты.Заголовок = &Заголовок";
ЗапросСвойства.УстановитьПараметр("Заголовок", "Производитель");
Результат = ЗапросСвойства.Выполнить().Выбрать();
Если Результат.Следующий() Тогда
Свойство = Результат.Свойство;
КонецЕсли;
Если свойство ищется по наименованию, учтите риск: заголовки могут дублироваться для разных наборов объектов (например, «Цвет» у номенклатуры и у контрагентов). Безопаснее дополнительно отбирать по набору свойств или использовать предопределённое имя, если оно задано в конфигураторе.
Простой запрос: один дополнительный реквизит
Базовый сценарий — вывести список объектов вместе со значением одного реквизита. Для этого достаточно левого соединения с табличной частью объекта с условием на свойство. Условие по свойству обязательно размещается в секции соединения (или в ГДЕ), иначе при нескольких реквизитах у объекта строки задублируются.
ВЫБРАТЬ
Номенклатура.Ссылка КАК Номенклатура,
ДопРеквизиты.Значение КАК Производитель
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК ДопРеквизиты
ПО Номенклатура.Ссылка = ДопРеквизиты.Ссылка
И ДопРеквизиты.Свойство = &Свойство
Левое соединение используется намеренно: если у объекта реквизит не заполнен, строка всё равно попадёт в результат со значением NULL. Это удобно для отчётов, где нужно видеть и незаполненные позиции. Если нужны только объекты с заполненным реквизитом — замените на внутреннее соединение.
Для дополнительного сведения запрос аналогичен, но соединяемся с регистром:
ВЫБРАТЬ
Контрагенты.Ссылка КАК Контрагент,
ДопСведения.Значение КАК Регион
ИЗ
Справочник.Контрагенты КАК Контрагенты
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДопСведения
ПО Контрагенты.Ссылка = ДопСведения.Объект
И ДопСведения.Свойство = &Свойство
Несколько реквизитов в одной строке результата
Когда нужно вывести два-три реквизита рядом, есть два рабочих подхода. Первый — несколько левых соединений с псевдонимами, каждое со своим свойством. Он прост и читабелен, но при большом количестве реквизитов запрос разрастается, а производительность падает из-за множества соединений.
ВЫБРАТЬ
Номенклатура.Ссылка КАК Номенклатура,
Реквизит1.Значение КАК Производитель,
Реквизит2.Значение КАК Страна
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК Реквизит1
ПО Номенклатура.Ссылка = Реквизит1.Ссылка
И Реквизит1.Свойство = &Свойство1
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК Реквизит2
ПО Номенклатура.Ссылка = Реквизит2.Ссылка
И Реквизит2.Свойство = &Свойство2
Второй подход — группировка с агрегацией через ВЫБОР КОГДА. Он удобен, когда реквизитов много или их список формируется динамически:
ВЫБРАТЬ
ДопРеквизиты.Ссылка КАК Номенклатура,
МАКСИМУМ(ВЫБОР
КОГДА ДопРеквизиты.Свойство = &Свойство1
ТОГДА ДопРеквизиты.Значение
КОНЕЦ) КАК Производитель,
МАКСИМУМ(ВЫБОР
КОГДА ДопРеквизиты.Свойство = &Свойство2
ТОГДА ДопРеквизиты.Значение
КОНЕЦ) КАК Страна
ИЗ
Справочник.Номенклатура.ДополнительныеРеквизиты КАК ДопРеквизиты
СГРУППИРОВАТЬ ПО
ДопРеквизиты.Ссылка
Обратите внимание: при группировке в результат попадут только объекты, у которых есть хотя бы один дополнительный реквизит. Если нужны и «пустые» объекты, сделайте это выборку правой таблицей соединения от основного справочника.
Сравнение вариантов
Подходит для 1–3 реквизитов. Запрос прозрачен, легко отлаживать. При большом числе реквизитов становится громоздким и медленным.
Подходит для многих реквизитов и динамических списков. Одно сканирование табличной части. Минус — объекты без реквизитов выпадают из результата без внешнего соединения.
Подходит для отчётов без программирования: СКД умеет автоматически подтягивать доп. реквизиты. Ограничение — меньше контроля над итоговым SQL.
Вывод дополнительных реквизитов в отчёте на СКД
В системе компоновки данных дополнительные реквизиты можно подключить без ручных соединений. В типовых конфигурациях для основных справочников в схеме компоновки доступна группа полей «ДополнительныеРеквизиты» — при добавлении поля из этой группы СКД сама построит соединение с табличной частью.
Если отчёт строится на произвольном запросе, добавьте в схему характеристики: на закладке «Характеристики» конструктора СКД укажите тип значения (ссылка на объект), источник видов характеристик (план видов характеристик «ДополнительныеРеквизитыИСведения») и источник значений (табличная часть или регистр сведений). После этого пользователь сможет выводить и фильтровать по любому доп. реквизиту прямо в настройках отчёта.
Этот способ предпочтителен для пользовательских отчётов: при добавлении нового реквизита в базу он автоматически станет доступен в отчёте без доработки запроса.
- 1Создайте внешний отчёт и откройте схему компоновки данных
- 2Напишите базовый запрос по основному объекту (например, справочнику Номенклатура)
- 3На закладке «Характеристики» добавьте строку: тип — ссылка на объект, виды — ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения, значения — табличная часть ДополнительныеРеквизиты
- 4В настройках отчёта добавьте нужный доп. реквизит в выбранные поля
- 5Сформируйте отчёт и проверьте, что значения совпадают с карточками объектов
Проверка результата и типичные ошибки
После написания запроса проверьте его на контрольном примере: возьмите объект с известными значениями реквизитов и сравните с выводом запроса в консоли запросов. Особое внимание уделите количеству строк — задвоение почти всегда означает, что условие по свойству потерялось или попало не в ту секцию.
Частые ошибки и их последствия:
Отдельная тонкость — тип поля «Значение». В табличной части и в регистре оно имеет составной тип, поэтому сравнение со строкой в отборе может не работать на некоторых СУБД без приведения: используйте ВЫРАЗИТЬ(ДопРеквизиты.Значение КАК Строка(100)) или отбирайте через параметр с явным типом.
Как проверить результат
Равно числу объектов (при левом соединении) или меньше (при внутреннем)
Строк больше, чем объектов — дубли из-за отсутствующего условия по свойству
Совпадают с данными карточки объекта в пользовательском режиме
NULL у объектов с заполненным реквизитом — неверная ссылка на свойство
Присутствуют с пустым значением (для левого соединения)
Пропали — условие по свойству оказалось в секции ГДЕ
Производительность и ограничения механизма
Запросы к табличным частям дополнительных реквизитов на больших базах могут работать медленно: табличная часть сканируется целиком, а соединений бывает несколько. Если отчёт по доп. реквизитам выполняется долго, рассмотрите вариант с группировкой вместо множественных соединений и убедитесь, что в запросе нет соединений по полям составного типа без необходимости.
Ещё одно ограничение: дополнительные реквизиты не участвуют в стандартных индексах объектов, поэтому массовые отборы вида «найти всю номенклатуру, где Производитель = X» всегда будут тяжелее, чем отбор по штатному реквизиту. Если такой отбор нужен постоянно и критичен по скорости, это повод задуматься о переносе свойства в обычный реквизит объекта — но это уже доработка конфигурации со всеми последствиями для обновлений.
Для разовой выгрузки данных удобнее всего использовать консоль запросов (встроенную в режим предприятия через «Все функции» в некоторых конфигурациях или внешнюю обработку): вставляете текст запроса, задаёте параметр свойства и сразу видите таблицу результата, которую можно скопировать в Excel.
Что важно запомнить
Дополнительные реквизиты живут в табличной части объекта, сведения — в регистре ДополнительныеСведения. Отбор всегда идёт по ссылке на свойство из плана видов характеристик. Один реквизит — одно левое соединение; много реквизитов — группировка с МАКСИМУМ(ВЫБОР КОГДА) или характеристики в СКД. Проверяйте результат на дубли строк и потерянные объекты.
Частые вопросы
Чем дополнительный реквизит отличается от дополнительного сведения в запросе?
Реквизит хранится в табличной части конкретного объекта и запрашивается через Справочник.Имя.ДополнительныеРеквизиты. Сведение хранится в общем регистре сведений ДополнительныеСведения, где объект — составное поле. Функционально реквизиты обычно участвуют в отборах и логике, сведения — в справочной информации.
Можно ли отфильтровать объекты по значению дополнительного реквизита?
Да. Добавьте соединение с табличной частью с условием по свойству и в секции ГДЕ проверьте значение, например: ГДЕ ДопРеквизиты.Значение = &ИскомоеЗначение. Если значение строковое, может потребоваться приведение типа через ВЫРАЗИТЬ.
Почему запрос возвращает NULL, хотя реквизит в карточке заполнен?
Чаще всего неверна ссылка на свойство: вы нашли одноимённое свойство из другого набора. Проверьте, что свойство относится именно к нужному виду объектов. Вторая причина — реквизит на самом деле является дополнительным сведением и лежит в регистре, а не в табличной части.
Как вывести дополнительные реквизиты без программирования?
Используйте отчёт на СКД или универсальный отчёт в типовой конфигурации: в настройках отчёта по справочнику или документу дополнительные реквизиты доступны как отдельные поля в группе «Дополнительные реквизиты». Их можно выводить в колонки и использовать в отборах.
Влияет ли большое количество дополнительных реквизитов на скорость запроса?
Да. Каждое соединение с табличной частью увеличивает объём обрабатываемых данных. На больших базах предпочтительнее один проход с группировкой через МАКСИМУМ(ВЫБОР КОГДА) вместо пяти-десяти отдельных соединений, а также отбор объектов до соединения с реквизитами.
Как получить значение дополнительного сведения в коде без запроса?
В конфигурациях на БСП есть программный интерфейс: функция УправлениеСвойствами.ЗначениеСвойства(Объект, Свойство) возвращает значение одним вызовом. Это удобно для точечного чтения, но для списков объектов запрос эффективнее.