Как в запрос отчета 1С добавить параметр и установить его значение?

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

При разработке отчетов на Системе компоновки данных (СКД) часто возникает задача ограничить выборку данных по определенному условию, которое должно быть либо скрыто от пользователя, либо заполняться автоматически. Типичный пример — вывод только определенного типа цен (например, «Розничная») из регистра сведений ЦеныНоменклатуры. Рассмотрим подробнее, как правильно добавить параметр в запрос и какими способами можно установить его значение.

Шаг 1. Оптимальное добавление параметра в запрос

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

Многие начинающие разработчики совершают ошибку, накладывая фильтр в секции ГДЕ. С точки зрения производительности 1С, это неверно. Если мы напишем условие в конце запроса, система сначала получит из базы данных все цены всех видов, а потом начнет их отсеивать. Правильнее передать параметр напрямую в параметры виртуальной таблицы.

Рассмотрим, как должен выглядеть правильный запрос:


ВЫБРАТЬ
    СпрНоменклатура.Ссылка КАК Номенклатура,
    СпрНоменклатура.СтавкаНДС КАК СтавкаНДС,
    СпрНоменклатура.Родитель КАК Группа,
    ЦеныНоменклатурыСрезПоследних.Цена КАК Цена
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ВидЦены = &ВидЦены) КАК ЦеныНоменклатурыСрезПоследних
        ПО СпрНоменклатура.Ссылка = ЦеныНоменклатурыСрезПоследних.Номенклатура
ГДЕ
    СпрНоменклатура.ЭтоГруппа = ЛОЖЬ

В данном примере &ВидЦены — это и есть наш параметр. Обратите внимание, что мы поместили его во второй аргумент функции СрезПоследних. Это заставит СУБД выбрать только нужные записи еще на этапе формирования временной таблицы в памяти сервера.

Шаг 2. Визуальная настройка параметра в СКД без кода

Выясним, как сделать так, чтобы параметр «Вид цены» был всегда равен «Розничная» и пользователь не мог его изменить вручную. Для этого нам не обязательно писать код. Воспользуемся возможностями конструктора схемы компоновки данных:

  1. Перейдем на вкладку «Параметры» в схеме СКД.
  2. Найдем в списке наш параметр ВидЦены.
  3. В колонке «Значение» нажмем на кнопку выбора и выберем конкретный элемент из справочника ВидыЦен (например, «Розничная»).
  4. Установим галочку в колонке «Ограничение доступности».

После этих действий параметр станет «невидимым» для пользователя в настройках отчета, но система будет всегда подставлять в него выбранное нами значение. Это самый простой и надежный способ «зашить» логику в отчет.

Шаг 3. Использование выражений для гибкого поиска

Иногда мы не можем выбрать конкретную ссылку в конфигураторе (например, если база пустая или мы разрабатываем тиражное решение). В этом случае проанализируем использование колонки «Выражение» на той же вкладке «Параметры». Там можно написать небольшой фрагмент кода на языке 1С, который выполнится в момент формирования отчета.

Примеры выражений:

Этот метод позволяет отчету оставаться работоспособным даже при переносе между разными информационными базами, где внутренние идентификаторы (GUID) объектов могут отличаться.

Шаг 4. Программная установка параметра в модуле объекта

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

Разберем пример кода, который устанавливает параметр:


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

КонецПроцедуры

Посмотрим на более лаконичный способ установки значения, который часто применяется в современных конфигурациях:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

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

КонецПроцедуры

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

Шаг 5. Обработка пустых значений (NULL)

Поскольку в исходном запросе используется ЛЕВОЕ СОЕДИНЕНИЕ, может возникнуть ситуация, когда для какой-то номенклатуры цена выбранного вида просто не установлена. В этом случае в колонке «Цена» будет отображаться пустота (значение NULL).

Чтобы отчет выглядел профессионально, проанализируем использование функции ЕСТЬNULL. Изменим поле выбора в запросе следующим образом:

ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена

Теперь вместо пустых ячеек в отчете будут стоять нули, что гораздо понятнее для конечного пользователя.

Резюме

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

← На главную