При разработке отчетов на базе Системы компоновки данных (СКД) часто возникает задача автоматизировать заполнение одних параметров на основании других. Классический пример: пользователь выбирает основной Период, а система должна автоматически рассчитать начало прошлого месяца, границу остатков или технический параметр для запроса. В этой статье мы подробно разберем, как реализовать такую логику, избежав типичных ошибок начинающих разработчиков.
Рассмотрим самый простой и эффективный метод, который не требует написания кода в модулях и работает максимально быстро. В конструкторе СКД на закладке Параметры есть колонка Выражение. Мы можем использовать ее для вычислений «на лету».
Предположим, у нас есть стандартный параметр ПериодОтчета (тип СтандартныйПериод), и нам нужно автоматически получить дату начала этого периода для другого параметра ДатаНачала. Разберем по шагам, как это сделать:
ДатаНачала в колонке Выражение напишем: &ПериодОтчета.ДатаНачала.ДобавитьКДате(КонецПериода(&ПериодОтчета.ДатаОкончания, "Месяц"), "Месяц", -1).Проанализируем ситуацию: использование выражений внутри схемы позволяет сохранять отчет «чистым», так как вся логика инкапсулирована в XML-описании схемы. Это предпочтительный вариант для простых зависимостей.
Если логика расчета параметра слишком сложна для одной строки выражения (например, требуется запрос к базе данных или проверка сложных условий), мы будем использовать модуль объекта отчета. Рассмотрим наиболее подходящую для этого процедуру — ПриКомпоновкеРезультата.
Часто программисты допускают ошибку, пытаясь переопределить объект КомпоновщикНастроек, что приводит к ошибке «Поле объекта недоступно для записи». Выясним причину: этот объект создается платформой автоматически, и мы должны работать с его внутренними свойствами, а не заменять его целиком.
Посмотрим на пример правильного кода в модуле отчета:
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
// Отключаем стандартный вывод, если планируем полностью управлять процессом
// СтандартнаяОбработка = Ложь;
// Получаем значение основного периода, установленного пользователем
ПараметрПериод = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПериодОтчета"));
Если ПараметрПериод <> Неопределено И ПараметрПериод.Использование Тогда
ВыбранныйПериод = ПараметрПериод.Значение; // Тип СтандартныйПериод
// Рассчитываем зависимый параметр, например, НачалоПрошлогоГода
НужнаяДата = НачалоГода(ДобавитьМесяц(ВыбранныйПериод.ДатаНачала, -12));
// Устанавливаем значение в параметры данных
ЗначениеПараметра = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("НачалоПрошлогоГода"));
Если ЗначениеПараметра <> Неопределено Тогда
ЗначениеПараметра.Значение = НужнаяДата;
ЗначениеПараметра.Использование = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важный нюанс: Если параметр вынесен в Пользовательские настройки (те, что видны прямо на форме отчета), то изменение КомпоновщикНастроек.Настройки.ПараметрыДанных может не сработать, так как пользовательские настройки имеют приоритет. В этом случае нам нужно найти соответствующий элемент в КомпоновщикНастроек.ПользовательскиеНастройки.Элементы, используя ИдентификаторПользовательскойНастройки из основной схемы.
Вернемся к полю Выражение в схеме. Если выражения 1С:Предприятия в схеме не хватает, мы можем вызвать функцию из общего модуля. Это «золотая середина» между первым и вторым способами.
Рассмотрим требования к такой функции:
Например, создадим функцию в модуле РаботаСДатамиВызовСервера:
Функция ПолучитьСпециальнуюДату(ИсходнаяДата) Экспорт
// Здесь может быть любая сложная логика
Возврат КонецКвартала(ИсходнаяДата);
КонецФункции
Теперь в СКД в поле выражения параметра мы просто напишем: РаботаСДатамиВызовСервера.ПолучитьСпециальнуюДату(&ПериодОтчета.ДатаОкончания). Это позволяет вынести сложный расчет из модуля отчета, делая его доступным для повторного использования в других отчетах.
Иногда нужно, чтобы зависимый параметр менялся не в момент нажатия кнопки «Сформировать», а сразу, как только пользователь изменил основной период. Это важно для визуального контроля.
Для реализации этого метода нам потребуется работать в Модуле формы отчета:
Отчет.КомпоновщикНастроек.ПользовательскиеНастройки).ПриИзменении.Проанализируем этот подход: он самый трудозатратный, так как требует создания формы и программной привязки событий, но он обеспечивает лучший пользовательский опыт (User Experience), исключая неопределенность при формировании данных.
Разберем основные моменты, на которых спотыкаются разработчики:
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных внутри отчета. Это разрушает связь с формой и схемой. Работайте только со свойствами Настройки или ПользовательскиеНастройки.Подводя итог, можно сказать: для 90% задач достаточно использования поля Выражение непосредственно в схеме компоновки данных с обращением к свойствам СтандартногоПериода. Для остальных 10% сложных случаев используйте процедуру ПриКомпоновкеРезультата, аккуратно работая с коллекцией параметров данных.