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

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

При разработке отчетов в системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда пользователь может оставить дату пустой или вовсе снять галочку выбора параметра. В таких случаях отчет должен либо использовать текущую дату, либо игнорировать условие. Однако стандартное поведение системы часто приводит к ошибке "Значение не задано". В этой статье мы подробно разберем, почему это происходит, и рассмотрим несколько способов решения проблемы, включая настройку параметров схемы и программную обработку.

Причина ошибки «Значение не задано»

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

  1. Параметр выбран (стоит галочка), но значение пустое: В этом случае в запрос передается пустая дата 01.01.0001 00:00:00. Ваша проверка в коде запроса через ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0) сработает корректно.
  2. Параметр не выбран (галочка снята): В этом случае параметр вообще не передается в компоновщик макета. Когда движок СКД встречает в тексте запроса обращение к &НужнаяДата, а самого параметра в настройках нет, он выдает фатальную ошибку.

Для того чтобы избежать этой ошибки, необходимо в схеме СКД на закладке Параметры для нужного параметра установить свойство Использование в значение Всегда. Это гарантирует, что даже если пользователь не выбрал дату, параметр будет инициализирован (хотя бы пустым значением).

Решение 1: Использование выражений в схеме СКД

Это наиболее элегантный способ, который позволяет избежать сложной логики внутри текста запроса и сохранить производительность виртуальных таблиц. Вместо того чтобы писать ВЫБОР КОГДА прямо в ГДЕ, мы подготовим значение параметра заранее.

Рассмотрим порядок действий:

  1. Переходим на закладку Параметры в СКД.
  2. Находим наш пользовательский параметр, например, НужнаяДата.
  3. В колонке Выражение прописываем условие:

ВЫБОР 
    КОГДА &НужнаяДата = ДАТАВРЕМЯ(1, 1, 1) ИЛИ &НужнаяДата ЕСТЬ NULL 
    ТОГДА ТекущаяДата() 
    ИНАЧЕ &НужнаяДата 
КОНЕЦ

Теперь в самом тексте запроса или в параметрах виртуальной таблицы можно просто использовать &НужнаяДата без дополнительных проверок. Система сама подставит текущий момент времени, если пользователь оставил поле пустым.

Решение 2: Программная установка в модуле отчета

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

Мы можем перехватить настройки, проверить заполнение и программно установить значение перед тем, как будет сформирован макет компоновки. Пример кода:


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

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

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

Проблема объединения запросов и общих параметров

Рассмотрим ситуацию из практики: у вас есть отчет, объединяющий данные из остатков, аренды и документов перемещения. Вы создаете новый параметр &ДатаПрибытия для фильтрации перемещений, но обнаруживаете, что при его использовании перестают работать другие части запроса (например, остатки на дату).

Это происходит потому, что в объединении (ОБЪЕДИНИТЬ ВСЕ) СКД пытается сопоставить параметры для всех веток запроса. Если вы используете стандартный параметр &Период в одной ветке и кастомный &НужнаяДата в другой, система может запутаться в приоритетах фильтрации.

Выясним причину некорректной работы отборов в таких случаях:

Для корректной работы объединения нескольких запросов рекомендуется создать один общий параметр типа Дата, который будет программно заполняться актуальным значением (как описано выше), и использовать именно его во всех частях UNION ALL и во всех параметрах виртуальных таблиц. Это обеспечит целостность данных: все части отчета будут строиться на один и тот же момент времени.

Таким образом, комбинируя настройку Использование = Всегда и Выражение в параметрах СКД, вы получите надежный отчет, который не "падает" при пустых значениях и корректно обрабатывает данные даже в сложных объединениях запросов.

← На главную