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