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

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом Управленческий учет
← На главную

При разработке отчетов на базе Системы компоновки данных (СКД) часто возникает задача: предоставить пользователю возможность выбирать период (например, ДатаПриказа) через удобный интерфейс СтандартныйПериод. Однако стандартное поведение СКД таково, что если параметры начала и окончания периода используются в запросе в секции ГДЕ, система ожидает их обязательного заполнения. Если пользователь оставляет период пустым, система подставляет в запрос пустые даты (01.01.0001), что приводит к отсутствию данных в результате отчета. Проанализируем, как реализовать логику, при которой отбор применяется только при заполненном периоде, а в противном случае — игнорируется.

Метод 1. Использование расширения языка запросов (фигурные скобки)

Рассмотрим наиболее правильный и "нативный" способ решения задачи в рамках СКД. Чтобы условие в запросе стало необязательным, его необходимо поместить в фигурные скобки {}. Это указывает системе, что данный фрагмент кода должен включаться в итоговый SQL-запрос только тогда, когда пользователь установил соответствующий отбор в настройках.

Для реализации этого метода выполним следующие шаги:

  1. В конструкторе запроса на закладке "Компоновка данных" перейдем в раздел "Условия".
  2. Добавим наше поле ДатаПриказа в список доступных полей для отбора.
  3. В тексте запроса это будет выглядеть примерно так:

ВЫБРАТЬ
    ФактическиеОтпуска.Сотрудник,
    ФактическиеОтпуска.Регистратор.Дата КАК ДатаПриказа
ИЗ
    РегистрНакопления.ФактическиеОтпускаСотрудников КАК ФактическиеОтпуска
{ГДЕ
    (ФактическиеОтпуска.Регистратор.Дата >= &НачалоПериода 
     И ФактическиеОтпуска.Регистратор.Дата <= &КонецПериода)}

Проанализируем работу этого механизма: если параметры &НачалоПериода и &КонецПериода не будут задействованы или заполнены (при правильной настройке связей), СКД просто исключит секцию ГДЕ из финального запроса к базе данных.

Метод 2. Проверка заполнения параметров в тексте запроса

Если по каким-то причинам использование фигурных скобок неудобно, мы можем применить логическую проверку на "пустую дату" прямо в условии ГДЕ. Это классический прием, позволяющий сделать фильтр "прозрачным", если параметры не заданы. Выясним, как это выглядит на практике:


ГДЕ 
    (&НачалоПериода = ДАТАВРЕМЯ(1, 1, 1) ИЛИ &КонецПериода = ДАТАВРЕМЯ(1, 1, 1)
    ИЛИ (ДатаПриказа МЕЖДУ &НачалоПериода И &КонецПериода))

В данном случае, если пользователь не указал период, условие по первой части (проверка на пустую дату) вернет ИСТИНА для всех строк, и отчет сформируется без ограничений по дате. Важно: этот метод может незначительно снизить производительность на очень больших таблицах из-за использования оператора ИЛИ, который мешает оптимизатору СУБД эффективно использовать индексы.

Метод 3. Связка параметров и использование СтандартногоПериода

Посмотрим, как правильно настроить параметры на закладке "Параметры" в схеме компоновки данных, чтобы пользователю было удобно работать. Создадим параметр ПериодДатыПриказа с типом СтандартныйПериод.

Для внутренних параметров НачалоПериода и КонецПериода, которые используются в запросе, пропишем выражения:

Чтобы отбор стал действительно необязательным, у основных параметров (начало и конец) в колонке "Использование" установим значение "Авто". Также полезно установить флаг "Ограничение доступности", чтобы пользователь видел в настройках только один общий параметр ПериодДатыПриказа, а не три отдельных поля.

Метод 4. Программная установка использования параметров

В некоторых сложных случаях, когда логика включения отбора зависит от нескольких условий, можно прибегнуть к написанию кода в модуле отчета. Рассмотрим процедуру ПриКомпоновкеРезультата. Мы можем проверить, заполнен ли пользователем период, и программно включить или выключить использование параметров данных.

Разберем пример кода для управления использованием параметров:


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

    // Далее выполняем стандартную компоновку с обновленными настройками
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(Результат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Метод 5. Свойства пользовательских настроек (без кода)

Проанализируем еще один вариант, который часто упускают из виду. В СКД можно вынести отбор по полю ДатаПриказа непосредственно в пользовательские настройки. Для этого:

  1. На закладке "Настройки" перейдем на вкладку "Отбор".
  2. Добавим поле ДатаПриказа, выберем вид сравнения "В периоде".
  3. Нажмем правую кнопку мыши на этом элементе и выберем "Свойства элемента пользовательских настроек".
  4. Установим флаг "Включать в пользовательские настройки".
  5. Режим редактирования выберем "Непосредственно".

При такой настройке пользователь будет видеть галочку рядом с периодом. Если галочка снята — СКД автоматически игнорирует этот отбор при генерации запроса. Это самый быстрый способ сделать любой фильтр отключаемым без написания кода и сложных манипуляций с параметрами запроса.

Резюме

Мы рассмотрели различные подходы к созданию необязательного отбора по периоду. Подведем итог: если вам нужно максимально быстрое и простое решение — используйте свойства пользовательских настроек отбора. Если же логика требует жесткой привязки к параметрам запроса, оптимальным выбором станет использование фигурных скобок в тексте запроса или проверка на пустую дату. Программный метод стоит использовать только в тех случаях, когда условия включения отбора крайне сложны и не поддаются описанию на языке выражений СКД.

← На главную