Отборы в отчётах. Нюансы работы компоновщика настроек.

15.08.16

Разработка - Работа с интерфейсом

Открытие отчёта с предустановленным отбором, показанным пользователю. Изменение любых настроек в процессе работы отчёта. Взаимосвязи настроек.

Полагаю, нет нужды рассказывать, что такое СКД, компоновщик настроек и вообще весь набор объектов, предназначенных для работы с СКД. Основные направления использования, не считая хитрых действий в коде, это динамические списки и отчёты, причём в обоих случаях «за кадром» остаётся весьма существенный функционал. Мы зачастую даже не задумываемся, какова логика поведения и взаимосвязи всех участников процесса, т.к. обычно решаем достаточно простые задачи или полагаемся на умолчания платформы. Но, где есть умолчания, есть и внутренняя логика, эдакая «медвежья услуга» 1С, преодолеть плоды которой для достижения нужного эффекта иногда трудно и неочевидно, и при этом достаточно лишь правильно воспользоваться инструментарием.

Желающие могут пропустить части 1-4 и сразу перейти к примерам.

Попробую чуть более подробно остановиться на работе отборов СКД для случая их применения в отчётах. Полагаю, поведение в динамических списках, за рядом оговорок, будет близким. Итак, отборы в отчётах, немного теории и потом конкретные примеры.

Используются СП 8.3.6 и выше, разделы ИТС (пункт 10.3.7.5 и др.), книга «Профессиональная разработка в системе 1С-Предприятие 8» (Казань, 2012 г., второй том). В книге Е.Хрусталёвой вообще ничего внятного на эту тему не нашлось.

Часть 1

У компоновщика настроек, как известно, есть коллекции «Настройки», «Фиксированные настройки» (далее «ФН») и «Пользовательские настройки» (далее «ПН»). У отчёта может быть задано несколько вариантов, при этом связи между вариантом, Н, ПН и ФН весьма своеобразны. Также, не будем забывать об источнике доступных настроек, и его «прародителе», которым обычно бывает сама схема, тоже имеющая свои настройки по умолчанию.

* Настройки – настройки, созданные в режиме Конфигуратора и изменяемые в режиме правки варианта отчёта;

* ПользовательскиеНастройки – настройки, которые изменяет пользователь в режиме «1С:Предприятие» сугубо интерфейсно;

* ФиксированныеНастройки – те настройки, которые задаются из встроенного языка, в т.ч. неявно задаются системой. В это свойство попадают значения отбора, которые передаются в форму с помощью ее параметров (структура «Отбор»).

Настройки и ФН схожи по устройству и имеют коллекцию «Отбор» типа «Отбор компоновки данных», доступную для изменения состава в любое время существования отчёта. При этом Настройки доступны для интерфейсного изменения через правку варианта, а ФН вообще никак не доступны. ПН, в свою очередь, это «каша», где равноправными элементами могут быть как сам «Отбор», так и отдельные объекты типа «Элемент отбора компоновки данных» (т.н. вложенный объект). Несмотря на наличие соответствующих методов, изменять состав коллекции элементов ПН программно нельзя, если это ПН самого отчёта, а не сделанные «с нуля» конструктором – 1С сообщит, что «Коллекция пользовательских настроек не может изменять свой состав, так как она связана с настройками компоновки данных.» На ИТС сказано: «Свойство недоступно для записи с помощью встроенного языка.», но, как мы увидим позже, повлиять на ПН можно. «Каша» объектов имеет внутренние связи – она проверяется на непротиворечивость условий при формировании отчёта, и при изменении состава. На ИТС читаем: «Не будут добавляться элементы, которые сами отмечены как пользовательские. Например, в пользовательский отбор не будет помещен элемент отбора, который отмечен как пользовательский. Не будут добавлены элементы, содержащие пользовательские элементы. Например, не будет добавлена группа условий, если в этой группе присутствуют элементы, отмеченные как пользовательские. Для вложенных элементов свойство РежимОтображения не анализируется. Они добавляются или не добавляются вместе с родительскими элементами.» Таким образом, негласно действует «старшинство» объектов. При этом можно получить эффект, когда интерфейс позволит указать противоречивые отборы для варианта и его ПН, а также внутри ПН.

Казалось бы, «старшим» является вариант. Но нажатие на "Ещё"/"Изменить вариант" и подтверждение изменений в открывшейся форме вызывает обработчик события формы ПриОбновленииСоставаПользовательскихНастроекНаСервере, при этом отбор появляется в панели "Основные" на форме, вызываемой из "Настройки...", и появляется на форме отчёта, но НЕ показывается на закладке "Отбор"; причём либо он появляется сразу и на основной форме отчёта, и на форме по "Настройки..." (если есть флаг "Включать в пользовательские настройки"), либо ни там, ни там. Но в любом случае на закладке "Отбор" формы "Настройки..." его НЕ будет. Разница между закладкой "Основные" формой "Настройки..." и основной формой отчёта определяется полем "Режим редактирования" (обычный - только в "Настройках", быстрый - ещё и на самой форме отчёта), но это, думаю, все знают. Кстати, значения «Отбора» и «Быстрых» никак не синхронизированы и могут противоречить друг другу, а вот «Быстрый» на форме отчёта и на форме настроек жёстко синхронны. Так вот, при правке варианта он сам становится изменённым (но его ID и имя не меняются), а вот ПН остаются НЕ модифицированными (т.е. даже если речь о них, т.е. о флаге включения того или иного элемента в ПН).

Нажатие на "Выбрать вариант..." и подтверждение изменений в открывшейся форме вызывает в следующем порядке события:

ПередЗагрузкойВариантаНаСервере

ПриЗагрузкеВариантаНаСервере

ПередЗагрузкойПользовательскихНастроекНаСервере

