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