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