Как преобразовать разреженную таблицу в плоский вид средствами СКД?

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

При разработке отчетов в системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда результат запроса выглядит как «лесенка» или разреженная таблица. Это происходит, когда данные объединяются из разных источников через оператор ОБЪЕДИНИТЬ (UNION). В итоге мы получаем несколько строк для одного и того же объекта, где в каждой строке заполнена только часть колонок, а остальные содержат NULL или пустые значения. Наша задача — «схлопнуть» эти строки в одну плотную строку, где будут заполнены все показатели.

Рассмотрим подробнее основные способы решения этой задачи, начиная от самых простых настроек компоновки и заканчивая программными методами обработки результата.

Способ 1. Использование агрегатных функций для нечисловых полей

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

Разберем этот механизм по шагам:

  1. Перейдем на закладку Ресурсы в схеме компоновки данных.
  2. Добавим в список ресурсов все поля, которые в вашей исходной таблице «разбросаны» по разным строкам.
  3. Для каждого такого поля в колонке «Выражение» укажем функцию Максимум(ИмяПоля).
  4. На закладке Настройки сгруппируем данные по ключевому полю (например, по номенклатуре, контрагенту или уникальному идентификатору строки).

Почему это работает? СКД при группировке игнорирует значения NULL. Если для одного ключа у вас есть три строки, где в первой заполнено «Поле1», во второй — «Поле2», а в третьей — «Поле3», то функция Максимум выберет единственное непустое значение для каждой колонки и объединит их в одну результирующую строку. Это классический способ превращения разреженного набора данных в плоский.

Способ 2. Использование функции «СоединитьСтроки»

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

Посмотрим на пример выражения в ресурсах:

СоединитьСтроки(Различные НазваниеПоля, ", ")

Этот метод позволяет превратить вертикальный список значений в одну горизонтальную строку, перечисленную через запятую. Это исключает дублирование строк в отчете и делает таблицу компактной и читаемой.

Способ 3. Аналитические функции через «ВычислитьВыражение»

Если нам нужно подтянуть значение из соседней строки (например, перенести данные из строки 2 в строку 1 на этапе компоновки), мы можем использовать функцию ВычислитьВыражение. Данная функция обладает мощным набором параметров, позволяющих имитировать работу аналитических функций SQL (таких как LEAD или LAG).

Выясним причину, по которой этот метод полезен: он позволяет обращаться к группировкам и записям без изменения самого текста запроса. Рассмотрим пример выражения:

ВычислитьВыражение("ИмяПоля", , , "Следующая", "Следующая")

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

Способ 4. Настройка ролей полей в наборе данных

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

Для решения проблемы «размножения» строк попробуем выполнить следующие действия:

Способ 5. Использование кросс-таблиц

Если преобразование таблицы подразумевает перенос значений из строк в заголовки колонок (так называемый Pivot), то лучшим решением будет использование элемента настроек Таблица. В СКД это делается очень просто:

  1. В настройках отчета добавим элемент типа «Таблица».
  2. Поля, которые идентифицируют строку, поместим в Строки.
  3. Поля, значения которых должны стать колонками, поместим в Колонки.
  4. Показатели поместим в Выбранные поля (ресурсы).

СКД автоматически распределит данные по пересечениям, заполнив пропуски и объединив данные в плотную структуру.

Способ 6. Программная обработка в «ПриКомпоновкеРезультата»

Если стандартных механизмов СКД недостаточно для сложной трансформации, мы всегда можем прибегнуть к программной обработке. Рассмотрим алгоритм действий в модуле объекта отчета:

Перехватим процесс компоновки в процедуре ПриКомпоновкеРезультата. Вместо стандартного вывода в табличный документ, мы можем выгрузить результат во временную таблицу значений, программно «свернуть» её или обойти циклом для заполнения нужных полей, а затем передать модифицированную таблицу обратно в процессор вывода.

Пример программного обхода (схематично):


// Выгружаем результат в таблицу значений
ТаблицаРезультата = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультата);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

// Сворачиваем таблицу по ключевым полям, суммируя ресурсы
// или выбирая максимальные строковые значения в цикле
ТаблицаРезультата.Свернуть("КлючевоеПоле", "СуммовоеПоле");

// Далее выводим готовую ТЗ в отчет

Подводя итог, можно сказать, что в большинстве случаев проблема «разреженной таблицы» решается правильной настройкой Ресурсов с использованием функции Максимум. Это наиболее производительный и правильный путь с точки зрения идеологии системы компоновки данных.

← На главную