Как программно изменить макет схемы компоновки данных (СКД) в отчете 1С:Предприятия 8.3 и учесть пользовательские настройки?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Общий подход к программному изменению макета СКД

Прежде чем мы перейдем к конкретным примерам, рассмотрим общую логику действий, которую нам предстоит выполнить для программной модификации схемы компоновки данных. Стоит отметить, что стандартная объектная модель СКД довольно громоздка, и для упрощения работы часто применяют СКДБилдер — специальный модуль-обертку, который делает код значительно компактнее. Общий же подход позволяет гибко управлять структурой отчета в зависимости от различных условий:

  1. Получение объекта схемы компоновки данных: Нам необходимо получить объект СхемаКомпоновкиДанных, который представляет собой описание структуры нашего отчета. Это может быть как основная схема из макета отчета, так и использование двух разных схем в одном отчете в зависимости от условий.
  2. Клонирование схемы: Очень важно работать с копией схемы. Если мы будем изменять оригинальный объект схемы, который является частью метаданных, это может привести к непредсказуемым последствиям и изменению поведения отчета для всех пользователей. Поэтому мы всегда будем клонировать схему.
  3. Внесение изменений в клонированную схему: На этом этапе мы программно модифицируем различные элементы клонированной схемы: добавляем новые поля, изменяем существующие, корректируем ресурсы, параметры, наборы данных и так далее.
  4. Применение измененной схемы и формирование отчета: После того как мы внесли все необходимые изменения в клонированную схему, нам нужно применить ее к компоновщику настроек или непосредственно использовать для формирования отчета. Далее мы запускаем стандартный процесс компоновки и вывода результата.

Этот алгоритм позволяет нам динамически менять структуру отчета, не затрагивая его исходный макет в конфигурации.

Детальный разбор: Добавление нового поля и изменение заголовка существующего

Рассмотрим конкретный пример: нам нужно добавить новое поле в список выбранных полей отчета и изменить заголовок одного из уже существующих полей. К слову, иногда разработчикам требуется выполнить программное изменение заголовка группировки, что решается схожими методами работы с коллекциями схемы. Код модификации мы обычно размещаем в обработчике события ПриКомпоновкеРезультата в модуле объекта отчета.

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


// В модуле формы отчета или в модуле объекта отчета
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

    СтандартнаяОбработка = Ложь; // Важно: отключаем стандартную обработку, т.к. мы формируем отчет вручную

    // 1. Получаем схему компоновки данных отчета.
    // Если схема хранится в макете объекта отчета, мы можем получить ее так:
    Схема = ОтчетОбъект.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");

    // 2. Клонируем схему, чтобы все изменения применялись к копии, а не к оригинальному макету.
    МакетСКДКлон = Схема.Скопировать();

    // Получаем текущие настройки компоновщика.
    НастройкиКомпоновщикаТекущие = КомпоновщикНастроек.Настройки;

    // 3. Получаем объект коллекции выбранных полей из настроек по умолчанию клонированной схемы.
    ВыбранныеПоляСхемы = МакетСКДКлон.НастройкиПоУмолчанию.ВыбранныеПоля;

    // 4. Добавляем новое поле в выбранные поля схемы.
    НовоеПоле = ВыбранныеПоляСхемы.Добавить(Тип("ПолеКомпоновкиДанных"));
    НовоеПоле.Поле = "НаименованиеНовогоПоля"; 
    НовоеПоле.Заголовок = "Наш специально добавленный заголовок";

    // 5. Изменяем заголовок существующего поля.
    Для Каждого ЭлементПоля Из ВыбранныеПоляСхемы Цикл
        Если ЭлементПоля.Поле = "ПолеСуществующее" Тогда 
            ЭлементПоля.Заголовок = "Измененный заголовок для существующего поля";
            Прервать; 
        КонецЕсли;
    КонецЦикла;

    // 6. Применяем измененную схему к компоновщику настроек.
    КомпоновщикНастроек.Инициализировать(МакетСКДКлон);

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

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

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

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

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

Проблема с пользовательскими настройками и её решение

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

Чтобы обойти проблему приоритета настроек пользователя, нам нужно не просто инициализировать компоновщик новой схемой, но и активно скорректировать текущие настройки компоновщика, чтобы добавить в них наши программно определенные поля. Рассмотрим, как это сделать:


// ... (начало кода из предыдущего примера)

    // Инициализируем компоновщик нашей клонированной схемой.
    КомпоновщикНастроек.Инициализировать(МакетСКДКлон);

    // Теперь получаем актуальные настройки и программно добавляем в них желаемые поля.
    НастройкиКомпоновщикаАктуальные = КомпоновщикНастроек.Настройки;

    ПеречислениеЭлементовНастроек = НастройкиКомпоновщикаАктуальные.ВыбранныеПоля.Элементы;
    ГруппаПолейАвто = ПеречислениеЭлементовНастроек.Найти("ГруппаДополнительныхПолейАвто");

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

    НовоеПолеНастроек = ГруппаПолейАвто.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
    НовоеПолеНастроек.Поле = "НаименованиеНовогоПоля"; 
    НовоеПолеНастроек.Текст = "Наш специально добавленный заголовок"; 

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

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

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

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

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

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

Важные моменты и дополнительные рекомендации

  1. Различие между схемой и настройками:

    Схема — это шаблон, определяющий доступные данные. Настройки — параметры его использования. Для отладки этих структур крайне полезно использовать Инструментики — набор инструментов разработчика, включающий мощные консоли СКД и запросов для тонкого клиента.

  2. Место размещения кода:

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

  3. Влияние на производительность:

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

  4. Особенности работы с типами:

    Не путайте ПолеКомпоновкиДанных (для схемы) и ВыбранноеПолеКомпоновкиДанных (для настроек компоновщика).

  5. Дополнительные возможности:

    Вы можете управлять наборами данных, ресурсами, параметрами и отборами, обращаясь к соответствующим свойствам объекта СхемаКомпоновкиДанных.

Мы рассмотрели основной принцип программной модификации макета СКД и его применение. Эти знания помогут вам создавать более гибкие и функциональные отчеты в системе 1С:Предприятие 8.3.

← На главную