ПриЗагрузкеПользовательскихНастроекНаСервере

ПриОбновленииСоставаПользовательскихНастроекНаСервере

При этом ни вариант, ни ПН ничем и никак не изменяются. Отсюда ясно, что вариант и настройки если и связаны, то отнюдь не напрямую.

Нажатие на "Настройки..." и подтверждение изменений в открывшейся форме вызывает только событие ПриОбновленииСоставаПользовательскихНастроекНаСервере (при этом ПН становятся изменены, но представления и ключа (если их не было) не получают; если включён «Быстрый» для элементов объекта «Отбор» ПН, то кроме "Отбор", появляются и собственно его элементы как поля, т.е. ведёт себя аналогично вложенным элементам. Эти сделанные настройки сохраняются при закрытии и восстанавливаются при следующем входе в форму. Вариант оно никак трогает и не меняет.

Нажатие на "Ещё"/"Установить стандартные настройки" в форме настроек (а также и пункт «Стандартные настройки» в правке варианта) вызывает только событие ПриОбновленииСоставаПользовательскихНастроекНаСервере. При этом вариант становится изменённым, а вот ПН меняются. Если перед этим вариант был изменён, он остаётся изменённым (ни сброса флага изменённости, ни сброса реально сделанных настроек не происходит).

Нажатие на «Свойства элемента пользовательских настроек" в дереве структуры на форме правки варианта добавляет объект "Отбор", и он получается пуст и никак не синхронизируется с уже имеющимся отбором варианта и имеющимися вложенным элементам отбора. Вариант при этом никак не меняется.

Отсюда рекомендация: если надо в режиме «Конфигуратор» задать некие отборы, чтобы не возиться с кодом и чтобы при этом их не было в варианте, но были бы в интерфейсе отчёта – следует манипулировать не элементами отбора варианта, меняя их свойства, а самим отбором, кнопками «Свойства элемента…» и «Пользовательские настройки».

Добавление чего-либо, появившегося в Настройках, в состав ПН, требует действий в коде или интерфейсе, а вот удаление и очистка Настроек сказываются на ПН сразу и безо всяких обновлений, например:

Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы.Очистить();

Перед закрытием формы отчёта система спрашивает, только если были изменения варианта. Если были изменения ПН, они сохранятся автоматически безо всяких вопросов, и так же автоматически попытаются примениться в следующем сеансе работы с отчётом.

Примечания:

При ряде ошибок именно применения настроек сначала выводится сообщение о проблеме, а потом всё равно происходит компоновка, вызов события ОбработкаПроверкиЗаполненияНаСервере и построение отчёта. При этом ФН, если они и были, всё равно игнорируются, и роль играют только Настройки.

При добавлении отбора на форме "Изменить вариант" он делается сразу с установленным флагом "Включать в ПН", но, повторюсь, с точки зрения встроенного языка ПН остаются неизменными.

Установка изменённости варианта и установка изменённости ПН не связаны напрямую, это два разных направления изменений.

У ПН, помимо прочего, есть «Дополнительные настройки». Мне никак не удалось понять, чем и в какой момент они заполняются. Хотя в отчёте и есть настройки, "отмеченные в отборе и условном оформлении" как пользовательские (согласно СП), но дополнительные настройки во всех случаях оказывались пусты. На ИТС об этом ничего.

Несмотря на утверждение в СП, ПН прекрасно сериализуются в xml.

Если включены к использованию и независимые элементы отбора, и сам отбор, то отчёт компонуется верно, но при показе задваивает информацию об установленном отборе в итоговом макете.

Генерируемая по умолчанию форма правки варианта отчёта содержит множество интересных вещей, но нигде не работает с ФН и ПН, да и с основными настройками работает больше на чтение (разве что очищает выбор, порядок, усл.оформление).

Часть 2

Работа с Настройками и ФН через их коллекцию почти всегда допустима, но важно помнить, что меняется сущность «третьего уровня». На первом уровне всегда находятся настройки самой СКД по умолчанию, они же фигурируют неявно в источнике доступных настроек; на втором уровне – настройки используемого варианта. Но тут логика позволяет либо «затереть» нижележащие указания, либо их проигнорировать. А вот работа с ПН вольностей уже не предусматривает, и тонкие манипуляции надо делать с помощью специальных методов, а иногда и временных вспомогательных объектов-посредников, например:

комп=Новый КомпоновщикНастроекКомпоновкиДанных;
// можно ещё для начала
// комп.Инициализировать(НекийКомпоновщикНастроек.ПолучитьИсточникДоступныхНастроек());
комп.ЗагрузитьНастройки(НекийКомпоновщикНастроек.Настройки);
НекийКомпоновщикНастроек.ЗагрузитьПользовательскиеНастройки(комп.ПользовательскиеНастройки);

У компоновщика настроек имеется метод ЗагрузитьПользовательскиеНастройки(), который загружает значения пользовательских настроек, переданные в качестве параметра метода. Метод ПолучитьНастройки() позволяет получить копию текущих настроек (с учетом пользовательских настроек). Метод ЗагрузитьНастройки() загружает переданные настройки в компоновщик настроек (пользовательские настройки также перезаполняются на основании переданных данных, с учётом наличия ключей, см. пример ниже).

Применение пользовательских настроек к основным настройкам выполняется в методе ПолучитьНастройки() компоновщика настроек. При этом выполняются следующие действия:

* Для типов ЭлементОтбораКомпоновкиДанных содержимое элементов копируется в соответствующие пользовательские элементы настроек.

* Для типов ОтборКомпоновкиДанных элементы, находящиеся в основных настройках и отмеченные как Недоступный, остаются без изменения. Элементы из ПН переносятся в основные. Они добавляются в конец коллекции для Отбора.

* Для типов ГруппаЭлементовОтбораКомпоновкиДанных устанавливается свойство Использование в соответствующем элементе основных настроек (на основании признака использования элемента ПН).

Часть 3

При формировании окончательной настройки, если цитировать ИТС, различные варианты настроек комбинируются следующим образом:

* Если какой-либо вид настроек целиком отмечен как пользовательский, то в результирующие настройки попадают ПН. При этом, если какие-либо элементы настроек отмечены как недоступные, то эти настройки будут помещены в результирующие настройки из свойства КомпоновщикНастроек.Настройки.

* Если какой-либо вид настроек отмечен как пользовательский не целиком, а поэлементно, то элементы, отмеченные как пользовательские, попадут в результирующие настройки из свойства КомпоновщикНастроек.ПользовательскиеНастройки, а элементы, отмеченные как недоступные, будут взяты в результирующие настройки из свойства КомпоновщикНастроек.Настройки.

* Фиксированные настройки добавляются в результирующие настройки «как есть». При этом недопустима ситуация, когда в ФН и ПН есть одноименные настройки, например отбор с одинаковым левым значением в условии. Замечу, что даже полнейшее совпадение всех свойств этих условий запрещено. Честно говоря, несколько нелогично.

Замечу, что, если какой-либо фрагмент настроек подпадает под действие функциональной опции и должен быть ограничен, система работает «втихую» - убирает этот фрагмент отовсюду, ничего не сообщает, а при программных манипуляциях, касающихся такого фрагмента, отрабатывает «вхолостую» - ошибок не выдаёт, но и эффекта от кода никакого. Впрочем, возможно, разные релизы ведут себя по-разному.

Часть 4.

Расширение формы отчёта предоставляет нам параметры «ФН» и «ПН», однако нигде не рекомендуется заполнять их напрямую, передавая в форму. Как показали эксперименты, без дополнительных танцев с бубном наполнение этих параметров игнорируется – оно затирается при инициализации компоновщика в процессе открытия и при получении ранее сохранённых ПН. Рекомендуется работать с ключами ПН, по которым получать их из хранилища настроек и уже тогда раскрывать и использовать, и делается это автоматически на стороне формы отчёта, а не вызывающей формы.

Параметр «ИсточникДоступныхНастроек» автоматически транслируется в сведения компоновщика уже при создании формы на сервере и переопределяться не может. Вернее, может, но эффект это даст только после полного переопределения всей цепочки связанных объектов. При этом ПолучитьИсточникДоступныхНастроек() вплоть до конца отработки всех событий открытия формы будет возвращать Неопределено.

Замечу, что параметры формы, по сути не являющиеся ключевыми, «растягивают» своё действие на несколько событий, если установлен флаг формирования при открытии. Так, в событии ОбработкаПроверкиЗаполненияНаСервере, вызванном при открытии и формировании, параметр «Отбор» будет доступен, а при нём же, но вызванном просто нажатием пользователя на кнопку «Сформировать» - уже нет. Связано это с тем, что все эти события отрабатывают за одно «посещение» сервера, если формирование при открытии включено, и только в самом их конце управление передаётся на клиент и вызывается ПриОткрытии. При этом неключевые параметры, естественно, теряются.

Общий порядок выполнения событий при открытии формы с флагом формирования отчёта при открытии (несколько больше, чем описано в «Проф.разработке»):

ПриСозданииНаСервере

ПередЗагрузкойВариантаНаСервере

ПриЗагрузкеВариантаНаСервере

ПередЗагрузкойПользовательскихНастроекНаСервере

ПриЗагрузкеПользовательскихНастроекНаСервере

ПриОбновленииСоставаПользовательскихНастроекНаСервере

ОбработкаПроверкиЗаполненияНаСервере

ПриОткрытии

При этом ни вариант, ни ПН не являются изменёнными, если не предпринимались специальные усилия.

Часть 5.

Теперь остановимся более подробно на задаче открытия формы отчёта с его построением и предварительно указанным отбором. Краткие сведения об этом есть на ИТС и в методических рекомендациях, но там освещён только сам принцип и не раскрыты тонкости. Итак, для контекстного вызова отчёта необходимо передать его форме параметр «СформироватьПриОткрытии», равный Истина; и параметр «Отбор», содержащий структуру. Ключи структуры – это имена полей СКД или параметров СКД, а значения и есть их значения. Цитируя СП, если есть параметр СКД с именем, соответствующим имени ключа структуры, то значение будет установлено ему. Если параметра нет, но есть поле, то будет добавлен отбор на это поле. При этом, если есть одноимённые параметр и поле, то система просто тихо это проигнорирует и не установит ничего.

В «Проф.разработке» приведён пример изменения (т.е. перехвата и перенастройки) ПН «на лету» в событии ПередЗагрузкойПользовательскихНастроекНаСервере, куда передаётся аргумент, содержащий текущие ПН. На самом деле это не всегда так – например, возможны случаи, когда ошибка сохранения ПН в предыдущем сеансе, или противоречия между Настройками, ФН и ПН приведут к тому, что аргумент «Настройки» будет пуст. И что самое интересное, полноценно перенастроить его в этом событии не удастся, это можно сделать только «в конце» последовательности событий, а именно, в событии ОбработкаПроверкиЗаполненияНаСервере.

Посмотрим, что мы имеем перед загрузкой ПН на сервере.

Для простого случая, когда в СКД ничего не предзадано и никакие элементы не включены в ПН, ситуация такова: Настройки – пусты; ФН – содержат правильный отбор; ПН содержат пустой Отбор. Формирование работает правильно, но с точки зрения пользователя интерфейс противоречит внутренностям и обескураживает – отбор работает, но не виден. Аналогично, если в настройках структуры варианта включить Отбор в ПН, отчёт также строится с учётом отбора, но пользователь также не видит никакие отборы.

Зададим в настройках СКД в Конфигураторе предотборы (равные пустым значениям) и включим их в ПН. По идее, ФН должны заполнить Настройки, а те – ПН, но на самом деле имеем: в Настройках – Отбор с нужным элементом, но пустым правым значением, ФН – содержат правильный отбор, а ПН – всё равно не содержат ничего. Вдобавок, в этом случае и отчёт не построится, т.к. правое значение отбора пусто, несмотря на переданное в параметре Отбор значение.

Попытка поработать с элементами ПН также не даёт результата. Для элемента ПН можно изменить разве что флаг «Использование» и участие в «Быстрых». Значение отбора на интерфейсе будет пустым, никаких ошибок система не выдаст. Аналогично, попытка поработать с Отбором ПН также отработает, в отладчике правое значение будет видно как верно заполненное, но на интерфейсе вы не увидите ничего. А менять состав ПН, напомню, нельзя. Таким образом, требуются дополнительные ухищрения. Например:

&НаСервере
Процедура УстановитьПредзаданныеОтборы(ПользНастройки)
	Если не Параметры.Свойство("Отбор") Тогда Возврат КонецЕсли;
	Если Параметры.Отбор.Количество()=0 Тогда Возврат КонецЕсли;
	
	рТипЭО=Тип("ЭлементОтбораКомпоновкиДанных");
	
	Для каждого киз Из Параметры.Отбор Цикл
		рПоле=Новый ПолеКомпоновкиДанных(киз.Ключ);
		//
		Если (ТипЗнч(киз.Значение)=Тип("Массив") или ТипЗнч(киз.Значение)=Тип("СписокЗначений")) и киз.Значение.Количество()>1 Тогда
			рВидСравнения=ВидСравненияКомпоновкиДанных.ВСписке;
		Иначе
			рВидСравнения=ВидСравненияКомпоновкиДанных.Равно;
		КонецЕсли;
		//
		рНужныйОтбор=Неопределено; // смотрим, есть ли Отбор в польз.настройках
		рНужныйЭО=Неопределено; // смотрим, есть ли отдельный ЭлементОтбораКомпоновкиДанных в польз.настройках
		Для каждого элнастр Из ПользНастройки.Элементы Цикл
			Если ТипЗнч(элнастр)=Тип("ОтборКомпоновкиДанных") и рНужныйОтбор=Неопределено Тогда // он может быть только один
				рНужныйОтбор=элнастр; // это можно было бы делать и вне цикла, но перебирать польз.настройки надо и ради элементов...
			ИначеЕсли ТипЗнч(элнастр)=рТипЭО Тогда 
				// это элемент отбора, их может быть много, но нас интересуют не инициализированные или с нужным полем
				Если элнастр.ЛевоеЗначение=рПоле или элнастр.ЛевоеЗначение=Неопределено и рНужныйЭО=Неопределено Тогда
					рНужныйЭО=элнастр;
				КонецЕсли;				
			КонецЕсли;
		КонецЦикла;
		//
		Если рНужныйОтбор<>Неопределено Тогда // он идёт как приоритетный
			рНужныйЭОизОтбора=Неопределено;
			Для каждого элотб Из рНужныйОтбор.Элементы Цикл
				Если элотб.ЛевоеЗначение=рПоле Тогда рНужныйЭОизОтбора=элотб; Прервать КонецЕсли;
			КонецЦикла;
			Если рНужныйЭОизОтбора=Неопределено Тогда
				рНужныйЭОизОтбора=рНужныйОтбор.Элементы.Добавить(рТипЭО);
				рНужныйЭОизОтбора.ЛевоеЗначение=рПоле;
			КонецЕсли;
			рНужныйЭОизОтбора.ВидСравнения=рВидСравнения;
			рНужныйЭОизОтбора.ПравоеЗначение=киз.Значение;
			рНужныйЭОизОтбора.Использование=Истина;
			//
			рНужныйЭО.Использование=Ложь;
		ИначеЕсли рНужныйОтбор=Неопределено и рНужныйЭО<>Неопределено Тогда // ставим на элемент
			рНужныйЭО.ЛевоеЗначение=рПоле;
			рНужныйЭО.ВидСравнения=рВидСравнения;
			рНужныйЭО.ПравоеЗначение=киз.Значение;
			рНужныйЭО.Использование=Истина;
		КонецЕсли;
		
		рНужный=Неопределено;
		Для каждого элотб Из Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл // по-хорошему, тут должен быть рекурсивный поиск!
			Если ТипЗнч(элотб)=рТипЭО и элотб.ЛевоеЗначение=рПоле Тогда рНужный=элотб; Прервать КонецЕсли;
		КонецЦикла;
		Если рНужный=Неопределено Тогда
			рНужный=Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(рТипЭО);
			рНужный.ЛевоеЗначение=рПоле;
		КонецЕсли;
		рНужный.ВидСравнения=рВидСравнения;
		рНужный.ПравоеЗначение=киз.Значение;
		рНужный.Использование=Истина;
		//
	КонецЦикла;
	
	Отчет.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Очистить(); // иначе скажет, что элементы пересекаются/противоречат
	
КонецПроцедуры

Вызывать это наиболее правильно так:

&НаСервере
Процедура ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)
	УстановитьПредзаданныеОтборы(Отчет.КомпоновщикНастроек.ПользовательскиеНастройки);
