Мы часто сталкиваемся с задачами, когда необходимо работать с настройками отчетов программно. Типичная ситуация, с которой столкнулся автор темы: в пользовательском режиме отчет открывается с нужными отборами и группировками, но при попытке получить эти настройки кодом (например, для механизма рассылки отчетов или сохранения в файл), система возвращает стандартные настройки по умолчанию.
Давайте разберемся, почему так происходит, как устроена архитектура хранения настроек в Системе Компоновки Данных (СКД) и Библиотеке Стандартных Подсистем (БСП), и как нам получить именно те данные, которые видит пользователь.
Чтобы понять корень проблемы, нам нужно четко разделять два понятия в платформе 1С:
Проблема, описанная в теме, возникает из-за того, что методы типа ХранилищеВариантовОтчетов.Загрузить часто возвращают только первую часть — структуру. Если пользовательские значения (отборы) не были "впечены" в сам вариант при сохранении, они живут отдельно.
Рассмотрим места хранения, с которыми мы работаем:
ХранилищеЗначения лежит описание варианта. В типовых конфигурациях на БСП это часто не просто настройки СКД, а Структура, содержащая ключ Variant и иногда ключ UserSettings.Именно поэтому механизм рассылки отчетов (который работает в фоновом задании и не знает о локальном кэше пользователя) видит только "чистый" вариант из справочника без последних фильтров пользователя.
Прежде чем писать код, давайте проверим, правильно ли сохранен вариант. Если мы просто меняем настройки и закрываем отчет — они сохраняются "для себя". Чтобы они стали частью варианта (и были видны рассылке), нужно выполнить следующие действия:
Это действие принудительно запишет текущие пользовательские настройки (отборы) внутрь элемента справочника ВариантыОтчетов.
Если нам нужно программно "собрать" итоговые настройки, простого чтения хранилища недостаточно. Нам необходимо использовать объект КомпоновщикНастроекКомпоновкиДанных для слияния основных и пользовательских настроек.
Давайте рассмотрим алгоритм, который позволяет получить "финальные" настройки, готовые к выполнению компоновки:
// 1. Создаем объект отчета, чтобы получить доступ к его компоновщику
ОтчетОбъект = Отчеты[ИмяОтчета].Создать();
Компоновщик = ОтчетОбъект.КомпоновщикНастроек;
// 2. Получаем сохраненные настройки из хранилища вариантов
// КлючВарианта - это обычно ссылка на элемент справочника ВариантыОтчетов или строка-идентификатор
НастройкиВарианта = ХранилищеВариантовОтчетов.Загрузить(ИмяОтчета, КлючВарианта);
// В БСП настройки могут быть обернуты в структуру. Проверим это:
Если ТипЗнч(НастройкиВарианта) = Тип("Структура") И НастройкиВарианта.Свойство("Variant") Тогда
// Если это структура БСП
ОсновныеНастройки = НастройкиВарианта.Variant;
ПользовательскиеНастройки = ?(НастройкиВарианта.Свойство("UserSettings"), НастройкиВарианта.UserSettings, Неопределено);
Иначе
// Если это чистые настройки СКД
ОсновныеНастройки = НастройкиВарианта;
ПользовательскиеНастройки = Неопределено;
КонецЕсли;
// 3. Загружаем основные настройки в компоновщик
Компоновщик.ЗагрузитьНастройки(ОсновныеНастройки);
// 4. Если есть сохраненные пользовательские настройки - применяем их
Если ПользовательскиеНастройки <> Неопределено Тогда
Компоновщик.ЗагрузитьПользовательскиеНастройки(ПользовательскиеНастройки);
КонецЕсли;
// 5. Получаем итоговые настройки, где отборы слиты воедино
ИтоговыеНастройки = Компоновщик.ПолучитьНастройки();
Обратите внимание на метод ПолучитьНастройки() в конце. Именно он отвечает за наложение пользовательских фильтров (из списка ПользовательскиеНастройки) на структуру отчета.
В конфигурациях, использующих БСП (как CRM 2.0 в примере автора), свойство конфигурации ХранилищеВариантовОтчетов часто переопределено. Это значит, что стандартные методы платформы перехватываются менеджером хранилища настроек.
Автор темы справедливо заметил в сообщении 9:
"Получаю уже из списка КлючНастроек... А оно зараза вызывает процедуру ОбработкаЗагрузки... которая лезет в справочник ВариантыОтчетов и тянет оттуда настройки стандартные".
Давайте разберем, как получить список вариантов правильно. Метод ПолучитьСписок требует указания полного имени отчета в качестве ключа объекта.
// Правильный вызов получения списка вариантов
СписокВариантов = ХранилищеВариантовОтчетов.ПолучитьСписок("Отчет.ИмяВашегоОтчета");
Для Каждого ЭлементСписка Из СписокВариантов Цикл
ИмяВарианта = ЭлементСписка.Представление;
КлючВарианта = ЭлементСписка.Значение; // Здесь может быть GUID или Строка
// Загрузка конкретного варианта
Настройки = ХранилищеВариантовОтчетов.Загрузить("Отчет.ИмяВашегоОтчета", КлючВарианта);
КонецЦикла;
Если метод Загрузить возвращает "пустые" настройки, это подтверждает гипотезу о том, что в базе данных (в справочнике) сохранен вариант без пользовательских уточнений. В этом случае программно "угадать", какие фильтры хотел пользователь, невозможно, так как они остались только в кэше его формы или не были сохранены вовсе.
Если рассылка отчетов или другой программный код "не видит" настройки:
КомпоновщикНастроек и используйте метод ПолучитьНастройки().Структура, внутри которой лежат отдельно настройки схемы и отдельно пользовательские настройки.