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