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