Как программно выгрузить данные СКД в таблицу значений и вывести в свой макет

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

Нередко перед разработчиком встает задача построить отчет со сложным, нестандартным макетом (например, утвержденной регламентированной печатной формой или многоуровневой сложной шапкой), который крайне тяжело или невозможно сверстать штатными средствами компоновщика. В то же время отказываться от системы компоновки данных (СКД) не хочется, ведь она берет на себя автоматическое наложение пользовательских отборов, работу с системными параметрами и возможность фонового формирования с рассылкой.

Оптимальный выход в такой ситуации — использовать СКД в качестве мощного генератора данных: перехватить выполнение отчета, программно установить неизменные параметры, выгрузить результат работы схемы в объект ТаблицаЗначений и затем вручную вывести строки в подготовленный табличный документ. Разберем по шагам, как правильно реализовать эту схему и избежать типичных системных ошибок.

Пошаговый алгоритм программной компоновки в таблицу значений

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

  1. Отключаем стандартное формирование отчета, присвоив параметру СтандартнаяОбработка = Ложь;.
  2. Программно передаем в настройки компоновщика значения неизменяемых параметров (константы, массивы кодов, списки счетов).
  3. Инициализируем КомпоновщикМакетаКомпоновкиДанных с использованием специализированного генератора ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений.
  4. Создаем ПроцессорКомпоновкиДанных и передаем ему скомпилированный макет.
  5. Используем объект ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений, привязываем к нему пустую таблицу значений и выполняем вывод.
  6. Обходим полученную таблицу и заполняем готовый ТабличныйДокумент по своему произвольному макету.

Посмотрим на пример процедуры ПриКомпоновкеРезультата в модуле объекта отчета:


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

    СтандартнаяОбработка = Ложь;

    // 1. Программная установка неизменяемых параметров отчета
    ПараметрыДанных = КомпоновщикНастроек.Настройки.ПараметрыДанных;

    КПСПереоценки = Новый СписокЗначений;
    КПСПереоценки.Добавить(Справочники.КлассификационныеПризнакиСчетов.НайтиПоКоду("00000000000000171"));

    МассивЗатрат = Новый Массив;
    Для Каждого Стр Из ВернутьМассивКЭК("200") Цикл
        МассивЗатрат.Добавить(Стр);
    КонецЦикла;
    Для Каждого Стр Из ВернутьМассивКЭК("300") Цикл
        МассивЗатрат.Добавить(Стр);
    КонецЦикла;

    ПараметрыДанных.УстановитьЗначениеПараметра("КПСПереоценки", КПСПереоценки);
    ПараметрыДанных.УстановитьЗначениеПараметра("КПСДохода", ВернутьМассивКПС(Перечисления.ВидыКБК.КДБ));
    ПараметрыДанных.УстановитьЗначениеПараметра("КПСРасхода", ВернутьМассивКПС(Перечисления.ВидыКБК.КРБ));
    ПараметрыДанных.УстановитьЗначениеПараметра("КЭКДохода", ВернутьМассивКЭК("100"));
    ПараметрыДанных.УстановитьЗначениеПараметра("КэкЗатрат", МассивЗатрат);

    // 2. Создание макета компоновки для коллекции значений
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();

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

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

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

    // 5. Формирование собственного макета по данным ТаблицаДанных
    ВывестиСвойМакетВТабличныйДокумент(ДокументРезультат, ТаблицаДанных);

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

Причина ошибки «Не поддерживается вывод таблиц и диаграмм в универсальную коллекцию значений»

При использовании вызова КомпоновщикМакета.Выполнить(...) с типом ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений разработчики часто сталкиваются с исключением:

«Ошибка компоновки макета: Ошибка генерации макета: Не поддерживается вывод таблиц и диаграмм в универсальную коллекцию значений»

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

  1. В структуре отчета присутствует элемент «Таблица» или «Диаграмма». Если в дереве структуры отчета на закладке «Настройки» СКД создан элемент кросс-таблицы (содержащий строки и колонки) или диаграммы, генератор коллекции не может преобразовать двухмерную матрицу в плоскую таблицу. Приемлемым элементом структуры для таблицы значений является обычная плоская группировка без указания поля группировки (то есть «Детальные записи»).
  2. Вложенность детальных записей внутри таблицы. Нередко при редактировании схемы разработчик добавляет детальные записи внутрь строк существующей таблицы, при этом сам элемент ТаблицаКомпоновкиДанных остается родителем. Структуру необходимо очистить и добавить элемент типа ГруппировкаКомпоновкиДанных верхнего уровня.
  3. Влияние кэшированных пользовательских настроек. Метод КомпоновщикНастроек.ПолучитьНастройки() возвращает настройки с учетом сохраненного пользовательского состояния формы. Если пользователь (или разработчик в режиме отладки) ранее открывал отчет, в его системных настройках могла сохраниться старая структура схемы. В этом случае изменения в конфигураторе не вступят в силу, пока не выполнен сброс.

Способы решения проблемы со структурой

Разберем, как гарантированно устранить ошибку выгрузки:

Способ 1. Программное переопределение структуры отчета

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


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

// Очищаем существующую структуру (таблицы, диаграммы)
Настройки.Структура.Очистить();

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

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

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

Способ 2. Сброс настроек в режиме предприятия

Если структура правится в схеме компоновки вручную (удалены таблицы и оставлены только «Детальные записи» в корне), в режиме «1С:Предприятие» в форме отчета обязательно нужно нажать Еще — Установить стандартные настройки. Это заставит платформу стереть кэш старой структуры из системного хранилища.

Особенности передачи параметров

Обратим внимание на нюанс работы с параметрами. Когда мы устанавливаем значения в КомпоновщикНастроек.Настройки.ПараметрыДанных, а затем вызываем КомпоновщикНастроек.ПолучитьНастройки(), новые параметры гарантированно попадают в результирующий набор.

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


Настройки = КомпоновщикНастроек.ПолучитьНастройки();
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("КПСПереоценки", КПСПереоценки);

Также важно помнить о полях выбора: в созданную ТаблицуЗначений попадут исключительно те поля, которые добавлены в ветку «Выбранные поля» компоновщика настроек. Если состав выбранных полей пуст, результирующая таблица значений будет создана без колонок.

← На главную