Как в СКД объединить несколько строк характеристик в одну строку через запятую?

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

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

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

Использование ресурсов для агрегации строк

Первое и самое важное правило: поле, которое мы хотим превратить в список через запятую, не должно находиться в группировках отчета. Если мы оставим Характеристика в списке полей группировки, СКД по определению создаст отдельную строку для каждого уникального значения. Чтобы «склеить» данные, мы должны перевести поле в разряд ресурсов.

Разберем по шагам настройку в схеме компоновки данных:

  1. Перейдем на закладку Ресурсы.
  2. Выберем наше поле (например, Характеристика) и перенесем его в список ресурсов.
  3. В колонке «Выражение» напишем формулу агрегации.

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

СоединитьСтроки(Характеристика, ", ")

Однако, как справедливо заметил автор темы, простое использование этой функции часто приводит к «задвоению» или даже «задесятерению» данных. Это происходит из-за того, что функция СоединитьСтроки берет все значения из детальных записей, которые попали в данную группировку. Если в результате запроса одна и та же характеристика встретилась несколько раз (например, из-за соединений с другими таблицами), она столько же раз появится и в итоговой строке.

Решение проблемы дублей через массив

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

СоединитьСтроки(Массив(Различные Характеристика), ", ")

Выясним, как это работает изнутри: - Функция Массив(Различные ...) собирает все уникальные значения поля в рамках текущей группировки и помещает их в коллекцию. - Функция СоединитьСтроки принимает этот массив в качестве первого аргумента, обходит его и склеивает элементы, используя разделитель, указанный во втором аргументе.

Управление порядком вывода характеристик

Часто заказчики требуют, чтобы характеристики шли не в случайном порядке, а, например, по алфавиту. Напрямую внутри функции Массив() в СКД нельзя указать Упорядочить По.... Однако мы можем повлиять на это на уровне набора данных. Проанализируем ситуацию: СКД обычно сохраняет порядок следования данных из результата запроса при формировании массивов ресурсов. Если в основном запросе добавить УПОРЯДОЧИТЬ ПО Характеристика.Наименование, то и в итоговой строке через запятую они, скорее всего, выстроятся в нужном порядке.

Использование функций общих модулей для сложной логики

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

Для этого должны выполняться условия: - Общий модуль должен иметь флаги Сервер, Внешнее соединение и Вызов сервера. - Функция должна быть объявлена с ключевым словом Экспорт.

Посмотрим на пример такой функции в общем модуле МойОбщийМодуль:


Функция СклеитьХарактеристики(МассивДанных) Экспорт
    Результат = "";
    Для Каждого Элемент Из МассивДанных Цикл
        Если ЗначениеЗаполнено(Элемент) Тогда
            Результат = Результат + ?(Результат = "", "", "; ") + СокрЛП(Элемент);
        КонецЕсли;
    КонецЦикла;
    Возврат Результат;
КонецФункции

В выражении ресурса СКД мы вызовем её следующим образом:

МойОбщийМодуль.СклеитьХарактеристики(Массив(Различные Характеристика))

Это дает неограниченную гибкость в форматировании результирующей строки.

Обработка пустых значений и Null

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

Рассмотрим пример с использованием оператора ЕстьNull или Выбор:

Выбор Когда СоединитьСтроки(Массив(Различные Характеристика), ", ") = "" Тогда "Характеристики не заданы" Иначе СоединитьСтроки(Массив(Различные Характеристика), ", ") Конец

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

Важные нюансы настройки полей группировки

Еще раз вернемся к архитектуре отчета. Чтобы группировка работала корректно, убедитесь, что в настройках на закладке Настройки - Выбранные поля у вас выбрано только поле группировки (Номенклатура) и поле-ресурс (Характеристика). Если вы по ошибке добавите Характеристика как детальное поле, СКД применит настройки детальных записей, и вы снова увидите множество строк. Ресурс «рассчитывается» только тогда, когда записи сворачиваются по определенному ключу группировки.

Таким образом, мы разобрали, что превращение списка в строку в СКД — это не просто вызов одной функции, а правильная комбинация работы с ресурсами, массивами и уникальностью данных. Использование конструкции СоединитьСтроки(Массив(Различные Поле), ", ") является «золотым стандартом» для решения этой задачи в 1С 8.3.

← На главную