При разработке отчетов в системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда пользователь может оставить дату пустой или вовсе снять галочку выбора параметра. В таких случаях отчет должен либо использовать текущую дату, либо игнорировать условие. Однако стандартное поведение системы часто приводит к ошибке "Значение не задано". В этой статье мы подробно разберем, почему это происходит, и рассмотрим несколько способов решения проблемы, включая настройку параметров схемы и программную обработку.
Прежде всего, разберем ситуацию, когда пользователь работает с параметрами в пользовательских настройках. Проанализируем два принципиально разных состояния параметра:
01.01.0001 00:00:00. Ваша проверка в коде запроса через ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0) сработает корректно.&НужнаяДата, а самого параметра в настройках нет, он выдает фатальную ошибку.Для того чтобы избежать этой ошибки, необходимо в схеме СКД на закладке Параметры для нужного параметра установить свойство Использование в значение Всегда. Это гарантирует, что даже если пользователь не выбрал дату, параметр будет инициализирован (хотя бы пустым значением).
Это наиболее элегантный способ, который позволяет избежать сложной логики внутри текста запроса и сохранить производительность виртуальных таблиц. Вместо того чтобы писать ВЫБОР КОГДА прямо в ГДЕ, мы подготовим значение параметра заранее.
Рассмотрим порядок действий:
НужнаяДата.
ВЫБОР
КОГДА &НужнаяДата = ДАТАВРЕМЯ(1, 1, 1) ИЛИ &НужнаяДата ЕСТЬ NULL
ТОГДА ТекущаяДата()
ИНАЧЕ &НужнаяДата
КОНЕЦ
Теперь в самом тексте запроса или в параметрах виртуальной таблицы можно просто использовать &НужнаяДата без дополнительных проверок. Система сама подставит текущий момент времени, если пользователь оставил поле пустым.
Иногда логика заполнения даты зависит от сложных условий, которые трудно описать в выражении СКД. В этом случае воспользуемся событием ПриКомпоновкеРезультата в модуле отчета. Проанализируем этот метод подробнее.
Мы можем перехватить настройки, проверить заполнение и программно установить значение перед тем, как будет сформирован макет компоновки. Пример кода:
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Получаем настройки пользователя
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// Ищем нужный параметр
ПараметрДата = Настройки.ПараметрыДанных.Элементы.Найти("НужнаяДата");
Если ПараметрДата <> Неопределено Тогда
// Если галочка не стоит или дата пустая - ставим текущую
Если Не ПараметрДата.Использование Или ПараметрДата.Значение = '00010101' Тогда
ПараметрДата.Значение = ТекущаяДата();
ПараметрДата.Использование = Истина;
КонецЕсли;
КонецЕсли;
// Далее стандартный вывод отчета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Важный момент: если вы используете программную установку, убедитесь, что параметр в СКД доступен для редактирования пользователю, иначе ваши изменения в настройках могут быть проигнорированы или заменены значениями по умолчанию.
Рассмотрим ситуацию из практики: у вас есть отчет, объединяющий данные из остатков, аренды и документов перемещения. Вы создаете новый параметр &ДатаПрибытия для фильтрации перемещений, но обнаруживаете, что при его использовании перестают работать другие части запроса (например, остатки на дату).
Это происходит потому, что в объединении (ОБЪЕДИНИТЬ ВСЕ) СКД пытается сопоставить параметры для всех веток запроса. Если вы используете стандартный параметр &Период в одной ветке и кастомный &НужнаяДата в другой, система может запутаться в приоритетах фильтрации.
Выясним причину некорректной работы отборов в таких случаях:
Дата, а не СтандартныйПериод. Стандартный период — это объект, содержащий дату начала и дату окончания, его нельзя напрямую сравнивать с реквизитом типа Дата в запросе.РегистрНакопления.Остатки параметр Период критически важен. Если вы наложите фильтр ГДЕ Регистратор.Дата >= &НужнаяДата, но не передадите &НужнаяДата в параметры самой виртуальной таблицы, система сначала получит все остатки на текущий момент, а потом начнет их медленно фильтровать.Для корректной работы объединения нескольких запросов рекомендуется создать один общий параметр типа Дата, который будет программно заполняться актуальным значением (как описано выше), и использовать именно его во всех частях UNION ALL и во всех параметрах виртуальных таблиц. Это обеспечит целостность данных: все части отчета будут строиться на один и тот же момент времени.
Таким образом, комбинируя настройку Использование = Всегда и Выражение в параметрах СКД, вы получите надежный отчет, который не "падает" при пустых значениях и корректно обрабатывает данные даже в сложных объединениях запросов.