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

Программист 1С v8.3 (Управляемые формы) 1С:Комплексная автоматизация IT и автоматизация бизнеса
← На главную

При разработке индивидуальных печатных форм в конфигурациях на базе Библиотеки стандартных подсистем (включая 1С:Комплексная автоматизация 2, 1С:ERP и 1С:Управление торговлей) часто возникает задача вывести перечень дополнительных реквизитов объекта. Если для документа создано несколько десятков свойств, но в конкретном экземпляре заполнена лишь часть из них, пустые строки выводить на печать не имеет смысла. Разберем детально, как хранятся дополнительные реквизиты и какими способами можно отобрать только заполненные значения.

Особенности хранения дополнительных реквизитов в 1С

Для начала разграничим два понятия подсистемы «Свойства» БСП:

  1. Дополнительные сведения — хранятся отдельно от объекта в независимом регистре сведений ДополнительныеСведения.
  2. Дополнительные реквизиты — хранятся непосредственно внутри самого объекта в его табличной части ДополнительныеРеквизиты.

Табличная часть ДополнительныеРеквизиты документа содержит несколько ключевых реквизитов:

  1. Свойство — ссылка на план видов характеристик ДополнительныеРеквизитыИСведения;
  2. Значение — значение реквизита составного типа Характеристика.ДополнительныеРеквизитыИСведения;
  3. ТекстоваяСтрока — используется для хранения длинных текстовых строк.

Способ 1. Отбор заполненных реквизитов на уровне языка запросов

Разберем, как построить прямой запрос к табличной части документа. Поскольку поле Значение имеет составной тип данных, для корректного отсечения пустых значений в секции ГДЕ необходимо учесть проверку на пустые строки, НЕОПРЕДЕЛЕНО, а также пустые ссылки справочника значений свойств.

Посмотрим на пример текста запроса:


ВЫБРАТЬ
    ДокРеквизиты.Свойство КАК Свойство,
    ВЫБОР
        КОГДА ДокРеквизиты.Свойство.Заголовок <> ""
            ТОГДА ДокРеквизиты.Свойство.Заголовок
        ИНАЧЕ ДокРеквизиты.Свойство.Наименование
    КОНЕЦ КАК ПредставлениеСвойства,
    ВЫБОР
        КОГДА ДокРеквизиты.ТекстоваяСтрока <> ""
            ТОГДА ДокРеквизиты.ТекстоваяСтрока
        ИНАЧЕ ДокРеквизиты.Значение
    КОНЕЦ КАК ЗначениеРеквизита
ИЗ
    Документ.КоммерческоеПредложениеКлиенту.ДополнительныеРеквизиты КАК ДокРеквизиты
ГДЕ
    ДокРеквизиты.Ссылка = &Ссылка
    И НЕ ДокРеквизиты.Свойство.ПометкаУдаления
    И ДокРеквизиты.Значение <> НЕОПРЕДЕЛЕНО
    И ДокРеквизиты.Значение <> ""
    И ДокРеквизиты.Значение <> ЗНАЧЕНИЕ(Справочник.ЗначенияСвойствОбъектов.ПустаяСсылка)
    И ДокРеквизиты.Значение <> ЗНАЧЕНИЕ(Справочник.ЗначенияСвойствОбъектовИерархия.ПустаяСсылка)
УПОРЯДОЧИТЬ ПО
    ДокРеквизиты.Свойство.РеквизитДопУпорядочивания

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

  1. Заголовок реквизита: для вывода пользователю берем поле Свойство.Заголовок, а если оно не заполнено — системное наименование Свойство.Наименование.
  2. Текстовые данные: учитываем поле ТекстоваяСтрока, так как длинный пользовательский текст может сохраняться именно в него.
  3. Порядок следования: упорядочивание по полю Свойство.РеквизитДопУпорядочивания гарантирует, что реквизиты будут выводиться в той же последовательности, которая настроена пользователем в режиме предприятия.

Способ 2. Выборка всех строк и программная фильтрация перед выводом

Если в базе настроены реквизиты со сложными составными типами (ссылки на разные справочники, документы или примитивные типы), отсечь абсолютно все варианты пустых ссылок в одном условии запроса бывает громоздко. В таких ситуациях удобнее выбрать все строки табличной части и применить универсальную платформенную функцию ЗначениеЗаполнено() во встроенном языке.

Рассмотрим пример реализации такого алгоритма:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ДокРеквизиты.Свойство КАК Свойство,
    |	ДокРеквизиты.Свойство.Заголовок КАК Заголовок,
    |	ДокРеквизиты.Свойство.Наименование КАК Наименование,
    |	ДокРеквизиты.Значение КАК Значение,
    |	ДокРеквизиты.ТекстоваяСтрока КАК ТекстоваяСтрока
    |ИЗ
    |	Документ.КоммерческоеПредложениеКлиенту.ДополнительныеРеквизиты КАК ДокРеквизиты
    |ГДЕ
    |	ДокРеквизиты.Ссылка = &Ссылка
    |	И НЕ ДокРеквизиты.Свойство.ПометкаУдаления
    |УПОРЯДОЧИТЬ ПО
    |	ДокРеквизиты.Свойство.РеквизитДопУпорядочивания";

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

Пока Выборка.Следующий() Цикл
    ТекущееЗначение = Выборка.Значение;
    Если ЗначениеЗаполнено(Выборка.ТекстоваяСтрока) Тогда
        ТекущееЗначение = Выборка.ТекстоваяСтрока;
    КонецЕсли;
    
    // Проверяем заполненность любого типа данных
    Если НЕ ЗначениеЗаполнено(ТекущееЗначение) Тогда
        Продолжить;
    КонецЕсли;
    
    // Имя реквизита для макета
    ИмяСвойства = Выборка.Заголовок;
    Если НЕ ЗначениеЗаполнено(ИмяСвойства) Тогда
        ИмяСвойства = Выборка.Наименование;
    КонецЕсли;
    
    ОбластьСтрока.Параметры.ИмяРеквизита = ИмяСвойства;
    ОбластьСтрока.Параметры.ЗначениеРеквизита = ТекущееЗначение;
    ТабличныйДокумент.Вывести(ОбластьСтрока);
КонецЦикла;

Обратите внимание: функция ЗначениеЗаполнено() для булевого типа возвращает Истина в том числе для значения Ложь. Если в печатной форме флаги со значением Ложь выводить не требуется, добавьте явную проверку типа и значения перед выводом строки.

Способ 3. Построение печатной формы на базе СКД

Если печатная форма строится с использованием схемы компоновки данных (СКД), фильтрация пустых реквизитов существенно упрощается:

  1. В наборе данных запроса выбираются поля табличной части ДополнительныеРеквизиты.
  2. В настройках варианта отчета или группировки на вкладке Отбор добавляется стандартное системное условие: Значение Заполнено.
  3. СКД автоматически проверяет заполненность для любых типов данных (включая ссылки и составные типы) и исключает пустые строки из результирующего табличного документа без необходимости ручного написания условий.
← На главную