При разработке отчетов в системе компоновки данных (СКД) программисты часто сталкиваются с задачей отображения иерархических или связанных данных. Классический пример: у одного покупателя может быть несколько поставщиков, и нам необходимо вывести их в одной строке или в виде красиво сгруппированного блока. Стандартный вывод СКД в таких случаях часто дублирует данные основной группировки, что делает отчет трудночитаемым.
В этой статье мы подробно разберем несколько способов реализации такого функционала — от простых настроек ресурсов до программной обработки готового табличного документа. Мы проанализируем ситуацию, когда нужно вывести от 1 до Х связанных записей, и выберем оптимальный метод для каждого случая.
Если ваша задача не требует вывода каждого связанного контрагента в отдельной физической ячейке, а достаточно перечислить их через запятую или с новой строки, то функция СоединитьСтроки — это самый элегантный и быстрый способ. Рассмотрим, как это настроить.
Перейдем на вкладку Вычисляемые поля в схеме компоновки данных. Добавим новое поле, например, СписокПоставщиков. В выражении ресурсов для этого поля мы укажем специальную функцию. Проанализируем её синтаксис:
СоединитьСтроки(Поставщик, ", ", "Поставщик")
Разберем по шагам, что мы сделали:
Символы.ПС.Теперь в настройках отчета достаточно выбрать поле СписокПоставщиков. В результате для каждого покупателя будет выведена одна строка, где в одной ячейке будут перечислены все его поставщики. Это значительно экономит место на листе и упрощает восприятие данных.
Рассмотрим ситуацию, когда поставщиков нужно развернуть «в ширину», то есть каждый поставщик должен занять отдельную колонку. Для этого мы воспользуемся механизмом таблиц в СКД.
В настройках структуры отчета выполним следующие действия:
Покупатель.Поставщик.Истина или 1 и настроить условное оформление для вывода текста.Этот метод отлично подходит для сравнительного анализа, но стоит помнить: если поставщиков у одного покупателя слишком много, отчет станет избыточно широким и неудобным для печати.
Иногда заказчик просит вывести данные строго в колонки «Поставщик 1», «Поставщик 2» и так далее. Выясним причину такой необходимости: обычно это нужно для жестко заданных бланков. Чтобы реализовать это в СКД, нам придется подготовить данные еще на уровне запроса.
Нам нужно пронумеровать поставщиков для каждого покупателя. В современных версиях платформы 1С (начиная с 8.3.20+) можно использовать оконные функции. Посмотрим на пример кода запроса:
ВЫБРАТЬ
Продажи.Покупатель КАК Покупатель,
Продажи.Поставщик КАК Поставщик,
ПОРЯДКОВЫЙ_НОМЕР() ОБЪЕДИНИТЬ ПО (УПОРЯДОЧИТЬ ПО Продажи.Поставщик) КАК НомерПоставщика
ИЗ
РегистрНакопления.Продажи КАК Продажи
Если же ваша версия платформы не поддерживает оконные функции, нумерацию можно реализовать через соединение таблицы самой с собой по условию Т1.Поставщик >= Т2.Поставщик с последующей группировкой и подсчетом количества записей.
После того как у нас появилось поле НомерПоставщика, мы используем его в СКД как группировку колонок, как в предыдущем методе. Это позволит зафиксировать количество столбцов или просто упорядочить их по порядку.
Многие пользователи хотят видеть отчет, в котором ячейка с покупателем визуально объединена, а справа от нее перечислены поставщики. В СКД это называется «псевдообъединением». Разберем, как добиться такого эффекта через Макеты.
На вкладке Макеты мы можем создать Макет группировки для поля Покупатель.
Это создаст визуальный эффект одной большой ячейки. Однако стоит учитывать, что это лишь визуализация, и при копировании данных в Excel ячейки останутся разъединенными.
Если требуется «настоящее» объединение ячеек (как метод Объединить() в Excel), мы должны вмешаться в процесс формирования отчета программно. Это самый мощный метод, позволяющий реализовать любую логику. Проанализируем ситуацию: отчет выводится в ТабличныйДокумент, и после этого мы запускаем цикл обработки.
Пример кода в модуле формы отчета:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Инициализируем схему и настройки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Алгоритм объединения ячеек
ПредыдущееЗначение = "";
НачалоОбъединения = 0;
Для НомерСтроки = 1 По ДокументРезультат.ВысотаТаблицы Цикл
ТекущееЗначение = ДокументРезультат.Область(НомерСтроки, 1, НомерСтроки, 1).Текст;
Если ТекущееЗначение = ПредыдущееЗначение Тогда
Если НачалоОбъединения = 0 Тогда
НачалоОбъединения = НомерСтроки - 1;
КонецЕсли;
Иначе
Если НачалоОбъединения > 0 Тогда
ОбластьДляОбъединения = ДокументРезультат.Область(НачалоОбъединения, 1, НомерСтроки - 1, 1);
ОбластьДляОбъединения.Объединить();
НачалоОбъединения = 0;
КонецЕсли;
ПредыдущееЗначение = ТекущееЗначение;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В этом примере мы перехватываем стандартный вывод, заполняем ТабличныйДокумент, а затем проходим по первой колонке. Если значение в текущей строке совпадает с предыдущим, мы запоминаем начало диапазона и в конце вызываем метод Объединить(). Это позволяет получить профессионально выглядящий отчет.
Если программирование кажется вам избыточным, можно воспользоваться стандартным свойством группировки. В настройках группировки на вкладке Дополнительные настройки найдите параметр Расположение группировок. Если установить его в значение Отдельно и в начале группы, 1С сама будет выводить заголовок только один раз.
Также можно использовать Условное оформление. Мы можем задать условие, при котором цвет текста поля Покупатель будет совпадать с цветом фона, если значение совпадает с «предыдущим». Хотя в СКД нет прямого обращения к «предыдущему» значению в условии, этого эффекта можно добиться, настроив группировку таким образом, чтобы детальные записи не выводили значение группировочного поля (флаг Выводить дублирующиеся значения в настройках группировки).
Мы рассмотрели различные подходы к выводу связанных контрагентов в СКД. Выбор метода зависит от ваших целей:
СоединитьСтроки.Экспериментируйте с этими методами, чтобы найти наиболее удобный для ваших пользователей вариант. Совместное использование настроек СКД и небольших программных вставок позволяет создавать действительно мощные и красивые отчеты в 1С.