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