Где лежат и как прочитать настройки отчёта на СКД, которые поменял пользователь
Содержание
Чтобы получить пользовательские настройки СКД внутри отчёта, вызовите КомпоновщикНастроек.ПолучитьНастройки(). Метод вернёт итоговые настройки: вариант отчёта плюс всё, что пользователь поменял в шапке формы. Сохранённые настройки другого пользователя читают из хранилища: ХранилищеПользовательскихНастроекОтчетов.Загрузить().
Дальше всё зависит от того, где вы находитесь. Внутри отчёта хватает компоновщика. Из внешней обработки нужны хранилище и ключи. Если же вы ищете, куда платформа пишет настройки на уровне СУБД, придётся смотреть служебные таблицы и технологический журнал. Код ниже рассчитан на платформу 8.3 и управляемые формы.
Как платформа хранит настройки отчётов на СКД
У отчёта на системе компоновки данных три слоя настроек:
- 📐 Вариант отчёта — настройки из схемы (
Схема.ВариантыНастроек) или сохранённый пользователем вариант. Это структура: группировки, поля, отборы. - 🎛️ Пользовательские настройки (
ПользовательскиеНастройкиКомпоновкиДанных) — только те элементы, у которых в варианте включён флаг «Включать в пользовательские настройки». Это период, отборы в шапке, флажки. - 🧩 Фиксированные настройки — накладываются программно и пользователю не видны.
Пользовательские настройки не содержат копии всего варианта. Каждый их элемент несёт ИдентификаторПользовательскойНастройки и ссылается на свой элемент в варианте. Поэтому их нельзя читать в отрыве от варианта: без него набор элементов почти бессмыслен.
Куда это попадает при сохранении, задают свойства корня конфигурации:
| Свойство конфигурации | Что хранит | Глобальная переменная в коде |
|---|---|---|
| Хранилище вариантов отчётов | Сохранённые варианты | ХранилищеВариантовОтчетов |
| Хранилище пользовательских настроек отчётов | Пользовательские настройки | ХранилищеПользовательскихНастроекОтчетов |
| Хранилище настроек данных форм | Значения реквизитов форм | ХранилищеНастроекДанныхФорм |
| Хранилище общих настроек | Прочие настройки | ХранилищеОбщихНастроек |
Если свойство пустое, используется стандартное хранилище платформы. Если там указано хранилище из ветки «Хранилища настроек», данные пишет код конфигурации — например, в справочник. В типовых конфигурациях на БСП варианты отчётов хранятся в справочнике «Варианты отчетов», поэтому первым делом откройте свойства корня в Конфигураторе и посмотрите, что задано.
Получение пользовательских настроек СКД программно
Внутри модуля отчёта
Самый частый сценарий: отчёт должен узнать, какой период или отбор выбрал пользователь, и что-то сделать с этим значением. Используйте обработчик ПриКомпоновкеРезультата в модуле объекта отчёта:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// Вариант + изменения пользователя в одной структуре
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
ЗначениеПериода = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(
Новый ПараметрКомпоновкиДанных("Период"));
Если ЗначениеПериода <> Неопределено И ЗначениеПериода.Использование Тогда
Период = ЗначениеПериода.Значение; // СтандартныйПериод
Сообщить("Отчёт строится с " + Формат(Период.ДатаНачала, "ДФ=dd.MM.yyyy"));
КонецЕсли;
// СтандартнаяОбработка не трогаем: отчёт сформируется как обычно
КонецПроцедуры
Не читайте КомпоновщикНастроек.Настройки напрямую, если нужен выбор пользователя. Там лежит вариант без учёта шапки отчёта. Правильный источник — результат ПолучитьНастройки().
Перебор всех элементов пользовательских настроек
Иногда нужен полный список того, что видит пользователь: для журнала, для печати «условий отбора» над таблицей, для отладки. Коллекция ПользовательскиеНастройки.Элементы смешанная, поэтому тип каждого элемента проверяем:
Функция ОписаниеПользовательскихНастроек(ПользовательскиеНастройки) Экспорт
Результат = Новый Массив;
Для Каждого Элемент Из ПользовательскиеНастройки.Элементы Цикл
Если ТипЗнч(Элемент) = Тип("ЗначениеПараметраНастроекКомпоновкиДанных") Тогда
Результат.Добавить(СтрШаблон("Параметр %1 = %2, включён: %3",
Элемент.Параметр, Элемент.Значение, Элемент.Использование));
ИначеЕсли ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
Результат.Добавить(СтрШаблон("Отбор %1 %2 %3, включён: %4",
Элемент.ЛевоеЗначение, Элемент.ВидСравнения,
Элемент.ПравоеЗначение, Элемент.Использование));
ИначеЕсли ТипЗнч(Элемент) = Тип("ОтборКомпоновкиДанных") Тогда
Результат.Добавить(СтрШаблон("Блок отбора, условий: %1",
Формат(Элемент.Элементы.Количество(), "ЧГ=0")));
Иначе
Результат.Добавить("Другая настройка: " + Строка(ТипЗнч(Элемент)));
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Вызов из модуля объекта: ОписаниеПользовательскихНастроек(КомпоновщикНастроек.ПользовательскиеНастройки).
В модуле формы отчёта
У формы отчёта есть обработчик ПриЗагрузкеПользовательскихНастроекНаСервере(Настройки). Параметр Настройки — те самые ПользовательскиеНастройкиКомпоновкиДанных, которые платформа только что подняла из хранилища. Это удобная точка, чтобы подменить значение по умолчанию (например, всегда ставить текущий месяц) до того, как пользователь увидит форму. Парный обработчик ПриСохраненииПользовательскихНастроекНаСервере срабатывает при записи.
Чтение сохранённых настроек из хранилища
Когда нужно узнать настройки другого пользователя или собрать их по всей базе, компоновщик не поможет. Работаем с хранилищем.
Шаг 1. Узнать ключи
Ключ объекта и ключ настроек платформа формирует сама, и угадывать их не стоит. Стандартное хранилище умеет выбирать записи с отбором:
Отбор = Новый Структура("Пользователь", "Иванов");
Выборка = ХранилищеПользовательскихНастроекОтчетов.Выбрать(Отбор);
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.КлючОбъекта + " | " + Выборка.КлючНастроек
+ " | " + Выборка.Представление);
КонецЦикла;
В отбор можно передать КлючОбъекта, КлючНастроек и Пользователь (имя пользователя информационной базы). В КлючОбъекта вы увидите полное имя отчёта и ключ варианта, по нему легко найти нужную строку.
Метод Выбрать() есть у стандартного хранилища. Если в свойствах конфигурации указано своё хранилище, перебор записей придётся делать через его справочник или регистр.
Шаг 2. Загрузить настройки
&НаСервереБезКонтекста
Функция ЗагрузитьНастройкиОтчета(КлючОбъекта, КлючНастроек, ИмяПользователя)
ОписаниеНастроек = Неопределено;
Настройки = ХранилищеПользовательскихНастроекОтчетов.Загрузить(
КлючОбъекта, КлючНастроек, ОписаниеНастроек, ИмяПользователя);
Если ТипЗнч(Настройки) <> Тип("ПользовательскиеНастройкиКомпоновкиДанных") Тогда
Возврат Неопределено;
КонецЕсли;
Возврат Настройки;
КонецФункции
Чтение чужих настроек выполняйте под пользователем с административными правами. Обычный пользователь видит только своё.
Шаг 3. Получить итоговые значения
Сами по себе загруженные настройки — набор элементов с идентификаторами. Чтобы понять, какой период или отбор в них записан, наложите их на вариант через новый компоновщик:
Схема = Отчеты.ПродажиПоКлиентам.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
НастройкиВарианта = Схема.НастройкиПоУмолчанию;
Для Каждого Вариант Из Схема.ВариантыНастроек Цикл
Если Вариант.Имя = КлючВарианта Тогда
НастройкиВарианта = Вариант.Настройки;
Прервать;
КонецЕсли;
КонецЦикла;
Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема));
Компоновщик.ЗагрузитьНастройки(НастройкиВарианта);
Компоновщик.ЗагрузитьПользовательскиеНастройки(ПользНастройки);
Итог = Компоновщик.ПолучитьНастройки();
ПродажиПоКлиентам и имя макета замените на свои. Дальше с Итог работаете как в первом примере: ПараметрыДанных.НайтиЗначениеПараметра(), Отбор.Элементы и так далее.
Порядок вызовов важен: сначала Инициализировать, потом вариант, и только потом пользовательские настройки. Иначе идентификаторы не совпадут, и платформа молча проигнорирует выбор пользователя.
Служебные таблицы базы данных: что можно увидеть через СУБД
Стандартное хранилище пишет настройки в служебные таблицы платформы. В клиент-серверной базе их видно в Management Studio или pgAdmin: _CommonSettings, _ReportsSettings, _FrmDtSettings, _SystemSettings. В файловой базе те же таблицы лежат внутри 1Cv8.1CD.
Что из этого реально полезно:
- 🔎 найти, у каких пользователей вообще есть сохранённые настройки конкретного отчёта (по колонке с ключом объекта);
- 📊 оценить объём: у отчёта с тяжёлыми отборами таблица разрастается;
- 🧹 понять, откуда берётся «залипшее» значение, которое пользователь не может сбросить.
Чего сделать нельзя — прочитать значения. Колонка с данными двоичная: это сериализованное и сжатое значение платформы. Его не разобрать запросом SQL, только кодом 1С через хранилище.
Не изменяйте и не удаляйте строки этих таблиц средствами СУБД. Платформа не ждёт правки своих служебных таблиц снаружи. Чистить настройки нужно из 1С: методом Удалить() хранилища или через обработку настроек пользователей в конфигурации.
Если отчёты используют своё хранилище, служебные таблицы платформы для них пусты. Данные ищите в таблице справочника или регистра, который указан в свойствах конфигурации.
Как отследить запись и чтение настроек через техжурнал и профайлер
Бывает, что непонятно, какой код и в какой момент перезаписывает настройки. Тогда помогают три инструмента.
Замер производительности в Конфигураторе
Запустите отладку, включите замер производительности и откройте отчёт. В результатах замера видно, какие строки модулей выполнялись при загрузке формы. Ищите вызовы Загрузить, Сохранить и обработчики ПриЗагрузкеПользовательскихНастроекНаСервере. Это самый быстрый способ найти «чужой» код, который подменяет выбор пользователя.
Технологический журнал
Для клиент-серверной базы настройте logcfg.xml в каталоге conf установленной платформы. Отбор по имени служебной таблицы покажет каждое обращение к ней:
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\1C_TJ" history="2">
<event>
<eq property="name" value="DBMSSQL"/>
<like property="sql" value="%ReportsSettings%"/>
</event>
<property name="all"/>
</log>
</config>
Для PostgreSQL вместо DBMSSQL укажите событие DBPOSTGRS. В записях журнала будут пользователь, контекст вызова и текст запроса.
Технологический журнал нагружает сервер и быстро заполняет диск. Включайте его на короткое время, лучше на копии базы, и удаляйте logcfg.xml сразу после замера.
Профайлер СУБД
SQL Server Profiler или Extended Events дают ту же картину со стороны СУБД. Фильтр по тексту запроса с _ReportsSettings покажет, когда идут INSERT и UPDATE. Связать запрос с пользователем 1С тут сложнее, поэтому техжурнал обычно удобнее.
Выгрузка, загрузка и перенос вариантов отчётов
Средствами пользовательского режима
В формах отчётов кнопки сохранения и выбора вариантов и настроек находятся в меню Ещё. Пользователь сохраняет вариант под своим именем и потом выбирает его из списка.
В типовых конфигурациях на БСП администратор может скопировать или очистить настройки одного пользователя для другого: Администрирование → Настройки пользователей и прав, далее ссылка на настройки пользователей. Там же видно, какие отчёты у пользователя уже настроены.
В файл из кода
Пользовательские настройки сериализуются в XML. Это удобно для бэкапа перед обновлением или переноса между базами:
// Выгрузка
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ИмяФайла);
СериализаторXDTO.ЗаписатьXML(Запись, ПользНастройки, НазначениеТипаXML.Явное);
Запись.Закрыть();
// Загрузка
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
ПользНастройки = СериализаторXDTO.ПрочитатьXML(Чтение);
Чтение.Закрыть();
Если XML не нужен, подойдёт пара ЗначениеВСтрокуВнутр() / ЗначениеИзСтрокиВнутр(). Строку можно положить в реквизит, регистр или текстовый файл.
Загруженные настройки записываются обратно методом хранилища Сохранить() с теми же ключами и именем пользователя.
| Способ переноса | Когда подходит | Ограничения |
|---|---|---|
| Сохранение варианта в форме отчёта | Один пользователь, одна база | Не переносит между базами |
| Копирование настроек в БСП | Раздать настройки отделу | Только внутри одной базы |
XML через СериализаторXDTO | Перенос между базами, бэкап | Варианты в базах должны совпадать |
Выгрузка в .dt | Перенос базы целиком | Переносит всё, выборочно нельзя |
Частые ошибки при работе с пользовательскими настройками СКД
Ещё одна ловушка — правка настроек через ПолучитьНастройки(). Метод возвращает копию. Изменения в ней не вернутся ни в компоновщик, ни в форму. Чтобы поменять значение для пользователя, меняйте элемент в КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.
Частые вопросы
Чем пользовательские настройки отличаются от варианта отчёта?
Можно ли получить настройки, которые пользователь поменял, но не сохранил?
Как сбросить настройки отчёта одному пользователю?
ХранилищеПользовательскихНастроекОтчетов.Удалить() с ключом объекта и именем пользователя. В конфигурациях на БСП то же делается в настройках пользователей раздела «Администрирование».Работает ли это во внешнем отчёте?
Выбрать(), а не вручную.