При разработке отчетов и обработок на платформе 1С часто возникает задача получить результат выполнения запроса из Схемы компоновки данных (СКД) не в табличный документ, а в коллекцию значений — Таблицу Значений (ТЗ). Это необходимо для дальнейшей программной обработки данных, передачи их в другие функции или вывода в специфические интерфейсные формы. Однако при попытке программно применить настройки пользователя (фильтры, параметры) многие разработчики сталкиваются с тем, что результат оказывается пустым или настройки не применяются вовсе. Разберем по шагам, как правильно реализовать этот механизм и избежать типичных ошибок.
Для начала проанализируем стандартную последовательность действий, которая требуется для выгрузки данных. Основными объектами здесь выступают КомпоновщикМакетаКомпоновкиДанных, ПроцессорКомпоновкиДанных и ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений. Типовой код выглядит следующим образом:
// 1. Получаем схему из макета
СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
// 2. Инициализируем компоновщик макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
// 3. Формируем макет компоновки
// Важно указать тип генератора: ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиДляВыполнения, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
// 4. Инициализируем процессор компоновки
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки);
// 5. Выводим результат в Таблицу Значений
ТЗ = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ТЗ);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
В этой схеме ключевым моментом является второй параметр метода Выполнить — НастройкиДляВыполнения. Именно здесь чаще всего возникают ошибки при попытке использовать программно созданные или загруженные из хранилища настройки.
Выясним причину, по которой программно загруженные настройки могут не отрабатывать. В системе СКД существует разделение на основные настройки (объект НастройкиКомпоновкиДанных) и пользовательские настройки (объект ПользовательскиеНастройкиКомпоновкиДанных).
Когда мы меняем отбор или параметры на форме отчета, платформа зачастую записывает эти изменения именно в ПользовательскиеНастройки. Если вы просто загружаете из хранилища объект настроек и передаете его в компоновщик, но при этом игнорируете пользовательские настройки, результат выполнения макета может не содержать примененных фильтров. Рассмотрим, как правильно объединить эти два объекта перед выполнением компоновки.
Наиболее изящный и надежный способ — использовать встроенный механизм компоновщика настроек. Проанализируем правильный алгоритм:
ПолучитьНастройки(), который автоматически накладывает пользовательские изменения на основную структуру.
// Создаем компоновщик и связываем его со схемой
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных);
КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
// Загружаем настройки (например, из хранилища или другого отчета)
КомпоновщикНастроек.ЗагрузитьНастройки(СохраненныеНастройки);
// Теперь получаем финальный объект настроек для выполнения макета
ФинальныеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
// Передаем эти настройки в метод Выполнить
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, ФинальныеНастройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
Посмотрим на ситуацию со стороны структуры данных. При выводе в ТабличныйДокумент СКД может обрабатывать сложные группировки, иерархию и итоги. Однако ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений имеет свои ограничения. Чтобы получить «плоскую» таблицу, которая наиболее удобна для программной обработки, необходимо убедиться, что в настройках выбрана группировка Детальные записи.
Если в ваших программно сформированных настройках присутствуют только группировки по полям (например, по Контрагенту или Номенклатуре), но отсутствуют детальные записи, в ТаблицуЗначений могут попасть только агрегированные данные или итоги. Чтобы гарантировать вывод каждой строки, убедитесь, что в структуре настроек есть элемент группировки без указания полей (пустая группировка).
Если ваша схема СКД использует Внешние наборы данных (например, если источником является уже имеющаяся в памяти ТаблицаЗначений), крайне важно правильно инициализировать ПроцессорКомпоновкиДанных. Проанализируем пример передачи внешних данных:
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("МояВнешняяТЗ", ИсходнаяТаблица);
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
// Передаем структуру внешних наборов вторым параметром
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных);
Без указания внешних наборов данных во время инициализации процессора, СКД не сможет сопоставить поля схемы с данными, и результат в итоговой ТЗ будет пустым, даже если настройки сформированы идеально.
При выводе в коллекцию значений стоит обратить внимание на типизацию колонок. 1С автоматически пытается определить типы колонок ТЗ на основе описания полей в СКД. Однако, если в результате запроса по какому-то полю приходят только значения NULL, колонка может остаться без типа, что вызовет ошибку при попытке записать туда данные другого типа в дальнейшем. Рекомендуем в запросе СКД всегда использовать функцию ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) для обеспечения строгости типов.
Также, перед выполнением метода Выполнить, хорошей практикой считается проверка настроек на валидность, особенно если они были загружены из внешнего источника. Это можно сделать методом ПроверитьНастройки() компоновщика настроек. Это поможет отловить ошибки удаления полей в конфигураторе, которые остались в старых сохраненных настройках пользователя.
Используя предложенные методы инициализации компоновщика через ИсточникДоступныхНастроекКомпоновкиДанных и объединение настроек через ПолучитьНастройки(), мы обеспечиваем стабильную и предсказуемую работу механизма выгрузки данных из СКД в Таблицу Значений.