Как решать сложные задачи в СКД: интеграция внешних данных, функции агрегации и настройка интерфейса

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Система компоновки данных (СКД) является мощным инструментом, но часто программисты сталкиваются с ситуациями, которые выходят за рамки стандартного конструктора запросов. В этой статье мы подробно разберем, как интегрировать программно сформированные данные (например, из ЗУП 3.1), как управлять порядком вывода полей, использовать сложные функции вычисления выражений и настраивать удобные интерфейсные элементы, такие как выбор периода.

Интеграция внешних данных в отчет СКД (на примере ЗУП 3.1)

Часто возникает задача: в типовых конфигурациях (ЗУП 3.1, ERP) кадровые данные или данные о себестоимости собираются сложными программными модулями, которые возвращают временную таблицу или таблицу значений. Рассмотрим, как правильно сопрягать такие данные с отчетом на СКД.

Наиболее эффективным методом является использование набора данных типа Объект. Разберем этот процесс по шагам:

  1. В схеме компоновки данных создадим новый Набор данных - объект. Дадим ему имя, например, ВнешниеДанныеКадров. В списке полей опишем те поля, которые мы планируем получить из программного кода (например, ФизическоеЛицо, Должность, Подразделение).
  2. В модуле объекта отчета перехватим событие ПриКомпоновкеРезультата.
  3. Внутри этой процедуры вызовем нужную нам процедуру общего модуля, которая сформирует таблицу значений с данными.
  4. Передадим полученную таблицу в процессор компоновки через структуру внешних наборов данных.

Рассмотрим пример кода в модуле объекта отчета:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Получаем настройки пользователя
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Вызываем кадровые процедуры (пример для ЗУП)
    ТаблицаКадровыхДанных = ПолучитьТаблицуКадровыхДанных(Настройки);
    
    // Создаем структуру для внешних наборов данных
    ВнешниеНаборыДанных = Новый Структура;
    ВнешниеНаборыДанных.Вставить("ВнешниеДанныеКадров", ТаблицаКадровыхДанных);
    
    // Далее стандартный цикл вывода программной компоновки
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Обратите внимание на важный нюанс: при формировании данных для объекта желательно считывать настройки из КомпоновщикНастроек (отборы и параметры), чтобы передать их в процедуру формирования таблицы. Это позволит базе данных выполнять фильтрацию сразу, а не выгружать миллионы строк в память 1С.

Вывод реквизитов и измерений после ресурсов

По умолчанию СКД выводит ресурсы (числовые показатели) в самом конце строки, после всех измерений и реквизитов. Но что делать, если заказчик хочет видеть, например, «Сумму», а следом за ней «Комментарий» или «Менеджера»? Выясним, как это сделать без рисования сложного макета.

Проанализируем возможности вкладки Настройки - Выбранные поля. В современных версиях платформы 8.3 реализован механизм группировки полей:

  1. Перейдем в настройки варианта отчета на вкладку «Выбранные поля».
  2. Нажмем правую кнопку мыши и выберем Новая группа выбранных полей.
  3. В эту группу добавим ресурсы и реквизиты в том порядке, в котором они должны идти в отчете.
  4. Установим у группы свойство Расположение в значение Горизонтально.

Если нам нужно, чтобы реквизиты шли строго после ресурсов, мы просто перемещаем измерения/реквизиты ниже ресурсов в списке выбранных полей и используем группировку. Это позволяет гибко управлять визуальным представлением без жесткого кодирования макета.

Использование сложных выражений: ВычислитьВыражениеСГруппировкойМассив

Разберем ситуацию, когда нам нужно посчитать итог по группировке, основываясь на результатах вычисления других ресурсов. Например, если в детальных записях у нас есть формула, которая может возвращать массив или специфическое значение.

Часто возникает ошибка: при использовании ВычислитьВыражение в ресурсах итоги по группировкам «плывут» или показывают пустые значения. Рассмотрим пример использования ВычислитьВыражениеСГруппировкойМассив для расчета сложных итогов:

В выражении ресурса для нужного поля напишем:

Сумма(ВычислитьВыражениеСГруппировкойМассив("ПредварительныйРасчет", "Номенклатура"))

Почему это важно? Функция ВычислитьВыражениеСГруппировкойМассив собирает значения поля со всех группировок (в данном примере «Номенклатура») в массив, а внешняя функция Сумма корректно их складывает. Это позволяет обходить ограничения, когда агрегатные функции внутри самого вычисляемого поля работают некорректно.

Настройка удобного выбора периода в отчете

Пользователи привыкли выбирать период (месяц, квартал) одним нажатием через стандартное окно «Выберите период». В чистом СКД параметры ДатаНачала и ДатаОкончания обычно выглядят как два отдельных поля ввода даты. Посмотрим на пример, как сделать это правильно.

  1. Вкладка Параметры: добавим новый параметр ПериодОтчета с типом СтандартныйПериод.
  2. Для параметров ДатаНачала и ДатаОкончания в колонке «Выражение» пропишем:
    • Для даты начала: &ПериодОтчета.ДатаНачала
    • Для даты окончания: &ПериодОтчета.ДатаОкончания
  3. Установим для параметров ДатаНачала и ДатаОкончания флаг Ограничение доступности. Теперь пользователь будет видеть только удобный выбор периода, а даты в запрос подставятся автоматически.

Вывод даты и времени формирования отчета

Иногда требуется вывести в заголовке или подвале отчета время, когда он был сформирован, без написания кода в модулях. Это реализуется через системные поля или параметры.

Рассмотрим самый простой способ через параметры:

  1. Создадим параметр ДатаФормирования.
  2. В колонке «Выражение» укажем функцию ТекущаяДата().
  3. На вкладке «Настройки» перейдем в Другие настройки и включим Выводить параметры.

Если же нужно красиво оформить заголовок, мы можем добавить вычисляемое поле с выражением представления:

Строка("Отчет сформирован: ") + Формат(ТекущаяДата(), "ДЛФ=DT")

Решение проблем с фиксированными настройками в новых платформах

Начиная с версии платформы 8.3.13, многие разработчики заметили, что программная установка отборов в КомпоновщикНастроек.ФиксированныеНастройки перестала работать «сама по себе» в некоторых самописных отчетах. Выясним причину.

Дело в том, что платформа стала требовать более явной инициализации настроек при создании формы. Если ваши отборы не применяются, попробуйте в модуле формы отчета выполнить инициализацию компоновщика, используя URL схемы, а не саму схему:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Вместо прямой передачи схемы используем путь к ней, если отчет встроенный
    ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(Отчет.АдресСхемы);
    Отчет.КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
    
    // Теперь фиксированные настройки подхватятся корректно
    ЭлементОтбора = Отчет.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = Параметры.Организация;
    ЭлементОтбора.Использование = Истина;
    
КонецПроцедуры

Использование АдресСхемы или прямого обращения к макету через ИсточникДоступныхНастроек гарантирует, что компоновщик на клиенте и сервере будет синхронизирован, и ваши программные отборы не «слетят» при формировании результата.

Подводя итог, можно сказать, что большинство проблем в СКД решаются либо глубоким пониманием функций ВычислитьВыражение, либо использованием программной инициализации через ВнешниеНаборыДанных. Эти подходы позволяют создавать отчеты любой сложности, сохраняя при этом гибкость настроек для конечного пользователя.

← На главную