Почему не заполняется таблица значений при программном формировании отчета СКД?

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

Часто при программной работе с Системой Компоновки Данных (СКД) возникает ситуация: код выполняется без ошибок, отладчик показывает, что запрос к базе данных отработал и данные получены, но итоговая ТаблицаЗначений остается пустой. Давайте вместе разберемся, почему это происходит и как исправить такую ситуацию на примере конкретного кода.

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


СхемаСКД = ПолучитьМакет("ВыгрузкаНоменклатуры"); 
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; 
КомпоновщикСхемы = Новый КомпоновщикНастроекКомпоновкиДанных; 

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

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

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

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

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

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

На первый взгляд, все объекты созданы и инициализированы правильно. Однако результат пуст. Выясним причину.

Причина №1: Не определена структура отчета в настройках

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

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

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

Посмотрим на исправленный и дополненный код:


СхемаСКД = ПолучитьМакет("ВыгрузкаНоменклатуры");
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

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

// Устанавливаем параметры
ПараметрУзел = НастройкиСКД.ПараметрыДанных.Элементы.Найти("УзелОбмена");
ПараметрУзел.Использование = Истина;
ПараметрУзел.Значение = ПланОбмена;

// --- НАЧАЛО ВАЖНОГО БЛОКА ---
// Очищаем существующую структуру на случай, если в схеме были настройки по умолчанию
НастройкиСКД.Структура.Очистить();

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

// Добавляем в выборку все доступные поля из набора данных
// АвтоВыбранноеПолеКомпоновкиДанных - это специальный объект для этой цели
АвтоВыбор = ДетальныеЗаписи.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
АвтоВыбор.Использование = Истина;
// --- КОНЕЦ ВАЖНОГО БЛОКА ---

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

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

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

// Теперь в переменной "Результат" должны быть данные
Сообщить("Количество строк в результате: " + Результат.Количество());

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

Причина №2: Отсутствие данных в источнике

Банально, но возможно. Запрос с переданными параметрами может действительно не возвращать ни одной строки. Прежде чем искать ошибку в коде вывода, убедитесь, что данные вообще есть.

Методы проверки:

  1. Консоль запросов. Скопируйте текст запроса из макета СКД, вставьте его в консоль запросов, установите те же значения параметров (в нашем случае УзелОбмена) и выполните. Если результат пуст, проблема в самом запросе или в данных, а не в коде компоновки.
  2. Временный вывод в табличный документ. Вывод в ТабличныйДокумент — более стандартная и менее требовательная к настройкам операция. Если данные не выводятся даже в него, это почти наверняка означает их отсутствие. Замените конечную часть кода на следующую:

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

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

ПроцессорВывода.Вывести(ПроцессорКомпоновки);

// Показываем результат пользователю
ТабличныйДокумент.Показать("Результат выполнения СКД");

Причина №3: Ограничения при выводе в коллекцию значений

Важно помнить, что генератор макета для коллекции значений (ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений) имеет строгие ограничения. Он предназначен для получения "сырых" данных и не поддерживает сложные элементы отчета.

Если в настройках СКД (особенно в настройках по умолчанию, сохраненных в самой схеме) присутствуют такие элементы, как:

...то вывод в ТаблицуЗначений или ДеревоЗначений завершится неудачей, и результат будет пустым. Перед программным формированием откройте схему в конфигураторе и проверьте, что на вкладке "Настройки" нет таких несовместимых элементов.

Пошаговый план отладки

Если вы столкнулись с проблемой пустой таблицы при работе с СКД, действуйте по следующему алгоритму:

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

Следуя этим шагам, вы сможете быстро диагностировать и устранить причину, по которой ваша ТаблицаЗначений остается пустой.

← На главную