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