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

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

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

Способ 1. Использование выражения в схеме компоновки данных

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

Если нам нужно, чтобы параметр &ВидЦены всегда принимал значение конкретного элемента справочника «Виды цен» с названием «Закупочная», мы можем прописать код прямо в этой колонке. Система исполнит этот код на встроенном языке 1С перед выполнением запроса.

Пример выражения для параметра:

Справочники.ВидыЦен.НайтиПоНаименованию("Закупочная")

Важные моменты при использовании выражений:

  1. Если вы используете этот способ, установите галочку Ограничение доступности. Это скроет параметр от пользователя, и он не сможет случайно изменить значение, которое вы жестко задали в схеме.
  2. Помните, что поиск по наименованию считается «хрупким» решением. Если пользователь переименует «Закупочную» в «Закупочная цена», поиск вернет пустую ссылку.
  3. Если параметр должен рассчитываться относительно текущей даты, в выражении можно использовать функции ТекущаяДата(), КонецПериода() или ДобавитьКДате().

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

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

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


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

Обратите внимание на использование метода УстановитьЗначениеПараметра. Рассмотрим более лаконичный вариант установки значения без полного переопределения вывода отчета:


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

Однако помните: если параметр выведен в Пользовательские настройки (быстрый отбор на форме), то изменение в КомпоновщикНастроек.Настройки может быть перекрыто значениями из КомпоновщикНастроек.ПользовательскиеНастройки. В таких случаях нужно менять значение именно в пользовательских настройках.

Работа с виртуальными таблицами и ошибка «Параметр не найден»

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

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

Разберем пример кода запроса:


ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних({(&КонецПериода)}, {(ВидЦены = &ВидЦены)}) КАК ЦеныНоменклатурыСрезПоследних
ПО ВременнаяТаблица.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура

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

Почему цены «задваиваются» и как это исправить?

Одной из самых раздражающих проблем в СКД является ситуация, когда цена или остаток в отчете суммируются, превращаясь в огромные цифры. Например, если цена товара 100 рублей, а в отчете вывелось 300, это явный признак того, что система сложила значения из разных записей или соединений.

Рассмотрим причины возникновения этой ситуации:

  1. Некорректное соединение в запросе. Если в левом соединении к одной строке продаж цепляется несколько строк из регистра цен (например, из-за того, что цены установлены в разрезе характеристик, а в запросе характеристика не указана), строк в выборке становится больше.
  2. Неправильная агрегатная функция в ресурсах. Это самая частая причина. По умолчанию СКД предлагает для всех числовых полей функцию СУММА().

Чтобы исправить это, перейдем на закладку Ресурсы. Найдем поле Цена. Если для него в колонке «Рассчитывать по...» указана функция Сумма(Цена), заменим ее на Максимум(Цена) или Среднее(Цена).

Посмотрим на пример настройки ресурсов:

Практические советы для отладки

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

Выполните следующие действия:

  1. Откройте отчет в консоли СКД.
  2. Сформируйте отчет.
  3. Посмотрите вкладку Исполняемый запрос. Именно там вы увидите, какие параметры реально подставились и где произошло размножение строк из-за LEFT JOIN.
  4. Если вы видите, что поле ВидЦены в итоговом запросе пустое (NULL), проверьте тип данных параметра в схеме. Он должен строго соответствовать типу измерения в регистре.

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

← На главную