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