КонецПроцедуры

Тогда, контекстный вызов, например, из формы справочника, будет выглядеть так:

&НаКлиенте
Процедура ОткрытьОтчет(Команда)
	Если ЗначениеЗаполнено(Объект.Ссылка) Тогда
		отб=Новый Структура("СсылкаНаСправочник",Объект.Ссылка); // так поле названо в СКД отчёта
		ПараметрыФормы=Новый Структура("Отбор,СформироватьПриОткрытии",отб,Истина);
		ОткрытьФорму("Отчет.Отчет1.Форма.ФормаОтчета",ПараметрыФормы,ЭтаФорма);
	КонецЕсли;	
КонецПроцедуры

Часть 6.

При необходимости менять настройки отчёта в процессе работы с ним, в т.ч. и при запуске, и после открытия, наиболее правильным способом представляется изменение «от начала», т.е. от настроек СКД. Изменение схемы СКД выполняется только с объектом Отчёт (или ВнешнийОтчёт), а не с данными формы, и само по себе ничего не меняет - в Настройках и в ПН остаётся то же, что и было, а ФН вообще могут оставаться пусты. Поэтому, в зависимости от наших задач:

После выполнения

Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(СКД.НастрПоУмолч)

изменяется только вариант, и ничего более;

После выполнения приёма, приведённого в п.2 (с использованием «посредника» и метода ЗагрузитьПользовательскиеНастройки()

срабатывает, только если сбросить текущие ПН средствами интерфейса. Сами  по себе они, при изменении варианта, не изменятся. При этом меняется Отбор, но не добавляется новый ЭлементОтбора.

После выполнения

ЭтаФорма.СоздатьЭлементыФормыПользовательскихНастроек(,РежимОтображенияНастроекКомпоновкиДанных.Все)

платформа просто тихо падает. Проверено на нескольких разных релизах. А вызов с режимом отображения настроек только для быстрых не имеет смысла – мы же не повлияли на их состав, поэтому ничего всё равно не изменится.

А поскольку нам всё-таки нужно полноценно изменить не только внутренние отборы, но и отображение на форме отчёта и в связанных формах, то либо приходится менять только Отбор, либо действовать следующим образом:

&НаСервере
Процедура ИзменитьСКД()
	рОбъект=РеквизитФормыВЗначение("Отчет");
	отб=рОбъект.СхемаКомпоновкиДанных.ВариантыНастроек.Получить(0).Настройки.Отбор;
	эо=отб.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	эо.ЛевоеЗначение=Новый ПолеКомпоновкиДанных("СсылкаНаСправочник.Поле1");
	эо.ВидСравнения=ВидСравненияКомпоновкиДанных.Равно;
	эо.ПравоеЗначение=Истина;
	эо.Использование=Истина;
	ЗначениеВРеквизитФормы(рОбъект,"Отчет");
	
	Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(рОбъект.СхемаКомпоновкиДанных.НастройкиПоУмолчанию);
	Отчет.КомпоновщикНастроек.Восстановить(); // желательно, хотя ФН это всё равно не затрагивает.
	
        // собственно, именно это можно назвать изменением состава ПН
	Для каждого эл Из Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
		эл.РежимОтображения=РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ;
		Если ПустаяСтрока(эл.ИдентификаторПользовательскойНастройки) Тогда
			// можно для элемента ПН использовать метод эл.УстановитьИдентификатор, см.его справку в СП, там всё достаточно внятно
			эл.ИдентификаторПользовательскойНастройки="ID123"; // важно - идентификатор может быть ЛЮБЫМ, не UUID и не GUID!
			эл.ПредставлениеПользовательскойНастройки="Проба";
		КонецЕсли;		
	КонецЦикла;
	
	комп=Новый КомпоновщикНастроекКомпоновкиДанных;
	комп.ЗагрузитьНастройки(рОбъект.СхемаКомпоновкиДанных.НастройкиПоУмолчанию);
	Отчет.КомпоновщикНастроек.ЗагрузитьПользовательскиеНастройки(комп.ПользовательскиеНастройки);
	
	Для каждого эл Из Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы Цикл
		эл.РежимОтображения=РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ; // вытащим на форму отчёта
	КонецЦикла;
	
	// и вот теперь это даст эффект:
	ЭтаФорма.СоздатьЭлементыФормыПользовательскихНастроек(,РежимОтображенияНастроекКомпоновкиДанных.БыстрыйДоступ);
КонецПроцедуры

Собственно, изучать эту механику можно ещё долго. Эта публикация выросла из изучения способов решения одной конкретной проблемы, и поэтому весьма однобокая; но подоздреваю, что о внутренней логике настроек, особенно пользовательских, вообще можно написать отдельную книгу не тоньше, чем хрусталёвская. У меня на это, к сожалению, сил и времени нет. Кому пригодятся конкретные наработки - уже хорошо.

Кое-что выяснено экспериментально и потому спорно. Знающие больше - приглашаются критиковать и комментировать.

Построение отчетов настройкка отчетов СКД компоновщик настроек отбор отбор СКД фиксированные настройки пользовательские настройки

См. также

Богатый редактор картинок, хранимых в базе, с возможностью РИСОВАНИЯ. Редактор внешних файлов картинок. Объект, расширяющий возможности работы с картинками из встроенного языка (Три в одном) + Обработка «Стандартизация картинок»

Работа с интерфейсом Рабочее место Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Обработка предназначена для редактирования картинок в режиме «Предприятие», с возможностью РИСОВАТЬ на них. Поддерживается работа как в обычных формах (толстый клиент) так и на управляемых формах (тонкий клиент). Обработка позволяет редактировать как картинки, хранимые в базе, так и графические файлы с диска на файловой системе. Помимо базовых функций (изменение размеров, преобразование формата, обрезание картинки, повороты и т.п.) – редактор имеет богатый набор инструментов для рисования. Доступна функция вставки изображения из буфера обмена. Также обработка может быть использована из встроенного языка как объект для редактирования картинок. Объект может быть использован: на стороне клиента, на стороне сервера, из внешнего соединения. Данная обработка будет особенно полезна тем, кто вносит картинки в базу (изображения номенклатуры, фотографии физических лиц и т.п.). Функционал реализуется с использованием JavaScript и бесплатного ПО ImageMagick (без использования внешних компонент).

6000 руб.

16.01.2015    61699    43    59    

80

[Расширения] Динамическое управление видимостью и доступностью элементов форм (УФ) (8.3.6+)

Работа с интерфейсом Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Механизм «Динамическое управление доступом к элементам форм объектов 1С8» предназначен для обеспечения возможности оперативного управления видимостью и доступностью элементов форм документов и справочников продуктов фирмы «1С» «1С:Предприятие 8». Решение универсальное, встраивается в любую конфигурацию с минимальными доработками, что позволяет без проблем обновлять типовые решения.

5000 руб.

14.01.2016    54316    16    21    

42

Управление дашбордами

Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Обработка предназначена для создания и управления дашбордами.

2400 руб.

29.06.2020    16623    21    4    

35

Новогоднее оформление для 1С

Работа с интерфейсом Платформа 1С v8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 Бесплатно (free)

Добавьте новогоднего настроения! Расширение создает декорацию в виде гирлянды на некоторых формах объектов.

27.12.2023    10564    745    elcoan    45    

106

Конструктор HTML, CSS и javascript

Инструментарий разработчика Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Подходит для создания web-страниц для замены управляемых форм 1С, красивых отчетов, интерфейса мобильного приложения на платформе 1С и для простых страниц веб-сайтов.

2 стартмани

10.04.2023    9485    150    acces969    31    

115

Модель состояния для MVC

Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

"MVC плохо применима в 1С" - познакомьтесь с моделью состояния и, возможно, ваше мнение поменяется! Представленное решение является эволюционным развитием идеи реализации MVC для 1С. В новой версии добавлены DSL для описания модели состояния, а также параметризация свойств параметров и элементов формы.

1 стартмани

05.07.2022    3577    kalyaka    2    

27

Табло очереди заказов на экран телевизора

WEB-интеграция Работа с интерфейсом Платформа 1С v8.3 1С:Розница 2 Платные (руб)

Связка из веб-приложения и расширения для 1С: Розница 2.3.

3600 руб.

29.04.2022    12010    1    5    

10
Вознаграждение за ответ
Показать полностью
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. director04 3657 16.08.16 07:28 Сейчас в теме
До сей статьи каша в голове (по поводу отборов компоновки данных) была, но не очень густая.
После прочтений половины (до конца не дошел - голова закружилась и мысль убежала на переферию) каша в голове загустела, и появилось раздражение ....
На мой взгляд, статье не хватает систематичности и пунктуальности.

Автор и другие читари, могут со мною не согласится. У каждого свое мнение.
ikalmykia; SagittariusA; androidT1C; Aleksandr_prof; kalyaka; paxan; nikitan; An-Aleksey; egorious; al_zzz; klmop; Suslik_Johns; HiGHT; kuzyara; igormiro; LeXXeR; HystriX; dj_serega; корум; Lisena_Xitrena; kasper076; jaroslav.h; Makushimo; Solovyeff; dabu-dabu; alest; sigmov; SuhoffGV; rozer; Сурикат; ixijixi; mszsuz; Yashazz; Alien_job; A56; +35 Ответить
18. StudentM 49 09.02.18 20:09 Сейчас в теме
(1) Валерий, в первом комментарии, я бы поблагодарил бы автора за поднятие такой важной и интересной темы! А разбираться с настройками СКД следует "с карандашом и калькулятором", т.е. постепенно и тщательно. В том числе с привлечением отладчика, СП, ИТС (Руководство разработчика), книг Проф Разработка и книг Елены Юрьевны Хрусталёвой (например, Разработка сложных отчётов Глава 3 Справочник разработчика - Настройки отчета).
2. Yashazz 4707 16.08.16 10:28 Сейчас в теме
Так я и сам соглашусь. Только - в чём беда - любое увеличение систематичности приводит к необходимости раскатать это на вдвое-втрое больший объём, или оставить некоторые вещи неосвещёнными совсем. Ну и пришлось бы гораздо больше копипастить общедоступные ресурсы, а я этого не люблю и потому пропустил.

Сам понимаю, что каша. Подступался несколько раз, довёл хотя бы до такого вида.

А вот про пунктуальность не понял, поясните.
polyusgold; +1 Ответить
3. maxx 991 16.08.16 20:24 Сейчас в теме
Может блок - схемы или mind-карты добавить
4. Yashazz 4707 16.08.16 21:26 Сейчас в теме
(3) maxx, как вариант, можно) Я хотел, кстати, графическую схемку набросать об этом всём, но - честно - просто не успел. Выходные кончились(( Авось осилю чуть позже...
5. SuhoffGV 17.08.16 15:26 Сейчас в теме
(3) maxx, Или популярные кейсы описать. Читать очень тяжело.
6. i.kovtun 180 19.08.16 20:58 Сейчас в теме
Мне кажется, нужно всегда с mind-карты начинать. Во вступлении нужно определить цели статьи, сформулировать задачи. Затем расписать пути решения, входящие в них этапы. Подвести итоги и сделать выводы. Все как всегда: завязка, развязка, кульминация:) Кстати, если таким образом подойти к предмету, тогда у разделов появятся "говорящие" заголовки, а не номера.
И еще, мне также кажется, что лучше не злоупотреблять сложноподчиненными предложениями, это сбивает темп чтения. Не стоит заворачивать неоформленную мысль в одно длинное предложение. Лучше пару минут подумать и написать несколько простых фраз.
7. Yashazz 4707 21.08.16 10:38 Сейчас в теме
(6) i.kovtun, насчёт неоформленной мысли не совсем понял. Если я нечто пишу, следовательно, имею целиком и полностью оформленную мысль. К длине и сложности выстраиваемых предложений это не имеет ни малейшего отношения.

Что до остального, то:
1. Это не статья как таковая. Это заметки.
2. Чем, на ваш взгляд, цели отличаются от задач?
3. Пути решения и их этапы - это практика. Вы предлагаете выкинуть теорию и демонстрировать "голые" примеры?
8. Aphanas 92 01.10.16 17:30 Сейчас в теме
Автор, нужен ВЫВОД. Вывода нет, непонятно о чем разговор. Я ньюансы знаю, интересно только к чему ты пришел.
9. Yashazz 4707 01.10.16 21:57 Сейчас в теме
(8) Aphanas, не может быть никакого единого вывода. Это всё равно, что спросить "какой вывод из 1С?" Ну вот, я для себя сделал вывод, что эта часть системы весьма разветвлённая, местами избыточная и переусложнённая, и недостаточно документирована и снабжена примерами. Так пойдёт?))
user774630; +1 Ответить
10. zqzq 23 03.10.16 08:37 Сейчас в теме
Как-то сумбурно. Хотелось бы разбить на подразделы: 1.1. Конкретная задача - 1.2. Код решения - 1.3. Теоретическое объяснение решения.

