1с скд не сохраняются настройки
Как я уже писал ранее, сделал клиенту в УТ отчет, где подменил схему компоновки данных. Все работало хорошо, но не сохранялись настройки в варианте.
Проявлялось это так — если в настройках добавить поле «Остаток», то отчет формировался. Если сохранить вариант, потом переключиться на другой, потом вернуться на сохраненный, поле тоже показывалось.
Но если закрыть отчет и открыть сохраненный вариант, поля не было.
Я предполагал, что разбирательства будут долгими, так оно и оказалось. Работы были гарантийными, но мне было интересно, в чем проблема. Так можно было просто подменить макет через расширение макета, но хотелось докопаться до истины.
Вообще, был интересен вопрос — вариант сохраняется криво, без моего поля или же при восстановлении варианта происходит сбой.
Сейчас я понимаю, что надо было просто проверить, есть ли поле в настройках компоновщика при компоновке отчета из сохраненного варианта.
Но я пошел другим путем, не самым быстрым.
Я сделал замер производительности при сохранении варианта и нашел, где создается схема компоновки данных:
И вот тут я увидел, что в тексте запроса компоновки нет поля «Остаток», который я добавил (смотрите табло внизу):
Я отладил и нашел, где создается объект отчета:
В итоге я решил добавить событие, чтобы при создании отчета обновлялась компоновка данных.
В модуле ВариантыОтчетов:
В модуле отчета ВыручкаИСебестоимостьПродаж:
После этого в компоновке появилось мое поле остаток:
Дальше я решил проверить, как загружаются настройки при открытии отчета, нашел вот эту функцию, где опять же создавался объект отчета, похоже со стандартной схемой компоновки (не измененной):
По стеку сложно было привязаться к каким либо событиям:
Поэтому я решил привязаться к событию ЗагрузитьНастройкиВКомпоновщик:
Код выглядел примерно так:
Однако почему-то ЗначениеВРеквизитФормы выдавало ошибку, ругаясь на второй параметр. В общем, отладка показала, что ничего в запросе схемы компоновки не меняется, он остается без поля остаток.
Но тут я все же отладил загрузку варианта. Чтобы отлаживать не в фоновом режиме, я использовал запуск 1С с параметром РежимОтладки.
Я обнаружил, что настройка варианта загружается нормально, т.е. в списке полей настройки есть поле Остаток. Т.е. все предыдущие доработки были зря, потому что и без них вариант сохранялся и загружался нормально.
Настройки пропадают где-то при формировании отчета в коде самого отчета:
Дальнейшая проверка показала, где пропадает настройка:
Вот в этом коде настройки корректные:
А вот в этом коде поля Остаток уже нет:
Я добавил строчку для подмены настроек и отчет сформировался корректно:
Но мне не нравилось, что приходится менять код отчета. Поэтому я немножко поэкспериментировал и обнаружил, как можно привести настройки в адекватное состояние.
По сути, проблема сохранения варианта решается одной дополнительной строчкой кода в расширении, вот она:
Почему сбоят настройки, т.е. почему ПолучитьНастройки и Настройки одного и того же объекта выдают разные значения, я так и не понял. Я пробовал и метод ВосстановитьНастройки и добавлял инициализацию настроек в компоновщике настроек после подмены схемы компоновки, ничего не помогло. Видимо, это фича 1С.
Ошибкой было еще предположение, что где-то схема используется не измененная, поэтому настройки не сохраняются. Нужно было проверить настройки при компоновке отчета, тогда бы я увидел, что они уже там правильные, но сбрасываются из-за этой фичи.
Дело в том, что 1С всегда вызывает событие перед загрузкой настроек отчета, а там уже моё изменение схемы есть. Поэтому я по сути большую часть времени потратил на поиски фантомной ошибки, которой на самом деле не было.
Разборки показали, что проблема в пользовательских настройках, именно они при старте отчета не содержат поля остаток.
Я попробовал так, но не помогло:
Поле ДоступныеНастройки.ПользовательскиеНастройки.Элементы[3].Элементы не содержит поле Остаток:
Похоже, что пользовательские настройки отчета были модифицированы ранее.
Более детальный анализ показал, что настройки загружаются в событии формы перед загрузкой пользовательских настроек:
Поэтому нужно при создании формы отчета подменить схему компоновки.
Вот так заработало:
Но так не годится — это вмешательство в код.
Поэтому переношу код в расширение, таким образом, в расширении формы отчета достаточно такого кода (достаточно вызвать только при создании):
Ну и в расширении модуля отчета по валовой прибыли необходимый код такой:
Перед загрузкой настроек в компоновщик тоже надо обрабатывать, иначе не срабатывает.
Время факт: 3 час. Среда: УТ 11.4.13.46
Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.
Добрый день!
СКД отчеты управляемые формы, платформа 8.1.
У пользователей открыт доступ к пользовательским настройкам отчетов. Они изменяют видимость полей и группировки. Это необходимо для работы.
Но как сделать, чтобы настройки не сохранялись после закрытия отчета.
Понимаю, что для программной работы с пользовательскими настройками отчета нужно создать Хранилище настроек. Создал.
В СКД отчете указал свойство Хранилище настроек.
Что нужно и где прописать, чтобы пользовательские настройки не сохранялись.
Как программно вызвать стандартную команду формы Установить стандартные настройки я не разобрался.
Написал код на событие закрытие формы:
Забыл дописать. Что создавать форму отчета нежелательно. Поэтому использовать события формы связанные с настройками не могу.
(2) если доступа к форме отчета нет, то у нас для маневра есть только свойства объекта-отчета с компоновщиком и модуль объекта. Сомневаюсь, что в указанных сущностях есть
возможность указания запрета сохранения настроек.
в форме отчета ПередЗакрытием()
или События формы отчета а ля
ПриСохраненииНастроек. () и т.п. посмотреть в СП.
может в событие нужно еще воткнуть Отказ = Истина;
Если создаю форму отчета.
В событии Перед закрытием ставлю Отказ = ложь , тогда форма вообще не закрывается.
Модифицированость = Ложь не сказывается на сохранение настроек.
Я пробую написать, что-то типа :
Как программно вызвать стандартную команду формы Установить стандартные настройки я не разобрался.
Написал код на событие закрытие формы:
когда пользователь закрывает отчет с измененными настройкам то за сохранение "отвечают" свойства управляемой формы отчета "ВариантМодифицирован,ПользовательскиеНастройкиМодифицированы"
установки в модуле формы перед закрытием
"обманывают" отчет при сохранении, т.е. система должна считать, что настройки неизменны при закрытии.
как в 8.1 на обычных формах насчет подобного свойства не помню. отладчиком посмотреть надо свойства формы отчета в конфе на 8.1.
Задача: нужно хранить настройки отчета на СКД в базе, причем у каждого поль зователя должно быть произвольное количество настроек.
Для хранения настроек отчетов в УПП существуют два метаданных. Регистр сведений "Сохраненные настройки" и одноименный справочник.
Их структура похожа, в обоих есть информация:
- О пользователе, который может использовать данную настройку
- "СохранятьАвтоматически" - сохранять настройку при закрытии
- "ИспользоватьПриОткрытии" - при открытии будет выведен отчет по настройке с данной галочкой. Галочка может стоять только у одной настройки к каждому отчету. Если ни у одной настройки галочки нет, то будет выведена типовая настройка СКД.
- Реквизит с типом "Хранилище значения" (в справочнике реквизит "ХранилищеНастроек", в регистре сведений ресурс "СохраненнаяНастройка"). В данном объекте собсвенно и хранятся настройки. Как известно хранилище значения может хранить любое значение.
В регистре сведений хранятся настройки для отчетов, построенных на универсальном отчете, в справочнике - построенных на СКД. Логично сохранять настройки в справочнике. Но после беглого взгляда возникает несколько но:
- Данный справочник содержит предопределенные элементы, имя которых совпадает с именами отчетов. Свои же отчеты туда добавить нельзя, так как в результате обновления может возникнуть коллизия, 1с добавит новые элементы и в тоже время будут существовать предопределенные элементы, добавленные пользователем.
- Справочник заточен на работу с шаблоном отчета 1с, и процедуры и функции работы с сохранением настроек выдрать из него достаточно сложно.
Регистр сведений. Как говорилось выше - в нем хранятся настройки для отчетов на универсальном отчете. Но просмотрев механизм, я решил использовать его, так как процедуры работы с сохранением и восстановлением настроек взять гораздо проще, и более того, данный механизм использован не только в отчетах, но и в типовой обработке "Универсальный журнал", код из которой, немного изменив, я и приспоспособил для решения данной задачи.
Итак. На форму надо добавить кнопки сохранения и восстановления значений настроек , добавить процедуры к ним, и написать код в процедуры "ПриОткрытии" и "ПриЗакрытии".
Процедура ДействияФормыСохранитьНастройки ( Кнопка )
Если мТекущаяНастройка <>Неопределено Тогда
СтруктураНастройки = мТекущаяНастройка ;
Иначе
СтруктураНастройки = Новый Структура ;
СтруктураНастройки . Вставить ( "ИмяОбъекта" , Строка ( ЭтотОбъект ));
СтруктураНастройки . Вставить ( "НаименованиеНастройки" , Неопределено);
СтруктураНастройки . Вставить ( "ИспользоватьПриОткрытии" , Ложь);
СтруктураНастройки . Вставить ( "СохранятьАвтоматически" , Ложь);
КонецЕсли;
СтруктураНастройки . Вставить ( "Пользователь" , глЗначениеПеременной ( "глТекущийПользователь" ));
СохраненнаяНастройка = Новый ХранилищеЗначения ( КомпоновщикНастроек . ПолучитьНастройки ());
СтруктураНастройки . Вставить ( "СохраненнаяНастройка" , СохраненнаяНастройка );
ВозвращаемаяСтруктура = УниверсальныеМеханизмы . СохранениеНастроек ( СтруктураНастройки );
Если ВозвращаемаяСтруктура <> Неопределено Тогда
мТекущаяНастройка = ВозвращаемаяСтруктура ;
Иначе
мТекущаяНастройка = СтруктураНастройки ;
КонецЕсли;
Процедура ДействияФормыВосстановитьНастройки ( Кнопка )
СтруктураНастройки = Новый Структура ;
СтруктураНастройки . Вставить ( "Пользователь" , глЗначениеПеременной ( "глТекущийПользователь" ));
СтруктураНастройки . Вставить ( "ИмяОбъекта" , Строка ( ЭтотОбъект ));
СтруктураНастройки . Вставить ( "НаименованиеНастройки" , ?( мТекущаяНастройка = Неопределено, Неопределено, мТекущаяНастройка . НаименованиеНастройки ));
ВозвращаемаяСтруктура = УниверсальныеМеханизмы . ВосстановлениеНастроек ( СтруктураНастройки );
Если ВозвращаемаяСтруктура <> Неопределено Тогда
мТекущаяНастройка = ВозвращаемаяСтруктура ;
КомпоновщикНастроек . ЗагрузитьНастройки ( мТекущаяНастройка . СохраненнаяНастройка . Получить ());
КонецЕсли;
Процедура ПриОткрытии ()
СтруктураНастройки = Новый Структура ;
СтруктураНастройки . Вставить ( "Пользователь" , глЗначениеПеременной ( "глТекущийПользователь" ));
СтруктураНастройки . Вставить ( "ИмяОбъекта" , Строка ( ЭтотОбъект ));
Если УниверсальныеМеханизмы . ПолучитьНастройкуИспользоватьПриОткрытии ( СтруктураНастройки ) Тогда
мТекущаяНастройка = СтруктураНастройки ;
КомпоновщикНастроек . ЗагрузитьНастройки ( мТекущаяНастройка . СохраненнаяНастройка . Получить ());
Иначе
//установка первоначальных настроек, например периода и т.д.
КонецЕсли;
КонецПроцедуры
Если мТекущаяНастройка <> Неопределено И мТекущаяНастройка . НаименованиеНастройки <> Неопределено
И мТекущаяНастройка . Свойство ( "СохранятьАвтоматически" ) И мТекущаяНастройка . СохранятьАвтоматически Тогда
ТекПользователь = глЗначениеПеременной ( "глТекущийПользователь" );
Если ТекПользователь <> мТекущаяНастройка . Пользователь Тогда
Ответ = Вопрос ( "Вы восстановили настройку другого пользователя, сохранить ее в
|ваших настройках?" , РежимДиалогаВопрос . ДаНет );
Если Ответ = КодВозвратаДиалога . Да Тогда
Если ВвестиСтроку ( мТекущаяНастройка . НаименованиеНастройки ,
"Укажите наименование сохраняемой настройки" ) Тогда
мТекущаяНастройка . Пользователь = ТекПользователь ;
УниверсальныеМеханизмы . СохранитьНастройку ( мТекущаяНастройка );
КонецЕсли;
КонецЕсли;
Иначе
УниверсальныеМеханизмы . СохранитьНастройку ( мТекущаяНастройка );
КонецЕсли;
КонецЕсли;
Данный, достаточно небольшой код, позволяет сохранять и восстанавливать настройки внешнего отчета на СКД.
sem_wolf Вопрос-ответ Ваш отзыв В закладки
Платформа 8.2 , обычное приложение. В отчете есть несколько схем СКД, на форме отчета в списке выбора пользователь сам выбирает нужную схему, помогите разобраться как сохранять/воостанавливать настройки схемы вместе с вариантом отчета. Настройки сохраняю в РС.СохраненныеНастройки. Проблема в том что я не понимаю как сохранить настройки СКД и значения реквизитов отчета вместе , получается только либо первое либо второе.
//Заполнение вариантов отчета
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
Варианты = Новый СписокЗначений;
Макеты = ЭтотОбъект.Метаданные().Макеты;
Для Каждого Схема ИЗ Макеты Цикл
Варианты.Добавить(Схема.Имя,Схема.Синоним);
КонецЦикла;
ЭлементыФормы.СписокВариантов.СписокВыбора = Варианты;
КонецПроцедуры
//выбор варианта отчета
Процедура СписокВариантовПриИзменении(Элемент)
СхемаКомпоновкиДанных = ЭтотОбъект.ПолучитьМакет(Элемент.Значение);
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
КонецПроцедуры
Процедура ПриОткрытии()
СтруктураНастройки = Новый Структура;
СтруктураНастройки.Вставить(“Пользователь”, глЗначениеПеременной(“глТекущийПользователь”));
СтруктураНастройки.Вставить(“ИмяОбъекта”, Строка(ЭтотОбъект));
Если УниверсальныеМеханизмы.ПолучитьНастройкуИспользоватьПриОткрытии(СтруктураНастройки) Тогда
мТекущаяНастройка = СтруктураНастройки;
КомпоновщикНастроек.ЗагрузитьНастройки(мТекущаяНастройка.СохраненнаяНастройка.Получить());
КонецЕсли;
КонецПроцедуры
//переопределение стандартных кн Сохранить/Восстановить значения
Процедура СохранитьНастройки() Экспорт
Перем СохраненнаяНастройка;
Если мТекущаяНастройка<>Неопределено Тогда
СтруктураНастройки = мТекущаяНастройка;
Иначе
СтруктураНастройки = Новый Структура;
СтруктураНастройки.Вставить(“ИмяОбъекта”, Строка(ЭтотОбъект));
СтруктураНастройки.Вставить(“НаименованиеНастройки”, Неопределено);
СтруктураНастройки.Вставить(“ИспользоватьПриОткрытии”, Ложь);
СтруктураНастройки.Вставить(“СохранятьАвтоматически”, Ложь);
КонецЕсли;
СтруктураНастройки.Вставить(“Пользователь”, глЗначениеПеременной(“глТекущийПользователь”));
СохраненнаяНастройка = Новый ХранилищеЗначения(КомпоновщикНастроек.ПолучитьНастройки());
СтруктураНастройки.Вставить(“СохраненнаяНастройка”, СохраненнаяНастройка);
Если ВозвращаемаяСтруктура <> Неопределено Тогда
мТекущаяНастройка = ВозвращаемаяСтруктура;
Иначе
мТекущаяНастройка = СтруктураНастройки;
КонецЕсли;
Процедура ВосстановитьНастройки() Экспорт
СтруктураНастройки = Новый Структура;
СтруктураНастройки.Вставить(“Пользователь”, глЗначениеПеременной(“глТекущийПользователь”));
СтруктураНастройки.Вставить(“ИмяОбъекта”, Строка(ЭтотОбъект));
СтруктураНастройки.Вставить(“НаименованиеНастройки”, ?(мТекущаяНастройка = Неопределено, Неопределено, мТекущаяНастройка.НаименованиеНастройки));
Если ВозвращаемаяСтруктура <> Неопределено Тогда
мТекущаяНастройка = ВозвращаемаяСтруктура;
КомпоновщикНастроек.ЗагрузитьНастройки(мТекущаяНастройка.СохраненнаяНастройка.Получить());
КонецЕсли;
КонецПроцедуры
Большинство хороших программистов делают свою работу не потому, что ожидают оплаты или признания, а потому что получают удовольствие от программирования (Linus Torvalds).
суббота, 21 декабря 2013 г.
Сохранение/восстановление отборов СКД в регистр "Сохраненные настройки"
В продолжение статьи Выгрузка результата СКД в таблицу значений рассмотрим, как установить отбор для созданной нами СКД, а также сохранять и восстанавливать настройки отбора и периода.
Для сохранения будут использоваться стандартные процедуры, которые применяются в отчетах в толстом клиенте (регистр сведений "Сохраненные настройки").
1) Для начала добавим в обработку реквизит "НастройкаОтбора" - тип "Строка", неограниченной длины. В этом реквизите и будет храниться наш отбор. Сохранять отбор будем с помощью функции сохранения значений ЗначениеВСтрокуВнутр(), а восстанавливать - ЗначениеИзСтрокиВнутр().
3) Откроем форму выберем пункт меню "Форма" - "Вставить элемент управления. " и добавим табличную часть "НастройкаОтбора" вместе с командной панелью.
4) Откроем свойства табличной части и в поле "Данные" выберем тип "КомпоновщикНастроек.Настройки.Отбор". Табличная часть примет вид как на рисунке ниже.
На панели формы создадим две кнопки "Сохранить" и "Восстановить настройки", а в модуле формы определим такой код:
Перем СКД ;
Перем мТекущаяНастройка ;
Процедура КнопкаВыполнитьНажатие ( Кнопка )
Продажи . Загрузить ( РезультатКомпоновкиВТЗ ( СКД , КомпоновщикНастроек ));
Процедура ПередОткрытием ( Отказ , СтандартнаяОбработка )
СохраненнаяНастройка = ?( ЗначениеЗаполнено ( НастройкаОтбора ), ЗначениеИзСтрокиВнутр ( НастройкаОтбора ),Неопределено);
КомпоновщикНастроек . Инициализировать (Новый ИсточникДоступныхНастроекКомпоновкиДанных ( СКД ));
Настройки = ?(НЕ СохраненнаяНастройка = Неопределено, СохраненнаяНастройка , СКД . НастройкиПоУмолчанию );
КомпоновщикНастроек . ЗагрузитьНастройки ( Настройки );
// Процедура восстановления сохраненных настроек
//
Процедура ВосстановитьНастройки () Экспорт
СтруктураНастройки = Новый Структура ;
СтруктураНастройки . Вставить ( "Пользователь" , глЗначениеПеременной ( "глТекущийПользователь" ));
СтруктураНастройки . Вставить ( "ИмяОбъекта" , Строка ( ЭтотОбъект ));
СтруктураНастройки . Вставить ( "НаименованиеНастройки" , ?( мТекущаяНастройка = Неопределено, Неопределено, мТекущаяНастройка . НаименованиеНастройки ));
Результат = УниверсальныеМеханизмы . ВосстановлениеНастроек ( СтруктураНастройки );
Если Результат <> Неопределено Тогда
мТекущаяНастройка = Результат ;
ВосстановитьНастройкиИзСтруктуры ( Результат . СохраненнаяНастройка );
// Процедура сохранения настроек
//
Процедура СохранитьНастройки () Экспорт
СтруктураНастройки = Новый Структура ;
СтруктураНастройки . Вставить ( "Пользователь" , глЗначениеПеременной ( "глТекущийПользователь" ));
СтруктураНастройки . Вставить ( "ИмяОбъекта" , Строка ( ЭтотОбъект ));
СтруктураНастройки . Вставить ( "НаименованиеНастройки" , ?( мТекущаяНастройка = Неопределено, Неопределено, мТекущаяНастройка . НаименованиеНастройки ));
СтруктураНастройки . Вставить ( "СохраненнаяНастройка" , СохраненнаяНастройка );
СтруктураНастройки . Вставить ( "ИспользоватьПриОткрытии" , Ложь);
СтруктураНастройки . Вставить ( "СохранятьАвтоматически" , Ложь);
Результат = УниверсальныеМеханизмы . СохранениеНастроек ( СтруктураНастройки );
Если Результат <> Неопределено Тогда
мТекущаяНастройка = Результат ;
Иначе
мТекущаяНастройка = СтруктураНастройки ;
КонецЕсли;
// Процедура восстановления значений реквизитов
//
Процедура ВосстановитьНастройкиИзСтруктуры ( СтруктураСНастройками ) Экспорт
Если ТипЗнч ( СтруктураСНастройками ) <> Тип ( "Структура" ) Тогда
Возврат;
КонецЕсли;
ЗаполнитьЗначенияСвойств ( ЭтотОбъект , СтруктураСНастройками );
ЗагрузитьНастройкуОтбора ();
// Процедура сохранения значений реквизитов
//
Процедура СформироватьСтруктуруДляСохраненияНастроек ( СтруктураСНастройками ) Экспорт
Если ТипЗнч ( СтруктураСНастройками ) <> Тип ( "Структура" ) Тогда
СтруктураСНастройками = Новый Структура ;
КонецЕсли;
СтруктураСНастройками . Вставить ( "НастройкаОтбора" , ЗначениеВСтрокуВнутр ( КомпоновщикНастроек . Настройки ));
СтруктураСНастройками . Вставить ( "НачалоПериода" , НачалоПериода );
СтруктураСНастройками . Вставить ( "КонецПериода" , КонецПериода );
Процедура ДействияФормыСохранитьНастройки ( Кнопка )
Процедура ДействияФормыВосстановитьНастройки ( Кнопка )
СКД = ПолучитьМакет ( "ПродажиЗаПериод" );
Функция РезультатКомпоновкиВТЗ ( СКД , КомпоновщикНастроек ) Экспорт
НастройкиКомпоновщика = КомпоновщикНастроек . Настройки ;
ПараметрыНастройки = НастройкиКомпоновщика . ПараметрыДанных ;
// устанавливаем параметры отчета
ЗначениеПараметра = ПараметрыНастройки . НайтиЗначениеПараметра (Новый ПараметрКомпоновкиДанных ( "НачалоПериода" ));
ЗначениеПараметра . Значение = НачалоПериода ;
ЗначениеПараметра = ПараметрыНастройки . НайтиЗначениеПараметра (Новый ПараметрКомпоновкиДанных ( "КонецПериода" ));
ЗначениеПараметра . Значение = КонецДня ( КонецПериода );
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных ;
МакетКомпоновкиДанных = КомпоновщикМакета . Выполнить ( СКД , НастройкиКомпоновщика . Тип ( "ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений" ));
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных ;
ПроцессорКомпоновкиДанных . Инициализировать ( МакетКомпоновкиДанных );
ТаблицаРезультат = Новый ТаблицаЗначений ;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений ;
ПроцессорВывода . УстановитьОбъект ( ТаблицаРезультат );
ПроцессорВывода . Вывести ( ПроцессорКомпоновкиДанных );
6) После запуска обработки можно установить параметры: начало и конец периода, а также определить отбор. Потом сохранить настройку. При последующей работе можно вернуться к этой настройке нажав кнопку восстановления настроек. Как это сделать показано на скриншоте.
Пример обработки можно скачать ЗДЕСЬ.
Читайте также: