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