Например, если нужно из текущего отчета открыть другой отчет и передать туда параметр(ы) с возможностью изменения я поступаю просто:
	Парам = Новый Структура;
	Парам.Вставить("КлючВарианта", "Основной"); 
	Парам.Вставить("КлючНазначенияИспользования", "РасшифровкаИз");
   
	НоваяФорма = ПолучитьФорму("Отчет.НекийОтчет.Форма", Парам, ЭтаФорма);
		
	//Передаём в новую форму период отчета (так, чтобы отображался пользователю)
	НоваяФорма.Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(
		НоваяФорма.Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(
		Новый ПараметрКомпоновкиДанных("ПериодОтчета")).ИдентификаторПользовательскойНастройки).Значение 
		= ЭтаФорма.Отчет.КомпоновщикНастроек.ПолучитьНастройки().ПараметрыДанных
		.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПериодОтчета")).Значение;	
		
	НоваяФорма.Открыть();	
	НоваяФорма.СкомпоноватьРезультат(РежимКомпоновкиРезультата.Авто);	
Показать
Может, не по фен-шую, зато работает и есть не просит.


Lisena_Xitrena; +1 Ответить
25. maxis33 45 12.01.23 15:36 Сейчас в теме
(10)
Парам = Новый Структура;
Парам.Вставить("КлючВарианта", "Основной");
Парам.Вставить("КлючНазначенияИспользования", "РасшифровкаИз");

