1С 8.3 Схема компоновки данных - Программист 1С Минск. Автоматизация бизнеса.

Перейти к контенту

1С 8.3 Схема компоновки данных

Данные > Примеры кода 1С > 1С 8.3 Схема компоновки данных (СКД)
Схема компоновки данных (СКД) в 1С 8.3 - это механизм создания отчетов со сложно структурированной информацией (настройки, детализация и свертка, группировка и отборы, результирующие формы) на основе их декларативного описания. Архитектура: настройка, сама СКД, макет, результат, форма данных (например, таблица). Главной особенностью применения СКД это автоматическая генерация выходной формы и создание отчета без написания кода. Процессом построения отчета можно управлять программно, а непосредственно само  исполнение отчета разбивать по этапам. При разработке и отладке удобно использовать КонсольСистемыКомпоновкиДанных.erf, которая позволяет в формате XML выводить промежуточные результаты запросов и анализировать отдельные составляющие СКД.
Создание СКД (программно) в 1С 8.3:
Функция СозданиеСКД(НаборДанных, СтруктураРесурсов = Неопределено, АвтоЗаполнениеДоступныхПолей = Истина, ИмяМакета = "")
   
// Универсальная функция которая принимает различные наборы данных и возвращающую готовую СКД
    //
    // Расшифровка параметров функции:
    // НаборДанных  (Тип: Строка, Запрос, ТЗ, ДЗ) - искомый набор данных
    // СтруктураРесурсов (Тип: Структура) - структура полей ресурсов, где ключ - ИмяПоля, Значение(Строка) - агрег.функция
    // ИмяМакета (Тип: Строка) - Имя макета оформления
   
Схема = Новый СхемаКомпоновкиДанных;

   
// Заполнение основных данных СКД
   
ИсточникДанных = Схема.ИсточникиДанных.Добавить();
   
ИсточникДанных.ТипИсточникаДанных = "Local";
   
ИсточникДанных.Имя = "ИсточникДанных";

    Если (
ТипЗнч(НаборДанных) = Тип("Строка")) или (ТипЗнч(НаборДанных) = Тип("Запрос")) Тогда
       
ТекНаборДанных = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
       
ТекНаборДанных.Имя = "ОсновнойНабор";
       
ТекНаборДанных.Запрос = ?(ТипЗнч(НаборДанных) = Тип("Строка"),НаборДанных,НаборДанных.Текст);
       
ТекНаборДанных.ИсточникДанных = "ИсточникДанных";
       
ТипНабора = "Запрос";
       
ТекНаборДанных.АвтоЗаполнениеДоступныхПолей = АвтоЗаполнениеДоступныхПолей;
    ИначеЕсли (
ТипЗнч(НаборДанных) = Тип("ТаблицаЗначений")) или (ТипЗнч(НаборДанных) = Тип("ДеревоЗначений")) Тогда
       
ТекНаборДанных = Схема.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
       
ТекНаборДанных.Имя = "ОсновнойНабор";
       
ТекНаборДанных.ИмяОбъекта = "ТаблицаИсточник";
       
ТекНаборДанных.ИсточникДанных = "ИсточникДанных";
       
ТипНабора = "Объект";
    Иначе
        Возврат Неопределено;
    КонецЕсли;

   
// Создание структуры СКД
   
НастройкиСКД = Схема.НастройкиПоУмолчанию;

   
// Группировка, записи и автополе СКД
   
ГруппировкаСКД = НастройкиСКД.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
   
ГруппировкаСКД.Использование = Истина;

   
АвтоПоле = ГруппировкаСКД.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
   
АвтоПоле.Использование = Истина;

   
КолонкиТЗ = Новый ТаблицаЗначений;
   
КолонкиТЗ.Колонки.Добавить("Имя");
   
КолонкиТЗ.Колонки.Добавить("ТипЗначения");
   
КолонкиТЗ.Колонки.Добавить("Заголовок");

    Если
ТипНабора = "Запрос" Тогда

       
ПостроительСКД = Новый ПостроительЗапроса;
        Если
ТипЗнч(НаборДанных) = Тип("Строка") Тогда
           
ПостроительСКД.Текст = СокрЛП(НаборДанных);
        Иначе
           
ПостроительСКД.Текст = СокрЛП(НаборДанных.Текст);
        КонецЕсли;
       
ПостроительСКД.ЗаполнитьНастройки();

        Для Каждого
ВыбранноеПоле Из ПостроительСКД.ВыбранныеПоля Цикл
           
НовКолонка = КолонкиТЗ.Добавить();
           
НовКолонка.Имя = ВыбранноеПоле.Имя;
           
НовКолонка.ТипЗначения = ПостроительСКД.ДоступныеПоля[ВыбранноеПоле.ПутьКДанным].ТипЗначения;
           
НовКолонка.Заголовок = ВыбранноеПоле.Представление
        КонецЦикла;

    ИначеЕсли
ТипНабора = "Объект" Тогда

        Для Каждого
Колонка Из НаборДанных.Колонки Цикл
           
НовКолонка = КолонкиТЗ.Добавить();
           
НовКолонка.Имя = Колонка.Имя;
           
НовКолонка.ТипЗначения = Колонка.ТипЗначения;
           
НовКолонка.Заголовок = Колонка.Имя;
        КонецЦикла;

    КонецЕсли;

   
// Добавление ресурсов СКД
   
Если ТипЗнч(СтруктураРесурсов) = Тип("Структура") Тогда
        Для Каждого
ЭлСтруктуры Из СтруктураРесурсов Цикл
           
// Проверка, а существует ли поле ресурса среди полей набора
           
Если КолонкиТЗ.Найти(ЭлСтруктуры.Ключ) <> Неопределено Тогда
               
// Проверка на правильность указания агрегатной функции
               
Если (ЭлСтруктуры.Значение = "Сумма")
                    ИЛИ (
ЭлСтруктуры.Значение = "Среднее")
                    ИЛИ (
ЭлСтруктуры.Значение = "Максимум")
                    ИЛИ (
ЭлСтруктуры.Значение = "Минимум")
                    ИЛИ (
ЭлСтруктуры.Значение = "Количество") Тогда

                   
ПолеРесурса             = Схема.ПоляИтога.Добавить();
                   
ПолеРесурса.ПутьКДанным = ЭлСтруктуры.Ключ;
                   
ПолеРесурса.Выражение   = ЭлСтруктуры.Значение + "(" + ЭлСтруктуры.Ключ + ")";
                ИначеЕсли
ЭлСтруктуры.Значение = "КоличествоРазличные" Тогда
                   
ПолеРесурса             = Схема.ПоляИтога.Добавить();
                   
ПолеРесурса.ПутьКДанным = ЭлСтруктуры.Ключ;
                   
ПолеРесурса.Выражение   = "Количество(Различные " + ЭлСтруктуры.Ключ + ")";
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;

   
// Добавление полей в набор СКД
   
Для каждого НовКолонка Из КолонкиТЗ Цикл
       
ПолеНабораСКД = ТекНаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
       
ПолеНабораСКД.Заголовок = СокрЛП(НовКолонка.Заголовок);
       
ПолеНабораСКД.Поле = СокрЛП(НовКолонка.Имя);
       
ПолеНабораСКД.ПутьКДанным = СокрЛП(НовКолонка.Имя);

       
// Удаление "Неопределено" и "NULL"
       
Массив = Новый Массив;
        Для каждого
ТекущийТип Из НовКолонка.ТипЗначения.Типы() Цикл
            Если (
ТекущийТип = Тип("Неопределено")) или (ТекущийТип = Тип("NULL"))
                или (
ТекущийТип = Неопределено) или (ТекущийТип = Null) Тогда
                Продолжить;
            КонецЕсли;
           
Массив.Добавить(ТекущийТип);
        КонецЦикла;
       
