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