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