Функция на вход принимает Запрос, Текст запроса, таблицу значений и дерево значений
Источник: http://infostart.ru/public/575659/
// Пример универсальной функции для создания схемы компоновки данных
// Опубликовал Дмитрий Иванов (kambl) в раздел Программирование - Практика программирования
// http://infostart.ru/public/575659/
//
// Если вам приходится часто создавать схему компоновки данных программно или вы начинающий специалист и пытаетесь разобраться, что же за зверь такой СКД, то эта статья может оказаться вам полезной. Функция создает схему компоновки с минимально необходимой структурой данных. С помощью передачи дополнительных параметров есть возможность добавления ресурсов и оформления.
// Появилась необходимость часто прибегать к программному созданию схемы компоновки данных. Было принято решение написать универсальную функцию принимающую различные наборы данных и на выходе возвращающую готовую СКД. Функция на вход принимает Запрос, Текст запроса, таблицу значений и дерево значений.
// Помимо набора данных функция принимает ряд необязательных параметров:
//
// Структура ресурсов: содержит перечень полей ресурсов, где ключ - ИмяПоля, Значение(Строка) - Агрегатная функция ("Сумма", "Среднее", "Количество", и т.д.);
// Флаг АвтоЗаполнениеДоступныхПолей;
// Строковое Имя макета оформления.
//
// НаборДанных (Типы: Строка, Запрос, ТаблицаЗначений, ДеревоЗначений)
// Искомый набор данных
//
// СтруктураРесурсов (Тип: Структура) - Структура полей ресурсов, где ключ - ИмяПоля, Значение(Строка) - Агрегатная функция
//
// ВноситьПоляВыбора (Тип: Булево) - Флаг добавление полей набора
//
// ИмяСтандартногоМакетаОформления (Тип: Строка) - Имя макета оформления
//
Функция СоздатьСхемуКомпоновкиДанных(НаборДанных, СтруктураРесурсов = Неопределено, АвтоЗаполнениеДоступныхПолей = Истина, ИмяСтандартногоМакетаОформления = "")
СКД = Новый СхемаКомпоновкиДанных;
// Заполнение основных данных схемы
ИсточникДанных = СКД.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "ИсточникДанных";
ИсточникДанных.ТипИсточникаДанных = "Local";
Если ТипЗнч(НаборДанных) = Тип("Строка") или
ТипЗнч(НаборДанных) = Тип("Запрос") Тогда
ТекущийНаборДанных = СКД.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
ТекущийНаборДанных.Имя = "ОсновнойНабор";
ТекущийНаборДанных.Запрос = ?(ТипЗнч(НаборДанных) = Тип("Строка"), НаборДанных, НаборДанных.Текст);
ТекущийНаборДанных.ИсточникДанных = "ИсточникДанных";
ТекущийНаборДанных.АвтоЗаполнениеДоступныхПолей = АвтоЗаполнениеДоступныхПолей;
ТипНабора = "Запрос";
ИначеЕсли ТипЗнч(НаборДанных) = Тип("ТаблицаЗначений") или
ТипЗнч(НаборДанных) = Тип("ДеревоЗначений") Тогда
ТекущийНаборДанных = СКД.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
ТекущийНаборДанных.Имя = "ОсновнойНабор";
ТекущийНаборДанных.ИмяОбъекта = "ТаблицаИсточник"; // связывание с внешними данными идёт именно по нему
ТекущийНаборДанных.ИсточникДанных = "ИсточникДанных";
ТипНабора = "Объект";
Иначе
Возврат Неопределено;
КонецЕсли;
НастройкиПоУмолчанию = СКД.НастройкиПоУмолчанию;
// Создание структуры.
// Группировка, детальные записи и автовыбранное поле
Группировка = НастройкиПоУмолчанию.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Группировка.Использование = Истина;
АвтоПоле = Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
АвтоПоле.Использование = Истина;
КоллекцияКолонок = Новый ТаблицаЗначений;
КоллекцияКолонок.Колонки.Добавить("Имя");
КоллекцияКолонок.Колонки.Добавить("ТипЗначения");
КоллекцияКолонок.Колонки.Добавить("Заголовок");
Если ТипНабора = "Запрос" Тогда
ПостроительЗапроса = Новый ПостроительЗапроса;
Если ТипЗнч(НаборДанных) = Тип("Строка") Тогда
ПостроительЗапроса.Текст = СокрЛП(НаборДанных);
Иначе
ПостроительЗапроса.Текст = СокрЛП(НаборДанных.Текст);
КонецЕсли;
ПостроительЗапроса.ЗаполнитьНастройки();
Для Каждого ПолеОтбора Из ПостроительЗапроса.ВыбранныеПоля Цикл
НоваяКолонка = КоллекцияКолонок.Добавить();
НоваяКолонка.Имя = ПолеОтбора.Имя;
НоваяКолонка.ТипЗначения = ПостроительЗапроса.ДоступныеПоля[ПолеОтбора.ПутьКДанным].ТипЗначения;
НоваяКолонка.Заголовок = ПолеОтбора.Представление
КонецЦикла;
ИначеЕсли ТипНабора = "Объект" Тогда
Для Каждого Колонка Из НаборДанных.Колонки Цикл
НоваяКолонка = КоллекцияКолонок.Добавить();
НоваяКолонка.Имя = Колонка.Имя;
НоваяКолонка.ТипЗначения = Колонка.ТипЗначения;
НоваяКолонка.Заголовок = Колонка.Имя;
КонецЦикла;
КонецЕсли;
// Добавление ресурсов
Если ТипЗнч(СтруктураРесурсов) = Тип("Структура") Тогда
Для Каждого ЭлСтруктуры Из СтруктураРесурсов Цикл
// Проверка, а Существует ли поле ресурса среди полей набора
Если КоллекцияКолонок.Найти(ЭлСтруктуры.Ключ) <> Неопределено Тогда
// Проверка на правильность указания агрегатной функции
Если ЭлСтруктуры.Значение = "Сумма" ИЛИ
ЭлСтруктуры.Значение = "Среднее" ИЛИ
ЭлСтруктуры.Значение = "Максимум" ИЛИ
ЭлСтруктуры.Значение = "Минимум" ИЛИ
ЭлСтруктуры.Значение = "Количество" Тогда
ПолеРесурса = СКД.ПоляИтога.Добавить();
ПолеРесурса.ПутьКДанным = ЭлСтруктуры.Ключ;
ПолеРесурса.Выражение = ЭлСтруктуры.Значение + "(" + ЭлСтруктуры.Ключ + ")";
ИначеЕсли ЭлСтруктуры.Значение = "КоличествоРазличные" Тогда
ПолеРесурса = СКД.ПоляИтога.Добавить();
ПолеРесурса.ПутьКДанным = ЭлСтруктуры.Ключ;
ПолеРесурса.Выражение = "Количество(Различные " + ЭлСтруктуры.Ключ + ")";
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
// Добавление полей в набор
Для Каждого НоваяКолонка Из КоллекцияКолонок Цикл
ПолеНабора = ТекущийНаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабора.Заголовок = СокрЛП(НоваяКолонка.Заголовок);
ПолеНабора.Поле = СокрЛП(НоваяКолонка.Имя);
ПолеНабора.ПутьКДанным = СокрЛП(НоваяКолонка.Имя);
// Удалим Неопределено и NULL
Массив = Новый Массив;
Для Каждого ТекущийТип Из НоваяКолонка.ТипЗначения.Типы() Цикл
Если ТекущийТип = Тип("Неопределено") ИЛИ ТекущийТип = Тип("NULL") ИЛИ
ТекущийТип = Неопределено ИЛИ ТекущийТип = Null Тогда
Продолжить;
КонецЕсли;
Массив.Добавить(ТекущийТип);
КонецЦикла;
ПолеНабора.ТипЗначения = Новый ОписаниеТипов(Массив, НоваяКолонка.ТипЗначения.КвалификаторыЧисла,
НоваяКолонка.ТипЗначения.КвалификаторыСтроки,
НоваяКолонка.ТипЗначения.КвалификаторыДаты);
ВыбранноеПолеКомпоновкиДанных = НастройкиПоУмолчанию.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ВыбранноеПолеКомпоновкиДанных.Поле = Новый ПолеКомпоновкиДанных(ПолеНабора.ПутьКДанным);
ВыбранноеПолеКомпоновкиДанных.Использование = Истина;
КонецЦикла;
// Оформление
Если не ПустаяСтрока(ИмяСтандартногоМакетаОформления) Тогда
ЗначениеПараметраВывода = НастройкиПоУмолчанию.ПараметрыВывода.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("МакетОформления"));
ЗначениеПараметраВывода.Значение = ИмяСтандартногоМакетаОформления;
ЗначениеПараметраВывода.Использование = Истина;
КонецЕсли;
Возврат СКД;
КонецФункции // СоздатьСхемуКомпоновкиДанных
Орфографическая ошибка в kambl: kambl Орфографическая ошибка в автовыбранное: автовыбранное
Выгрузить схему компоновки данных (скд) в файл/строку
Программное создание схемы СКД
Схема компоновки данных из запроса
Заполняем (описываем набор данных и поля) схему компоновки данных из таблицы значений
КомпоновщикНастроек для выполнения отбора на форме
Шаблон ПриКомпоновкеРезультата Программное формирование