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