ПолеНабораСКД.ТипЗначения = Новый ОписаниеТипов(Массив,НовКолонка.ТипЗначения.КвалификаторыЧисла,
       
НовКолонка.ТипЗначения.КвалификаторыСтроки,НовКолонка.ТипЗначения.КвалификаторыДаты);

       
ВыбранноеПолеКомпоновкиДанных = НастройкиСКД.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
       
ВыбранноеПолеКомпоновкиДанных.Поле = Новый ПолеКомпоновкиДанных(ПолеНабораСКД.ПутьКДанным);
       
ВыбранноеПолеКомпоновкиДанных.Использование = Истина;
    КонецЦикла;

   
// Оформление СКД
   
Если Не ПустаяСтрока(ИмяМакета) Тогда
       
МОф = НастройкиСКД.ПараметрыВывода.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("МакетОформления"));
       
ЗначениеПараметраВывода = МОф;
       
ЗначениеПараметраВывода.Значение = ИмяМакета;
       
ЗначениеПараметраВывода.Использование = Истина;
    КонецЕсли;

    Возврат
Схема;

КонецФункции
Создание СКД (с процессором) в 1С 8.3:
&НаКлиенте
Процедура СозданиеСКДсПроцессором(Команда)

   
СозданиеСКДНаСервере();
   
Элементы.РезультатСКД.ОтображениеСостояния.Видимость = Ложь;
   
Элементы.РезультатСКД.ОтображениеСостояния.ДополнительныйРежимОтображения = ДополнительныйРежимОтображения.НеИспользовать;

КонецПроцедуры

&НаСервере
Процедура СозданиеСКДНаСервере()

   
// Реквизиты формы/переменные:
    // Поставщик
    // ВыборПериода
    // РезультатСКД

   
Перем ДанныеРасшифровкиВрем; // Переменная для КомпоновщикМакета.Выполнить():
    //Нельзя использовать "ДанныеРасшифровки" при инициалиации Процессора компоновки, т.к. это реквизит формы
    //Нужен для обработки расшифровки (туда помещается адрес во временное хранилище, через 2 строки)
    //Иначе расшифровка СКД будет выводить только индексы элементов расшифровки

   
ОбъектОтчет = РеквизитФормыВЗначение("ОтчетПоПоставщикам");
   
Схема = ОбъектОтчет.ПолучитьМакет("ОсновнаяСКД");

   
//Если нужно обработать текст запроса (например, в зависимости от реквизита формы), то выводим в отдельную функцию:
    //Запрос = СхемаКомпоновки.НаборыДанных.НаборДанных1.Запрос;
    //СхемаКомпоновки.НаборыДанных.НаборДанных1.Запрос = ОбработкаТекстаЗапроса(Запрос);

   
НастройкиПоУмолч = Схема.НастройкиПоУмолчанию; // Реквизит формы, тип: "Произвольный"

    // Установка настроек СКД (делаем их недоступными пользователю на закладке Параметры СКД):
    // 1) Используется параметр, а не отбор, т.к. отбор используется во временной таблице (фильтре) и не выводится в результат СКД
    // Это значит, что поля для отбора нет.
   
ПараметрПоставщик = Отчет.КомпоновщикНастроек.НастройкиПоУмолч.ПараметрыДанных.Элементы[0];
   
ПараметрПоставщик.Значение = Поставщик;
   
ПараметрПоставщик.Использование = Истина;

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

   
НастройкиСКД = Отчет.КомпоновщикНастроек.Настройки;
   
// Формирование отчета СКД:
   
Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
   
МакетКомпоновки = Компоновщик.Выполнить(Схема, НастройкиСКД, ДанныеРасшифровкиВрем);

   
ДанныеРасшифровки = ПоместитьВоВременноеХранилище(ДанныеРасшифровкиВрем, УникальныйИдентификатор);

   
Процессор = Новый ПроцессорКомпоновкиДанных;
   
Процессор.Инициализировать(МакетКомпоновки,,ДанныеРасшифровкиВрем);

   
// Индикатор с % вывода отчета
   
