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