НоваяФорма = ПолучитьФорму("Отчет.НекийОтчет.Форма", Парам, ЭтаФорма);

//Передаём в новую форму период отчета (так, чтобы отображался пользователю)
НоваяФорма.Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(
НоваяФорма.Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(
Новый ПараметрКомпоновкиДанных("ПериодОтчета")).ИдентификаторПользовательскойНастройки).Значение
= ЭтаФорма.Отчет.КомпоновщикНастроек.ПолучитьНастройки().ПараметрыДанных
.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПериодОтчета")).Значение;

НоваяФорма.Открыть();
НоваяФорма.СкомпоноватьРезультат(РежимКомпоновкиРезультата.Авто);
Показать

Спасибо вам, добрый человек! Как раз искал это решение.
11. Makushimo 160 03.10.16 14:14 Сейчас в теме
очень тяжело читать.
Заметки или теория, но текст мертвый, как латынь.
HiGHT; JohnConnor; xforestyg; +3 Ответить
12. sml 41 19.05.17 09:44 Сейчас в теме
ДД, Процедура ИзменитьСКД() в каком месте вызывается?
13. HEKPOH 76 19.05.17 11:51 Сейчас в теме
14. dctvghbdtn 07.06.17 11:20 Сейчас в теме
Посоветуйте пожалуйста как поступить.

