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