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