Как объединить уникальные строковые значения в одну строку при группировке данных в 1С и избежать дублирования материалов при соединении с другими таблицами?

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

При работе с данными в 1С часто возникает задача объединить несколько строковых значений из разных записей одной группы в одну строку. Например, вам необходимо для каждой работы получить список всех участвовавших сотрудников, перечисленных через запятую. Если при этом к данным присоединяется информация из других таблиц, например, о материалах, то возникает дополнительная сложность: как избежать дублирования строк материалов из-за множества сотрудников?

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

Ограничения языка запросов 1С и почему СКД – оптимальный выбор

Современные системы управления базами данных (СУБД), такие как MS SQL Server, PostgreSQL или SQLite, давно поддерживают специализированные функции для агрегации строк, например, STRING_AGG или GROUP_CONCAT. Эти функции позволяют легко сгруппировать данные и объединить строковые значения в одной колонке. Однако, в языке запросов 1С такой встроенной функции нет.

Попытки реализовать аналог STRING_AGG на чистом языке запросов 1С обычно приводят к сложным и неэффективным конструкциям. Хотя существуют методы реализовать быстрое объединение строк в одну классическими способами, использование серии вложенных ВЫБОР КОГДА ... МАКСИМУМ() остается громоздким и практически неприменимым для динамического количества элементов.

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

Основное решение: СКД и функции СоединитьСтроки() с Массив(Различные...)

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

  1. Функция Массив(<ИмяПоля>):

    Эта функция собирает все значения указанного поля для текущей группировки в массив. Например, если у нас есть группа с ИДРаботы = 1, и для нее имеются сотрудники «Иванов», «Петров», «Иванов», Массив(Сотрудник) вернет массив значений ["Иванов", "Петров", "Иванов"].

  2. Ключевое слово Различные внутри Массив():

    Это ключевое слово критически важно для нашей задачи. Оно гарантирует, что в массив попадут только уникальные значения. Если у одного ИДРаботы сотрудник «Иванов» встречается несколько раз, Массив(Различные Сотрудник) вернет ["Иванов", "Петров"], исключив дубликаты.

  3. Функция СоединитьСтроки(<Массив>, <Разделитель>):

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

Таким образом, для создания списка уникальных сотрудников для каждой работы, в СКД нам нужно создать вычисляемое поле со следующим выражением:

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

Разберем по шагам, как это реализовать в СКД:

  1. Откройте схему компоновки данных.
  2. Перейдите на вкладку "Наборы данных".
  3. Создайте новый набор данных или выберите существующий.
  4. Перейдите на вкладку "Вычисляемые поля".
  5. Добавьте новое вычисляемое поле, например, с именем СписокСотрудников.
  6. В поле "Выражение" введите: СоединитьСтроки(Массив(Различные Сотрудник), ", ").
  7. На вкладке "Настройки" добавьте группировку по полю ИДРаботы и выведите СписокСотрудников.

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

Решение проблемы дублирования данных при левом соединении с таблицей материалов

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

Чтобы избежать этого, необходимо применять принцип "агрегация до соединения". В сложных отчетах для этого иногда приходится использовать две разных схемы в отчете СКД или раздельные наборы данных.

Разберем двухэтапный подход в СКД:

Шаг 1: Агрегация сотрудников в отдельном наборе данных

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

  1. Создаем первый набор данных (тип "Запрос"):
    
    ВЫБРАТЬ
        ИсполнителиРабот.ИДРаботы КАК ИДРаботы,
        ИсполнителиРабот.Сотрудник КАК Сотрудник
    ИЗ
        РегистрСведений.ИсполнителиРабот КАК ИсполнителиРабот
    
  2. Добавляем вычисляемое поле:

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

Шаг 2: Соединение агрегированных данных с таблицей материалов

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

  1. Создаем второй набор данных (тип "Запрос") для выбора информации о материалах (ИДРаботы, Материал, Количество).
  2. Устанавливаем связь между наборами данных:

    На вкладке "Связи наборов данных" создаем Левое соединение от набора с сотрудниками к набору с материалами по полю ИДРаботы.

  3. Построение структуры отчета:

    В настройках группируем данные по полям ИДРаботы, Материал и Количество, добавляя в выбранные поля вычисляемое поле СписокСотрудников.

Важные нюансы и рекомендации

  1. Преобразование типов данных:

    Если поле Сотрудник является ссылкой, СКД обработает его корректно. Но для объединения разнородных типов данных лучше использовать Представление(<ИмяПоля>).

  2. Производительность:

    Метод с использованием СоединитьСтроки(Массив(Различные...)) обычно хорошо оптимизирован. Однако при работе с гигантскими объемами данных всегда стоит проверять индексы и структуру запросов.

  3. Гибкость СКД:

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

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

← На главную