Забегая вперед: если бы подобный запрос с компоновщиком был всего один, то задача бы существенно упростилась:
- Создаем новый внешний отчет
- В нем формируем нужную основную СКД
- Далее на форме используем стандартный компоновщик, который уже имеет свой набор вариантов отчета, и самое главное: стандартную интерактивную "рулилку вариантов": когда можно добавить/удалить/сохранить вариант.
Отчет с СКД: отбор на форме, вывод в ТЗ
- Создаем отчет с СКД
- Создаем новую форму, либо пользуемся конструктором и выкидываем ненужные элементы
- На форме выкладываем то, что нужно для отбора СКД: это могут быть "параметры данных" и "отбор" СКД:
- Для управления вариантами отчета можно сделать подменю и перетянуть в него стандартные команды:
- В режиме 1С-предприятия результат будет примерно таким:
- Создаем ТЗ в конфигураторе на форме: предположим, что это простая таблица с 1-ой стандартной колонкой "Пометка" (на форме будет таблица с галочкой)
- Для вывода в ТЗ Используется "нехитрый" код, исполняющий результат СКД в объект ТЗ, а затем выводящий полученное ТЗ на форму отчета
Вывод результата СКД в таблицу на форме
R03;
&НаСервере
Процедура ТаблицаНаФормеИзТЗ(ИмяТЗ, ЗначениеТЗ)
ТаблицаОбъект = РеквизитФормыВЗначение(ИмяТЗ);
// Удаляем старые колонки и элементы управления по ним
КолонкиУдаление = Новый Массив;
Для Каждого Колонка Из ТаблицаОбъект.Колонки Цикл
Если Колонка.Имя = "Пометка" Тогда
Продолжить;
КонецЕсли;
КолонкиУдаление.Добавить(ИмяТЗ + "." + Колонка.Имя);
Элементы.Удалить(Элементы.Найти(ИмяТЗ + Колонка.Имя));
КонецЦикла;
ИзменитьРеквизиты(,КолонкиУдаление);
ТаблицаОбъект = ЗначениеТЗ;
Для Каждого Колонка Из ТаблицаОбъект.Колонки Цикл
Заг = СокрЛП(Колонка.Заголовок);
Заг = ?(Заг = "", Колонка.Имя, Заг);
// Определяем наличие такой же колонки
Если Элементы.Найти(ИмяТЗ + Колонка.Имя) <> неопределено Тогда Продолжить КонецЕсли;
// Добавляем колонки на форму
МассивДобавляемыхРеквизитов = Новый Массив;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, ИмяТЗ, Заг));
// Методы управляемой формы
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
// Добавляем отображение
НоваяКолонка = Элементы.Добавить(ИмяТЗ + Колонка.Имя, Тип("ПолеФормы"), Элементы[ИмяТЗ]);
НоваяКолонка.Заголовок = Заг;
НоваяКолонка.ПутьКДанным = ИмяТЗ + "." + Колонка.Имя;
НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
КонецЦикла;
ТаблицаОбъект.Колонки.Добавить("Пометка",Новый ОписаниеТипов("Булево"), "V");
ЗначениеВРеквизитФормы(ТаблицаОбъект, ИмяТЗ);
КонецПроцедуры
&НаСервере
Процедура СформироватьНаСервере()
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(РеквизитФормыВЗначение("Отчет").ПолучитьМакет("МакетСКДдляДДС"),
Отчет.КомпоновщикНастроек.Настройки, , ,
Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
РезультатТЗ = Новый ТаблицаЗначений;
ПроцессорВывода.УстановитьОбъект(РезультатТЗ);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
ТаблицаНаФормеИзТЗ("тзОстатокПоОплате", РезультатТЗ);
КонецПроцедуры
R03;
Далее можно сохранять/создавать варианты отчета и на основании этих настроек заполнять данные в ТЗ на форме.
Как говорится: это была присказка, а теперь сказка 😉
Отбор СКД на форме для нескольких запросов
Создаем новую обработку, назовем например "ВариантыТест"; предположим что 2 нужных запроса ранее были составлены в консоли запросов и помещены в СКД. Названия СКД "МакетСКДдляДДС", "МакетСКДдляНачисления"
- Для начала определимся с переменными обработки
- ДатаРасчета: дата сбора остатков в запросах. Чтобы не загромождать форму, параметры данных решено на нее не "вывешивать", достаточно 1-ой даты: реквизита обработки. В дополнение донастроим СКД, добавив в нее 1 параметр "ДатаРасчета", дабы не мучаться с установкой дат вида "31.12.2024 23:59:59", а устанавливать начало/конец дня без времени. В данном случае остатки берутся на начало месяца (01.01.2024):
- Таблицы значений на форме по СКД. называться могут произвольным образом, нужны только чтобы по окончанию установки всех отборов по специальной кнопке вида "Сформировать" "залить" в них результат СКД. Допустим что мы хотим каждую строку отметить флагом: добавляем 1 колонку "Пометка", остальные колонки создадутся динамически из запроса:
- Набор реквизитов на каждую СКД. При этом каждый реквизит состоит из префикса и наименования СКД, название реквизита строго соотвествует шаблону "<Префикс>_<Имя СКД>"
- a) Компоновщики настроек — префикс "Компоновщик"
- b)Таблицы с ранее сохраненными вариантами настроек — префикс "Варианты"
- c) Описание состояния настроек СКД — префикс "Изменения": <пусто>-ничего не делать, "Изменено" — отбор изменен (нужно сохранить), "Сохранить" — признак сохранения варианта перед закрытием.
- "СКДСписок": вспомогательный списочек макетов СКД по обработке для программных дейсвий на стороне клиента или сервера и исключения дублей кода.
Общий наглядный вид созданных реквизитов приведен на рисунке:
2. Действия при открытии формы обработки. При открытии сначала заполняются вспомогательные данные, после чего идет инициализация ранее сохраненных настроек компоновщиков. Если это 1-ый запуск обработки, то по сути ничего не сохранено, только считываются настройки из конфигуратора.
Общий принцип: в стандартное хранилище настроек пользователя по имени обработки и имени СКД сохраняется некая ТЗ, которая содержит список вариантов настроек, 1 из них "активный".
Сохранение/загрузка настроек
// Загрузка ТЗ настроек вариантов
ВсеВариантыОтчета = ХранилищеОбщихНастроек.Загрузить("ВнешняяОбработка.ВариантыТест",
СКДИмя,
ПользовательИнформационнойБазы);
// Сохранение ТЗ настроек вариантов
ХранилищеОбщихНастроек.Сохранить("ВнешняяОбработка.ВариантыТест", СКДИмя,
РеквизитФормыВЗначение("Варианты_" + СКДИмя),,
ПользовательИнформационнойБазы);
ПРИМЕЧАНИЕ: Полный программный код будет приведен в конце статьи.
3. Отбор СКД на форме. С целью удобства на форме использована отдельная закладка для отбора. Как ранее было упомянуто, параметры данных на форме не размещаем, параметр всего 1: дата Расчета. А отбор компоновки — это главный элемент, размещен на форме путем перетягивания из компоновщика-реквизита формы. Пример:
Далее на форме в режиме предприятия можно "крутить" отбор как угодно, насколько позволяет созданная СКД. При изменении настроек в форме будет отмечено, что настройки менялись — и при закрытии формы система спросит "Сохранить ли вариант", при этом откроется форма редактирования вариантов.
В текстовом поле по умолчанию ставится текущий активный вариант, но при желании можно изменить название (например "Основной1"), тогда с новыми настройками будет создан еще 1 вариант, а старый останется без изменений.
Если нажать "Продолжить редактирование", то форма основная закрыта не будет, редактирование будет продолжено.
4. Выбор вариантов. Также по каждому отбору предусмотрен выбор ранее сохраненных вариантов, для этого создана специальная кнопка "Варианты… — Открыть", которая открывает форму просмотра, выбора, удаления сохраненных вариантов настроек.
По умолчанию на форме активен последний сохраненный/выбранный вариант, но если нужно выбрать другой вариант настроек — достаточно указать его в списке и нажать "Выбрать". После этого в компоновщике установятся настройки выбранного варианта.
5. Удаление вариантов. Если выясняется, что какие-то варианты отбор были черновые, или просто по ошибке созданы: можно аналогично выбрать в меню "Варианты… — Открыть", затем выбрать "ненужный" вариант в списке и нажать "Удалить". После этого из оставшихся вариантов выбрать любой, который станет активным. ПРИМЕЧАНИЕ: удалить можно только пользовательские варианты, стандартные, заданные в конфигураторе механизм удалить не позволяет.
6. Сохранение вариантов. Для сохранения варианта, который "только что отредактировали" сделано специальное меню "Варианты… — Сохранение", по которому открывается та же форма, которая появляется по кнопке "Открыть" или при закрытии формы.
При этом можно указать новое имя варианта, можно выбрать существующий — тогда он будет перезаписан.
7. Механизм управления вариантами. При кодировании/конфигурировании действий по работе с вариантами настроек, лучше по возможности избегать дублирования кода, так как функционал для всех СКД единый: команды, функции использовать также единые для всех, параметры определять исходя из названий элементов управления/команд.
В частности для управления выбором/сохранением/изменением настроек СКД на форме использованы всего 4 команды, простое подменю "Варианты…" на форме. А действия по сохранению/изменению осуществляют всего 2 команды, которые получают имя используемой СКД из названия команды:
// <Команда открытия вариантов: вызывается по кнопке "Варианты... - Выбор" на форме>
// Параметры:
// <Команда> - <КомандаФормы> - имя команды формы: по конкретной СКД своя команда-кнопка
&НаКлиенте
Процедура КомандаОткрытьВарианты(Команда)
//Команда.Имя = "<СКДИмя>ОткрытьВарианты";
СКДИмя = Лев(Команда.Имя, СтрДлина(Команда.Имя) - СтрДлина("ОткрытьВарианты"));
ВариантыОткрытьФормуНастройки(СКДИмя, ложь, ложь);
КонецПроцедуры
// <Команда сохранения варианта: вызывается по кнопке "Варианты... - Сохранение" на форме>
// Параметры:
// <Команда> - <КомандаФормы> - имя команды формы: по конкретной СКД своя команда-кнопка
&НаКлиенте
Процедура КомандаСохранитьВариант(Команда)
//Команда.Имя = "<СКДИмя>СохранитьВариант";
СКДИмя = Лев(Команда.Имя, СтрДлина(Команда.Имя) - СтрДлина("СохранитьВариант"));
ВариантыОткрытьФормуНастройки(СКДИмя, истина, ложь);
КонецПроцедуры
Форма для управления настройками содержит 2 элемента управления "Список вариантов", "текущий вариант", 2 команды "Выбрать", "Продолжить редактирование".
Программный код формы настроек
&НаКлиенте
Процедура Выбрать(Команда)
Для каждого ЭлементСписка Из СписокВариантов Цикл
Если ЭлементСписка.Значение = Элементы.СписокВариантов.ТекущиеДанные.Значение Тогда
ЭлементСписка.Пометка = Истина;
Иначе
ЭлементСписка.Пометка = Ложь
КонецЕсли;
КонецЦикла;
Закрыть(Новый Структура("СписокВариантов, ТекущийВариант", СписокВариантов, ТекущийВариант));
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Для каждого СтрокаДанных Из Параметры.СписокВариантов Цикл
ЗаполнитьЗначенияСвойств(СписокВариантов.Добавить(), СтрокаДанных);
Если СтрокаДанных.Пометка Тогда
ТекущийВариант = СтрокаДанных.Представление
КонецЕсли;
КонецЦикла;
Элементы.ФормаУдалить.Видимость = НЕ Параметры.РежимСохранения;
Элементы.ТекущийВариант.Видимость = Параметры.РежимСохранения;
Элементы.ТекущийВариант.ЦветТекстаЗаголовка = ?(Параметры.РежимСохранения, Новый Цвет(255,0,0), Новый Цвет(0,0,0));
ЭтаФорма.АвтоЗаголовок = ложь;
ЭтаФорма.Заголовок = Параметры.Подсказка;
КонецПроцедуры
&НаКлиенте
Процедура СписокВариантовПередУдалением(Элемент, Отказ)
Если Элементы.СписокВариантов.ТекущиеДанные.Стандартный Тогда
Сообщить("Невозможно удалить стандартный вариант отчета");
Отказ = истина;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура СписокВариантовПриАктивизацииСтроки(Элемент)
ТекущийВариант = Элементы.СписокВариантов.ТекущиеДанные.Представление
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Для каждого СтрокаДанных Из СписокВариантов Цикл
Если СтрокаДанных.Пометка Тогда
Элементы.СписокВариантов.ТекущаяСтрока = СтрокаДанных.ПолучитьИдентификатор();
ТекущийВариант = СтрокаДанных.Представление;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ПродолжитьРедактирование(Команда)
Закрыть("ПродолжитьРедактирование");
КонецПроцедуры
Пример использования:
1. На 1-ой закладке устанавливаем дату получения бух.остатков, задаем нужный отбор СКД
2. На закладке №2 исполняем запрос по кнопке "Заполнить" — получаем нужное ТЗ на форме с данными
Далее аналогично строим отбор и получаем нужное ТЗ на 3,4 закладках. ПРИМЕЧАНИЕ: в реальной задаче в отбор на 3-ей закладке программно "заливались" контрагенты из ТЗ закладки 2, отмеченные галочками.
3. При закрытии обработки: так как отбор СКД был интерактивно изменен — обработка выдаст форму сохранения настроек варианта отчета:
4. При повторном открытии обработки на форме будут установлены настройки активного варианта СКД, которые были сохранены при закрытии формы
В заключение. Целью публикации было описать методику, которая использовалась в реальной работе. Лучше все-таки подобную задачу повторить самостоятельно, как как в реальной работе подобный "простенький пример" это только начальные наработки — и одним отбором СКД на форме как правило не ограничиваются 😉
Программный код обработки
&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
ВариантыПередЗакрытием(Отказ, СтандартнаяОбработка)
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
УстановитьВидимостьДоступность();
ГруппаСтраницыПриСменеСтраницы(Неопределено, Элементы.ГруппаСтраницы.ТекущаяСтраница);
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
СКДСписок.Добавить("МакетСКДдляДДС", "Таблица ДДС");
СКДСписок.Добавить("МакетСКДдляНачисления", "Таблица начислений");
ВариантыПриСозданииНаСервере(Отказ, СтандартнаяОбработка);
КонецПроцедуры
#Область РаботаСВариантами
// <Вспомогательная функция: Список колонок таблицы вариантовСКД>
&НаКлиентеНаСервереБезКонтекста
Функция ВариантыКолонкиНастройкиСКД()
КолонкиДанных = Новый Соответствие;
КолонкиДанных.Вставить("Имя", Неопределено);
КолонкиДанных.Вставить("Значение", Неопределено);
КолонкиДанных.Вставить("Представление", Новый ОписаниеТипов("Строка"));
КолонкиДанных.Вставить("Стандартный", Новый ОписаниеТипов("Булево"));
КолонкиДанных.Вставить("Пометка", Новый ОписаниеТипов("Булево"));
Возврат КолонкиДанных
КонецФункции
// <Получает варианты настроек СКД в виде таблицы из сохраненных настроек>
//
// Параметры:
// <СКД> - <СхемаКомпоновкианных> - <сама схема>
// <ПараметрыПрочие> - <Структура> - <настройки получения параметров>:
// "МетаданныеИмя" - <Строка> - Имя метаданных текущей обработки
// "СКДИмя" - <Строка> - Имя СКД, как задано в конфигураторе
// "ПользовательИнформационнойБазы" - <ПользовательИБ> - пока что всегда "текущий пользователь"
//
&НаСервереБезКонтекста
Функция СписокВариантовОтчетовПоСКД(СКД, ПараметрыПрочие)
КолонкиДанных = ВариантыКолонкиНастройкиСКД();
// Заполняем шаблон таблицы вариантов СКД.
ВариантыОтчета = Новый ТаблицаЗначений;
Для Каждого Колонка ИЗ КолонкиДанных Цикл
Если Колонка.Значение = Неопределено Тогда
ВариантыОтчета.Колонки.Добавить(Колонка.Ключ);
Иначе
ВариантыОтчета.Колонки.Добавить(Колонка.Ключ, Колонка.Значение);
КонецЕсли;
КонецЦикла;
// Читаем стандартные варианты СКД, заложенные в конфигураторе.
Для Каждого ВариантОтчета Из СКД.ВариантыНастроек Цикл
НоваяСтрока = ВариантыОтчета.Добавить();
НоваяСтрока.Имя = ВариантОтчета.Имя;
НоваяСтрока.Значение = ВариантОтчета.Настройки;
НоваяСтрока.Представление = ВариантОтчета.Представление;
НоваяСтрока.Стандартный = истина;
КонецЦикла;
// Получаем пользовательские настройки сохранения.
Если ПараметрыПрочие.ПользовательИнформационнойБазы = Неопределено Тогда
ВсеВариантыОтчета = ХранилищеОбщихНастроек.Загрузить(ПараметрыПрочие.МетаданныеИмя, ПараметрыПрочие.СКДИмя);
Иначе
ВсеВариантыОтчета = ХранилищеОбщихНастроек.Загрузить(ПараметрыПрочие.МетаданныеИмя,
ПараметрыПрочие.СКДИмя,
ПараметрыПрочие.ПользовательИнформационнойБазы);
КонецЕсли;
// Читаем пользовательские настройки сохранения как в стандартные арианты, так и созданные пользователем.
Если ТипЗнч(ВсеВариантыОтчета) = Тип("ТаблицаЗначений") Тогда
Для Каждого ВариантОтчета Из ВсеВариантыОтчета Цикл
СтрокаДанных = ВариантыОтчета.Найти(ВариантОтчета.Имя, "Имя");
Если СтрокаДанных = Неопределено Тогда
НоваяСтрока = ВариантыОтчета.Добавить();
НоваяСтрока.Имя = ВариантОтчета.Имя;
НоваяСтрока.Значение = ВариантОтчета.Значение;
НоваяСтрока.Представление = ВариантОтчета.Представление;
НоваяСтрока.Пометка = ВариантОтчета.Пометка;
Иначе
СтрокаДанных.Значение = ВариантОтчета.Значение;
СтрокаДанных.Пометка = ВариантОтчета.Пометка;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ВариантыОтчета
КонецФункции
// <Загружает таблицу значений в ДанныеФормаКоллекция>
//
// Параметры:
// <ИмяТЗ> - <Строка> - Имя таблицы-коллекции на форме
// <ЗначениеТЗ> - <ТаблицаЗначений> - объект таблицы, из которого идет загрузка
// <ФиксированныеКолонки> - <Массив> - Тип элементов "Строка": имена колонок коллекции, которые заданы в конфигураторе
// и являются неудаляемыми
//
&НаСервере
Процедура ТаблицаНаФормеИзТЗ(ИмяТЗ, ЗначениеТЗ, ФиксированныеКолонки)
// Далее если нужна ТЗ ...
ТаблицаОбъект = РеквизитФормыВЗначение(ИмяТЗ);
КолонкиУдаление = Новый Массив;
Для Каждого Колонка Из ТаблицаОбъект.Колонки Цикл
Если ФиксированныеКолонки.Найти(Колонка.Имя) <> Неопределено Тогда
Продолжить;
КонецЕсли;
КолонкиУдаление.Добавить(ИмяТЗ + "." + Колонка.Имя);
Элементы.Удалить(Элементы.Найти(ИмяТЗ + Колонка.Имя));
КонецЦикла;
ИзменитьРеквизиты(,КолонкиУдаление);
Для Каждого Колонка Из ЗначениеТЗ.Колонки Цикл
Заг = СокрЛП(Колонка.Заголовок);
Заг = ?(Заг = "", Колонка.Имя, Заг);
// Определяем наличие такой же колонки
Если ФиксированныеКолонки.Найти(Колонка.Имя) <> Неопределено Тогда
Продолжить;
КонецЕсли;
// Добавляем колонки на форму
МассивДобавляемыхРеквизитов = Новый Массив;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, ИмяТЗ, Заг));
// Методы управляемой формы
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
// Добавляем отображение
НоваяКолонка = Элементы.Добавить(ИмяТЗ + Колонка.Имя, Тип("ПолеФормы"), Элементы[ИмяТЗ]);
НоваяКолонка.Заголовок = Заг;
НоваяКолонка.ПутьКДанным = ИмяТЗ + "." + Колонка.Имя;
НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
КонецЦикла;
Для Каждого Колонка Из ТаблицаОбъект.Колонки Цикл
Если ФиксированныеКолонки.Найти(Колонка.Имя) = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ЗначениеТЗ.Колонки.Найти(Колонка.Имя) = Неопределено Тогда
ЗначениеТЗ.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения, Колонка.Заголовок);
КонецЕсли;
КонецЦикла;
ЗначениеВРеквизитФормы(ЗначениеТЗ, ИмяТЗ);
КонецПроцедуры
// <Команда открытия вариантов: вызывается по кнопке "Варианты... - Выбор" на форме>
// Параметры:
// <Команда> - <КомандаФормы> - имя команды формы: по конкретной СКД своя команда-кнопка
&НаКлиенте
Процедура КомандаОткрытьВарианты(Команда)
//Команда.Имя = "<СКДИмя>ОткрытьВарианты";
СКДИмя = Лев(Команда.Имя, СтрДлина(Команда.Имя) - СтрДлина("ОткрытьВарианты"));
ВариантыОткрытьФормуНастройки(СКДИмя, ложь, ложь);
КонецПроцедуры
// <Команда сохранения варианта: вызывается по кнопке "Варианты... - Сохранение" на форме>
// Параметры:
// <Команда> - <КомандаФормы> - имя команды формы: по конкретной СКД своя команда-кнопка
&НаКлиенте
Процедура КомандаСохранитьВариант(Команда)
//Команда.Имя = "<СКДИмя>СохранитьВариант";
СКДИмя = Лев(Команда.Имя, СтрДлина(Команда.Имя) - СтрДлина("СохранитьВариант"));
ВариантыОткрытьФормуНастройки(СКДИмя, истина, ложь);
КонецПроцедуры
// <Событие при создании на сервере в контексте вариантов СКД: вызывается в процедуре "ПриСозданииНаСервере">
&НаСервере
Процедура ВариантыПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Для каждого СКДИмя Из СКДСписок Цикл
ВариантыИнициализацияНастроекСКД(СКДИмя.Значение);
КонецЦикла;
ВариантыИнициализацияКомпоновщиковНаСервере();
КонецПроцедуры
// <Чтение активных вариантов настроек на форму по СКД: вызывается в процедуре "ВариантыИнициализацияКомпоновщиковНаСервере">
//
// Параметры:
// <СКДИмя> - <Строка> - Имя СКД, как задано в конфигураторе
&НаСервере
Процедура ВариантыИнициализацияКомпоновщикаНаСервере(СКДИмя)
СКД = РеквизитФормыВЗначение("Объект").ПолучитьМакет(СКДИмя);
ЭтаФорма["Компоновщик_" + СКДИмя].Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПоместитьВоВременноеХранилище(СКД,
УникальныйИдентификатор)));
ЭтаФорма["Компоновщик_" + СКДИмя].ЗагрузитьНастройки(СКД.НастройкиПоУмолчанию);
Для каждого Настройки Из ЭтаФорма["Варианты_" + СКДИмя] Цикл
Если Настройки.Пометка Тогда
ЭтаФорма["Компоновщик_" + СКДИмя].ЗагрузитьНастройки(Настройки.Значение);
Прервать;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// <Чтение активных вариантов настроек на форму по каждой СКД: вызывается в процедуре "ВариантыПриСозданииНаСервере">
&НаСервере
Процедура ВариантыИнициализацияКомпоновщиковНаСервере()
Для каждого СКДИмя Из СКДСписок Цикл
ВариантыИнициализацияКомпоновщикаНаСервере(СКДИмя.Значение);
КонецЦикла;
// берем дату расчета на форму из 1-го попавшегося компоновщика
ПараметрДатаРасчета = ЭтаФорма["Компоновщик_" + СКДСписок[0].Значение].Настройки.ПараметрыДанных.Элементы.Найти("ДатаРасчета");
Если ТипЗнч(ПараметрДатаРасчета.Значение) = Тип("Дата") Тогда
Объект.ДатаРасчета = ПараметрДатаРасчета.Значение;
Иначе
Объект.ДатаРасчета = ПараметрДатаРасчета.Значение.Дата;
КонецЕсли;
Для каждого СКДИмя Из СКДСписок Цикл
ЭтаФорма["Компоновщик_" + СКДИмя.Значение].Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("ДатаРасчета", Объект.ДатаРасчета);
КонецЦикла;
КонецПроцедуры
// <Событие перед закрытием формы в контексте вариантов СКД: вызывается в процедуре "ПередЗакрытием">
&НаКлиенте
Процедура ВариантыПередЗакрытием(Отказ, СтандартнаяОбработка)
Для каждого СКДИмя Из СКДСписок Цикл
Если ЭтаФорма["Изменения_" + СКДИмя.Значение] = "Изменено" Тогда
Отказ = истина;
ВариантыОткрытьФормуНастройки(СКДИмя.Значение, истина, истина);
Прервать;
КонецЕсли;
КонецЦикла;
ВариантыСохранитьНаКлиенте();
КонецПроцедуры
// Производит сохранение настроек с формы по заданным СКД во внутреннее хранилище БД
// Параметры:
// <СКДИмяПараметр> - <Строка> - Имя СКД, как задано в конфигураторе
// Если не задано - то идет сохранение всех требуемых настроек по СКД (при закрытии формы)
&НаКлиенте
Процедура ВариантыСохранитьНаКлиенте(СКДИмяПараметр = Неопределено)
МассивИменСКД = Новый Массив;
Если СКДИмяПараметр = Неопределено Тогда
Для каждого СКДИмя Из СКДСписок Цикл
МассивИменСКД.Добавить(СКДИмя.Значение);
КонецЦикла;
Иначе
МассивИменСКД.Добавить(СКДИмяПараметр);
КонецЕсли;
ЕстьСохранение = ложь;
Для каждого СКДИмя Из МассивИменСКД Цикл
Если ЭтаФорма["Изменения_" + СКДИмя] = "Сохранить" Тогда
ЕстьСохранение = истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЕстьСохранение Тогда
ВариантыСохранитьНаСервере();
КонецЕсли;
КонецПроцедуры
// <Событие интерактивного ввода даты расчета на форме обработки>
&НаКлиенте
Процедура ДатаРасчетаПриИзменении(Элемент)
// дату расчета с формы ставим во все параметры компоновщиков
Для каждого СКДИмя Из СКДСписок Цикл
ЭтаФорма["Компоновщик_" + СКДИмя.Значение].Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("ДатаРасчета", Объект.ДатаРасчета);
ЭтаФорма["Изменения_" + СКДИмя.Значение] = "Изменено";
КонецЦикла;
КонецПроцедуры
// <Событие интерактивного изменения отбора СКД на форме обработки>
&НаКлиенте
Процедура ВариантыКомпоновщикОтборПриИзменении(Элемент)
//Элемент.Имя = "Компоновщик<СКДИмя>НастройкиОтбор";
СКДИмя = Сред(Элемент.Имя, СтрДлина("Компоновщик")+1);
СКДИмя = Лев(СКДИмя, СтрДлина(СКДИмя) - СтрДлина("НастройкиОтбор"));
ЭтаФорма["Изменения_" + СКДИмя] = "Изменено";
Для Каждого ВариантОтчета Из ЭтаФорма["Варианты_" + СКДИмя] Цикл
Если ВариантОтчета.Пометка Тогда
ВариантОтчета.Значение = ЭтаФорма["Компоновщик_" + СКДИмя].Настройки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// <Обработчик ожидания для "ВариантыОткрытьФормуНастройки": устанавливает признаки сохранения вариантов настроек
// либо дает команду закрытия формы с сохранением/пропуском сохранения настроек СКД>
&НаКлиенте
Процедура ВариантыОткрытьФормуНастройкиПослеВыбора(Результат, ПараметрыВыбора) Экспорт
Если Результат = "ПродолжитьРедактирование" Тогда
Возврат
КонецЕсли;
СКДИмя = ПараметрыВыбора.СКДИмя;
Если Результат = Неопределено ИЛИ ПустаяСтрока(Результат.ТекущийВариант) Тогда
// закрыти форму без сохранения, либо указали пустой вариант
Если ПараметрыВыбора.Закрытие Тогда
ЭтаФорма["Изменения_" + СКДИмя] = "";
Закрыть();
КонецЕсли;
Возврат
КонецЕсли;
ЭтаФорма["Варианты_" + СКДИмя].Очистить();
Для каждого СтрокаДанных Из Результат.СписокВариантов Цикл
ЗаполнитьЗначенияСвойств(ЭтаФорма["Варианты_" + СКДИмя].Добавить(), СтрокаДанных);
КонецЦикла;
ТекущийВариант = Результат.ТекущийВариант;
ВариантНайден = ложь;
Для Каждого ВариантОтчета Из ЭтаФорма["Варианты_" + СКДИмя] Цикл
ВариантОтчета.Пометка = ложь;
Если СокрЛП(ТекущийВариант) = СокрЛП(ВариантОтчета.Представление) Тогда
Если ПараметрыВыбора.РежимСохранения Тогда
ВариантОтчета.Значение = ЭтаФорма["Компоновщик_" + СКДИмя].Настройки;
ВариантОтчета.Пометка = истина;
ВариантНайден = истина
Иначе //режим выбора варианта
ЭтаФорма["Компоновщик_" + СКДИмя].ЗагрузитьНастройки(ВариантОтчета.Значение);
ВариантОтчета.Пометка = истина;
ВариантНайден = истина
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не ВариантНайден Тогда
ВариантОтчета = ЭтаФорма["Варианты_" + СКДИмя].Добавить();
ВариантОтчета.Имя = "Вариант_" + СтрЗаменить(Новый УникальныйИдентификатор,"-","_");
ВариантОтчета.Представление = ТекущийВариант;
ВариантОтчета.Значение = ЭтаФорма["Компоновщик_" + СКДИмя].Настройки;
ВариантОтчета.Пометка = истина;
КонецЕсли;
Если ПараметрыВыбора.РежимСохранения Тогда
ЭтаФорма["Изменения_" + СКДИмя] = "Сохранить";
КонецЕсли;
Если ПараметрыВыбора.Закрытие Тогда
Закрыть();
ИначеЕсли ПараметрыВыбора.РежимСохранения Тогда
ВариантыСохранитьНаКлиенте(СКДИмя);
КонецЕсли;
КонецПроцедуры
// <Открытие формы существующих вариантов настроек СКД>
//
// Параметры:
// <СКДИмя> - <Строка> - Имя СКД, как задано в конфигураторе
// <РежимСохранения> - <Булево> - признак сохранения варианта: если "true", тогда будет видно поле ввода названия
// варианта и после ввода названия настройки будут сохранены во внутреннее хранилище БД
//
&НаКлиенте
Процедура ВариантыОткрытьФормуНастройки(СКДИмя, РежимСохранения, Закрытие)
ПараметрыВыбора = Новый Структура("РежимСохранения, СКДИмя", РежимСохранения, СКДИмя);
ПараметрыВыбора.Вставить("Закрытие", Закрытие);
Оповещение = Новый ОписаниеОповещения("ВариантыОткрытьФормуНастройкиПослеВыбора", ЭтотОбъект, ПараметрыВыбора);
СписокВариантов = Новый Массив;
КолонкиДанных = ВариантыКолонкиНастройкиСКД();
Для Каждого СтрокаДанных ИЗ ЭтаФорма["Варианты_" + СКДИмя] Цикл
ДанныеСтроки = Новый Структура;
Для Каждого Колонка ИЗ КолонкиДанных Цикл
ДанныеСтроки.Вставить(Колонка.Ключ, СтрокаДанных[Колонка.Ключ]);
КонецЦикла;
СписокВариантов.Добавить( ДанныеСтроки )
КонецЦикла;
ЭлементСКД = СКДСписок.НайтиПоЗначению(СКДИмя);
Если РежимСохранения Тогда
Подсказка = "Сохранение варианта """ + ЭлементСКД.Представление + """";
Иначе
Подсказка = "Выбор варианта """ + ЭлементСКД.Представление + """";
КонецЕсли;
ПараметрыОткрытия = Новый Структура("СписокВариантов, РежимСохранения", СписокВариантов, РежимСохранения);
ПараметрыОткрытия.Вставить("Подсказка", Подсказка);
ФормаНастройки = ПолучитьФорму("ВнешняяОбработка.ВариантыТест.Форма.ВариантыНастроек", ПараметрыОткрытия, ЭтаФорма);
ФормаНастройки.ОписаниеОповещенияОЗакрытии = Оповещение;
ФормаНастройки.РежимОткрытияОкна = РежимОткрытияОкнаФормы.БлокироватьОкноВладельца;
ФормаНастройки.Открыть();
КонецПроцедуры
// <Читает настройки вариантов СКД из временного хранилища и заполняет их в таблицу ""Варианты_СКДИмя">
//
// Параметры:
// <СКДИмя> - <Строка> - <Имя СКД для получения настроек>
//
&НаСервере
Процедура ВариантыИнициализацияНастроекСКД(СКДИмя)
ОтчетОбъект = РеквизитФормыВЗначение("Объект");
ПараметрыПрочие = Новый Структура(
"МетаданныеИмя, ПользовательИнформационнойБазы, СКДИмя",
ОтчетОбъект.Метаданные().Имя,
Пользователи.ТекущийПользователь(),
СКДИмя
);
СКД = ОтчетОбъект.ПолучитьМакет(СКДИмя);
ЗначениеВРеквизитФормы( СписокВариантовОтчетовПоСКД(СКД, ПараметрыПрочие), "Варианты_" + СКДИмя )
КонецПроцедуры
// <Сохраняет настройки СКД с формы по "активному" варианту отчета во внутреннее хранилище БД>
//
// Параметры:
// <СКДИмя> - <Строка> - Имя СКД, как задано в конфигураторе
// <ПараметрыПрочие> - <Структура> - <настройки получения параметров>:
// "МетаданныеИмя" - <Строка> - Имя метаданных текущей обработки
// "ПользовательИнформационнойБазы" - <ПользовательИБ> - пока что всегда "текущий пользователь"
//
&НаСервере
Процедура ВариантыСохранениеНастроекСКД(СКДИмя, ПараметрыПрочие)
ПараметрыПрочие.Вставить("СКДИмя", СКДИмя);
ОтчетОбъект = РеквизитФормыВЗначение("Объект");
СКД = ОтчетОбъект.ПолучитьМакет(СКДИмя);
СохраненныеВарианты = СписокВариантовОтчетовПоСКД(СКД, ПараметрыПрочие);
Для Каждого ВариантОтчета Из ЭтаФорма["Варианты_" + СКДИмя] Цикл
Если ВариантОтчета.Пометка Тогда
ВариантОтчета.Пометка = истина;
ВариантОтчета.Значение = ЭтаФорма["Компоновщик_" + СКДИмя].Настройки;
Иначе
ВариантОтчета.Значение = СохраненныеВарианты.Найти(ВариантОтчета.Имя, "Имя").Значение;
ВариантОтчета.Пометка = ложь;
КонецЕсли;
КонецЦикла;
Если ПараметрыПрочие.ПользовательИнформационнойБазы = Неопределено Тогда
ХранилищеОбщихНастроек.Сохранить(ПараметрыПрочие.МетаданныеИмя, СКДИмя, РеквизитФормыВЗначение("Варианты_" + СКДИмя));
Иначе
ХранилищеОбщихНастроек.Сохранить(ПараметрыПрочие.МетаданныеИмя, СКДИмя, РеквизитФормыВЗначение("Варианты_" + СКДИмя),,
ПараметрыПрочие.ПользовательИнформационнойБазы);
КонецЕсли;
КонецПроцедуры
// <Ссохраняет настройки всех СКД с формы во внутреннее хранилище БД>
&НаСервере
Процедура ВариантыСохранитьНаСервере()
ОтчетОбъект = РеквизитФормыВЗначение("Объект");
ПараметрыПрочие = Новый Структура(
"МетаданныеИмя, ПользовательИнформационнойБазы",
ОтчетОбъект.Метаданные().Имя,
Пользователи.ТекущийПользователь(),
);
//сохранение всех настроек СКД с формы, которые требуются
Для каждого СКДИмя Из СКДСписок Цикл
Если ЭтаФорма["Изменения_" + СКДИмя.Значение] = "Сохранить" Тогда
ВариантыСохранениеНастроекСКД(СКДИмя.Значение, ПараметрыПрочие);
ЭтаФорма["Изменения_" + СКДИмя.Значение] = ""
КонецЕсли;
КонецЦикла;
КонецПроцедуры
#КонецОбласти
Автор, приложи скриншот с примером, на котором видно, что получается в итоге.
Из описания к статье трудно понять, какую задачу решаешь.