Почему в отчете СКД возникает ошибка «Не найден внешний набор данных» и как ее исправить?

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

При разработке отчетов на базе системы компоновки данных (СКД) часто возникает необходимость передать в качестве источника произвольные данные — например, программно сформированную таблицу значений. Однако при попытке сформировать отчет разработчики нередко сталкиваются с ошибкой «Не найден внешний набор данных». Разберем детально, почему возникает данная ситуация, как правильно настроить программный вывод и избежать типичных ошибок при заполнении наборов данных.

Причина 1. Не отключена стандартная обработка формирования отчета

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

Дело в том, что процедура ПриКомпоновкеРезультата принимает параметр СтандартнаяОбработка, который по умолчанию равен Истина. Если не переопределить этот параметр, платформа после выполнения пользовательского кода инициирует стандартный механизм компоновки данных. Стандартный механизм пытается заново скомпоновать отчет без переданной структуры внешних наборов данных и закономерно падает с ошибкой.

Для исправления ситуации в самом начале процедуры обязательно укажем:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Формирование данных и программный вывод отчета
    
КонецПроцедуры

Причина 2. Несоответствие имени объекта в схеме и ключе структуры

Рассмотрим еще одну распространенную проблему. В схеме компоновки данных у набора данных типа «Объект» присутствуют два свойства:

  1. Имя набора данных — внутреннее имя набора в схеме.
  2. Имя объекта, содержащего данные — ключ, по которому компоновщик ищет источник во внешней структуре.

Ключом в структуре ВнешниеНаборыДанных должно выступать именно значение из поля «Имя объекта, содержащего данные». Если указать имя самого набора или допустить опечатку в регистре символов, процессор компоновки данных не сможет сопоставить переданную таблицу со схемой.

Пример корректного программного формирования отчета

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


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

Частая ошибка при заполнении ТаблицыЗначений

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


// ОШИБКА: метод Добавить() вызван только один раз
нс = тз.Добавить();
нс.Поле1 = "33№";
нс.Поле1 = "44№";
нс.Поле1 = "55№";

В этом случае в объекте ТаблицаЗначений создается всего одна строка, и ее колонка Поле1 последовательно перезаписывается новыми значениями. Чтобы в отчете отразились все строки, метод Добавить() необходимо вызывать для каждого элемента отдельно перед присвоением значений колонкам.

Важные рекомендации по работе с внешними наборами данных

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