Есть отчет в ЗУП, Табель учета рабочего времени. Подписывает его Руководитель. Программа ставит руководителя предприятия. Нас это не устраивает.

Есть желание вывести на форму отчета параметр для заполнения, кодом его отловить и обработать для вывода на печать.

Просто на форму отчета вынести реквизит нельзя. Т.к. это общая форма для всех отчетов, а сам отчет формируется в модуле объекта отчета.

Было принято решение добавить этот параметр в СКД программно и потом его уже обрабатывать, по аналогии с параметром Ответственный того же отчета.

Параметр допустим называется Руководитель.

В СКД вроде как бы все хорошо добавляется на начальном этапе, но потом все затирается, не пойму где. :(

Добавил в общую форму ФормаОтчета в процедуру ПередЗагрузкойПользовательскихНастроекНаСервере код:

ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
	
ПараметрРуководительПодразделения = ОтчетОбъект.СхемаКомпоновкиДанных.Параметры.Добавить(); 
ПараметрРуководительПодразделения.Имя = "Руководитель";
ПараметрРуководительПодразделения.Заголовок = "Руководитель";
ПараметрРуководительПодразделения.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.Сотрудники");
ПараметрРуководительПодразделения.ОграничениеИспользования = Ложь;
ПараметрРуководительПодразделения.Значение = Справочники.Сотрудники.ПустаяСсылка();
ПараметрРуководительПодразделения.Использование = ИспользованиеПараметраКомпоновкиданных.Всегда;
ПараметрРуководительПодразделения.ВключатьВДоступныеПоля = Истина;
	
мПараметрРуководительПодразделения = ОтчетОбъект.СхемаКомпоновкиДанных.ВариантыНастроек.УнифицированнаяФормаТ13.Настройки.ПараметрыДанных.Элементы.Добавить(); 
мПараметрРуководительПодразделения.Параметр = Новый ПараметрКомпоновкиДанных("Руководитель");
мПараметрРуководительПодразделения.Использование = Истина;
мПараметрРуководительПодразделения.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ;
мПараметрРуководительПодразделения.ИдентификаторПользовательскойНастройки = Новый УникальныйИдентификатор;
мПараметрРуководительПодразделения.Значение = Справочники.Сотрудники.ПустаяСсылка();
	
Отчет.КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ОтчетОбъект.СхемаКомпоновкиДанных));
Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(ОтчетОбъект.СхемаКомпоновкиДанных.НастройкиПоУмолчанию);
	
