Система компоновки данных (СКД) является мощным инструментом, но часто программисты сталкиваются с ситуациями, которые выходят за рамки стандартного конструктора запросов. В этой статье мы подробно разберем, как интегрировать программно сформированные данные (например, из ЗУП 3.1), как управлять порядком вывода полей, использовать сложные функции вычисления выражений и настраивать удобные интерфейсные элементы, такие как выбор периода.
Часто возникает задача: в типовых конфигурациях (ЗУП 3.1, ERP) кадровые данные или данные о себестоимости собираются сложными программными модулями, которые возвращают временную таблицу или таблицу значений. Рассмотрим, как правильно сопрягать такие данные с отчетом на СКД.
Наиболее эффективным методом является использование набора данных типа Объект. Разберем этот процесс по шагам:
ВнешниеДанныеКадров. В списке полей опишем те поля, которые мы планируем получить из программного кода (например, ФизическоеЛицо, Должность, Подразделение).ПриКомпоновкеРезультата.Рассмотрим пример кода в модуле объекта отчета:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Получаем настройки пользователя
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// Вызываем кадровые процедуры (пример для ЗУП)
ТаблицаКадровыхДанных = ПолучитьТаблицуКадровыхДанных(Настройки);
// Создаем структуру для внешних наборов данных
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ВнешниеДанныеКадров", ТаблицаКадровыхДанных);
// Далее стандартный цикл вывода программной компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Обратите внимание на важный нюанс: при формировании данных для объекта желательно считывать настройки из КомпоновщикНастроек (отборы и параметры), чтобы передать их в процедуру формирования таблицы. Это позволит базе данных выполнять фильтрацию сразу, а не выгружать миллионы строк в память 1С.
По умолчанию СКД выводит ресурсы (числовые показатели) в самом конце строки, после всех измерений и реквизитов. Но что делать, если заказчик хочет видеть, например, «Сумму», а следом за ней «Комментарий» или «Менеджера»? Выясним, как это сделать без рисования сложного макета.
Проанализируем возможности вкладки Настройки - Выбранные поля. В современных версиях платформы 8.3 реализован механизм группировки полей:
Горизонтально.Если нам нужно, чтобы реквизиты шли строго после ресурсов, мы просто перемещаем измерения/реквизиты ниже ресурсов в списке выбранных полей и используем группировку. Это позволяет гибко управлять визуальным представлением без жесткого кодирования макета.
Разберем ситуацию, когда нам нужно посчитать итог по группировке, основываясь на результатах вычисления других ресурсов. Например, если в детальных записях у нас есть формула, которая может возвращать массив или специфическое значение.
Часто возникает ошибка: при использовании ВычислитьВыражение в ресурсах итоги по группировкам «плывут» или показывают пустые значения. Рассмотрим пример использования ВычислитьВыражениеСГруппировкойМассив для расчета сложных итогов:
В выражении ресурса для нужного поля напишем:
Сумма(ВычислитьВыражениеСГруппировкойМассив("ПредварительныйРасчет", "Номенклатура"))
Почему это важно? Функция ВычислитьВыражениеСГруппировкойМассив собирает значения поля со всех группировок (в данном примере «Номенклатура») в массив, а внешняя функция Сумма корректно их складывает. Это позволяет обходить ограничения, когда агрегатные функции внутри самого вычисляемого поля работают некорректно.
Пользователи привыкли выбирать период (месяц, квартал) одним нажатием через стандартное окно «Выберите период». В чистом СКД параметры ДатаНачала и ДатаОкончания обычно выглядят как два отдельных поля ввода даты. Посмотрим на пример, как сделать это правильно.
ПериодОтчета с типом СтандартныйПериод.ДатаНачала и ДатаОкончания в колонке «Выражение» пропишем:
&ПериодОтчета.ДатаНачала&ПериодОтчета.ДатаОкончанияДатаНачала и ДатаОкончания флаг Ограничение доступности. Теперь пользователь будет видеть только удобный выбор периода, а даты в запрос подставятся автоматически.Иногда требуется вывести в заголовке или подвале отчета время, когда он был сформирован, без написания кода в модулях. Это реализуется через системные поля или параметры.
Рассмотрим самый простой способ через параметры:
ДатаФормирования.ТекущаяДата().Если же нужно красиво оформить заголовок, мы можем добавить вычисляемое поле с выражением представления:
Строка("Отчет сформирован: ") + Формат(ТекущаяДата(), "ДЛФ=DT")
Начиная с версии платформы 8.3.13, многие разработчики заметили, что программная установка отборов в КомпоновщикНастроек.ФиксированныеНастройки перестала работать «сама по себе» в некоторых самописных отчетах. Выясним причину.
Дело в том, что платформа стала требовать более явной инициализации настроек при создании формы. Если ваши отборы не применяются, попробуйте в модуле формы отчета выполнить инициализацию компоновщика, используя URL схемы, а не саму схему:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Вместо прямой передачи схемы используем путь к ней, если отчет встроенный
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(Отчет.АдресСхемы);
Отчет.КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
// Теперь фиксированные настройки подхватятся корректно
ЭлементОтбора = Отчет.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Параметры.Организация;
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
Использование АдресСхемы или прямого обращения к макету через ИсточникДоступныхНастроек гарантирует, что компоновщик на клиенте и сервере будет синхронизирован, и ваши программные отборы не «слетят» при формировании результата.
Подводя итог, можно сказать, что большинство проблем в СКД решаются либо глубоким пониманием функций ВычислитьВыражение, либо использованием программной инициализации через ВнешниеНаборыДанных. Эти подходы позволяют создавать отчеты любой сложности, сохраняя при этом гибкость настроек для конечного пользователя.