РезультатСКД.Очистить();
   
ПроцессорРезультата = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
   
ПроцессорРезультата.УстановитьДокумент(РезультатСКД);
   
ПроцессорРезультата.Вывести(Процессор);
   
//ДокументРезультат.ПоказатьУровеньГруппировокСтрок(0); // 0 - следующий за общим итогом

КонецПроцедуры
Отбор по полю компоновки в 1С 8.3:
&НаСервере
Процедура ПодключитьОтборПоПолюКомпоновки(Имя, Значение, ВидСравнения, Использование)

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

   
ЭлементОтбора = Отчет.КомпоновщикНастроек.НастройкиСКД.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
   
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(Имя);
   
ЭлементОтбора.ВидСравнения = ВидСравнения;
   
ЭлементОтбора.ПравоеЗначение = Значение;
   
ЭлементОтбора.Использование = Использование;

КонецПроцедуры

&НаСервере
Процедура ОтключитьОтборПоПолюКомпоновки(Имя)

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

КонецПроцедуры
Вывод СКД в табличный документ в 1С 8.3:
&НаСервере
Процедура ВыводСКДвТабличныйДокумент(ТаблДокумент_СКД, СхемаКомпоновки, КомпоновщикНастроек, ДанныеРасшифровки)

   
НаборыДанныхВнешние = Новый Структура;

   
Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
   
МакетКомпоновки = Компоновщик.Выполнить(СхемаКомпоновки, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);

   
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
   
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, НаборыДанныхВнешние, ДанныеРасшифровки, Истина);

   
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
   
ПроцессорВывода.УстановитьДокумент(ТаблДокумент_СКД); // Результирующий документ

   
ПроцессорВывода.Вывести(ПроцессорКомпоновки, Истина);

КонецПроцедуры
Функции добавленные в СКД начиная с релиза 8.3.20:
Лев(Left) – получить первые слева символы строки.
Прав(Right) – получить первые справа символы строки.
СокрЛ(TrimL) – отбросить незначащие пробелы слева.
СокрП(TrimR) – отбросить незначащие пробелы справа.
СокрЛП(TrimAll) – отбросить незначащие пробелы слева и справа.
СтрНайти(StrFind) – найти подстроку в строке (без учета регистра).
СтрЗаменить(StrReplace) – заменяет все вхождения подстроки на другую подстроку (без учета регистра).
ВРег(Upper) – преобразует все символы строки в верхний регистр.
НРег(Lower) – преобразует все символы строки в нижний регистр.
НСтр(NStr) – получает строку на языке пользователя (аналогично тому, как работает метод НСтр глобального контекста). Параметры:
  • ИсходнаяСтрока – строка, содержащая строки на разных языках (например, "ru = 'Добрый вечер!'; en = 'Good Evening!'").
  • КодЯзыка (необязательный) – строка с кодом языка, на котором нужно получать строку. Если не указан - строка получается на языке текущего пользователя.
📰 Актуальные новости с тегом #СКД:
  • В версии 8.3.21 при настройке характеристик объектов конфигурации реализована возможность указать, что характеристика может содержать более одного значения. Реализована поддержка этой возможности в системе компоновки данных и динамическом списке.
    Для объекта ОписаниеХарактеристик реализованы свойства ПолеИспользованияМножественныхЗначений, ПолеКлючаМножественныхЗначений, ПолеПорядкаМножественныхЗначений.
    Если в информационной базе указаны множественные характеристики, то при переходе на предыдущие версии платформы, данные в результате компоновки данных могут "задваиваться". В связи с этим не рекомендуется использовать предыдущие версии системы "1С:Предприятие" после указания множественных значений характеристик.
0
комментарии
____________________
Copyright©, «Программист 1С в г.Минске», 03.11.2020
Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник
Яндекс.Метрика
Защищенное соединение ssl
visa
mastercard
Maestro
Яндекс деньги
Назад к содержимому