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