ЭтаФорма.СоздатьЭлементыФормыПользовательскихНастроек(, РежимОтображенияНастроекКомпоновкиДанных.БыстрыйДоступ);

Показать


На форме появляется параметр, в СКД он как бы тоже есть, но при формировании отчета параметр пропадает и при нажатии кнопки Настройка тоже из интерфейса исчезает. :(
15. IrinaKostroma 12.09.17 19:41 Сейчас в теме
Молодец, что написал! Критиковать легко, а хоть какие то свои мысли и заметки написать не каждый может
Designer1C; StudentM; +2 Ответить
16. o.nikolaev 211 01.11.17 20:58 Сейчас в теме
Шикарная статья! Спасибо!
Designer1C; VKislitsin; +2 Ответить
17. leshiy26 147 12.01.18 23:07 Сейчас в теме
Для себя выделил:
- Пользовательские настройки - программно не трогаем. На то они и пользовательские.
- Если нужно заполнить какие-то настройки / отборы программно - используем событие формы ПриОбновленииСоставаПользовательскихНастроекНаСервере(), заполняем напрямую Отчет.КомпоновщикНастроек.Настройки.
- Если нужно открыть форму с заполненными настройками- передаем значения в параметрах
20. PerlAmutor 129 12.04.18 11:42 Сейчас в теме
(17)
ПриОбновленииСоставаПользовательскихНастроекНаСервере

Это событие вызывается при каждом чихе. Пытался заполнять пользовательские настройки по этому события через ПередЗаполнениемПанелиБыстрыхНастроек / ПослеЗаполненияПанелиБыстрыхНастроек в модуле отчета. В итоге это событие вызывается при нажатии на кнопку "Настройки" формы отчета, при смене вкладок этой формы, при закрытии этой формы настроек. И при этом фактически пользователь не меняет ни одну из настроек. Если в обработчике этого события идет тяжелый запрос к БД, то понятно к чему это все приводит.
Пробовал ставить настройки в событии ПриЗагрузкеВариантаНаСервере, настройки пользователя ставятся ровно 1 раз до выхода из формы. Затем они всегда перезаполняются поверх этих настроек повторно из пользовательских сохраненных в прошлый раз. С одной стороны логично, что пользователю могут не нравится предустановленные изначально параметры и т.д. А с другой - хочется контролировать то, что он там навыбирал и поправить в случае необходимости.
19. Yashazz 4707 10.02.18 18:45 Сейчас в теме
На самом деле если нужно открыть форму с такими настройками, чтобы было видно пользователю, например, форму динамического списка, то это именно пользовательские настройки надо делать, добавлять туда элементы отбора или сам отбор. В этом смысле Настройки или Отбор ничего не покажут юзеру, их не видно. И вообще они очень непрозрачно накладываются друг на друга.
В своё время общался с Белоусовым на эту тему, он так прямо и сказал, что доделывали платформу в несколько заходов, поэтому получилась дикая неоднозначность и путаница, но теперь уж как есть (((
21. gubanoff 63 17.08.18 17:32 Сейчас в теме
(19) Хочу добавить отбор динамического списка, чтобы был виден на форме, как вы и пишете.
Делаю так:
	ПользовательскийОтбор = Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(Список.КомпоновщикНастроек.Настройки.Отбор.ИдентификаторПользовательскойНастройки);
	ПользовательскийОтбор.Элементы.Очистить();
	ЭлементОтбора = ПользовательскийОтбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ответственный");
	ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ЭлементОтбора.Использование = Истина;
	ЭлементОтбора.ПравоеЗначение = "";
Показать


Эффекта 0. Отбор появляется в меню Все действия - настроить список, на на самом списке не виден, пока интерактивно не поставишь ему "Включать в пользовательские настройки". Что я делаю не так?
22. e.kogan 1892 24.08.18 15:46 Сейчас в теме +50 $m
А ещё очень "красиво" бывает в динамических списках, типа всеми любимых журналов документов в типовых. Добавил пользователь отбор: Контрагент Равно ... - и у него над списком сразу поле, удобно, быстро. Добавил, например, Склад Равно ... - тоже збс.

А потом объединил через настройку списка в "Или".
И забыл.

А поля остались как были, над списком.

"У меня эта ваша 1С не работает!"
23. TanyTany 17.10.18 01:20 Сейчас в теме
Спасибо за подробнейшие детали! Особенно за
Отчет.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Очистить(); // иначе скажет, что элементы пересекаются/противоречат
24. mopok 28.05.21 09:33 Сейчас в теме
(21)

	Для Каждого Элемент из Список.КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
		Элемент.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ;
		Если ПустаяСтрока(Элемент.ИдентификаторПользовательскойНастройки) Тогда
			Элемент.ИдентификаторПользовательскойНастройки = "Ответственный";
			Элемент.ПредставлениеПользовательскойНастройки = "Ответственный";
		КонецЕсли;		
	КонецЦикла;	


        ЭтаФорма.СоздатьЭлементыФормыПользовательскихНастроек(,РежимОтображенияНастроекКомпоновкиДанных.БыстрыйДоступ);	

Показать
Оставьте свое сообщение