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