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