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

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

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

Анализ проблемы и выбор инструмента

Проблема заключается в том, что обычное суммирование (агрегация) для строковых полей или дат не дает нужного результата — даты нельзя просто сложить. Нам необходимо выполнить конкатенацию строк (объединение) на уровне группировки. В 1С 8.3 для этих целей предусмотрена мощная связка функций: ВычислитьВыражениеСГруппировкойМассив и СоединитьСтроки. Эти функции позволяют собрать значения из детальных записей в массив в контексте определенной группировки и затем «склеить» их в одну строку с заданным разделителем.

Шаг 1. Подготовка запроса в схеме компоновки данных

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


ВЫБРАТЬ
    Соответствие.Сотрудник.ФизическоеЛицо.Наименование КАК СотрудникФИО,
    Соответствие.ДатаНачала КАК ДатаНачала,
    Соответствие.ДатаОкончания КАК ДатаОкончания
ИЗ
    РегистрСведений.Соответствия КАК Соответствие

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

Шаг 2. Настройка вычисляемых полей (необязательно, но полезно)

Чтобы формула в ресурсах не выглядела слишком громоздкой, мы можем создать вычисляемое поле, которое будет формировать строковое представление одного периода. Назовем его СтрокаПериода. Выясним, какую формулу лучше использовать. Поскольку период состоит из двух дат, нам нужно привести их к строке и соединить дефисом.

В поле «Выражение» вычисляемого поля можно написать:

Представление(ДатаНачала) + " - " + Представление(ДатаОкончания)

Или, если требуется строгий формат даты:


Формат(ДатаНачала, "ДФ=dd.MM.yyyy") + " — " + Формат(ДатаОкончания, "ДФ=dd.MM.yyyy")

Шаг 3. Настройка ресурсов — ключевой этап решения

Переходим на закладку «Ресурсы». Именно здесь происходит магия объединения строк. Нам нужно создать ресурс для нашего поля (или для нового поля, которое будет отвечать за вывод объединенных периодов). Разберем по шагам составление формулы.

Используем функцию СоединитьСтроки, которая принимает массив значений и разделитель. Массив мы получим с помощью функции ВычислитьВыражениеСГруппировкойМассив.

Формула ресурса:


СоединитьСтроки(ВычислитьВыражениеСГруппировкойМассив("Формат(ДатаНачала, ""ДФ=dd.MM.yyyy"") + "" - "" + Формат(ДатаОкончания, ""ДФ=dd.MM.yyyy"")", "СотрудникФИО"), ", ")

Проанализируем параметры функции ВычислитьВыражениеСГруппировкойМассив:

  1. Первый параметр: Выражение, которое нужно вычислить. В нашем случае это конкатенация отформатированных дат. Обратите внимание на двойные кавычки внутри строки — это необходимо для корректного синтаксиса СКД.
  2. Второй параметр: Поле группировки, в разрезе которого собирается массив. В нашем случае это СотрудникФИО. Это означает, что для каждого уникального сотрудника будет собран свой список периодов.

В колонке «Рассчитывать по...» в таблице ресурсов обязательно укажите группировку СотрудникФИО и Общий итог.

Шаг 4. Настройка структуры отчета

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

Правильная структура:

  1. Добавьте группировку по полю СотрудникФИО.
  2. В «Выбранные поля» этой группировки добавьте само поле СотрудникФИО и наш ресурсный период.
  3. Не добавляйте «Детальные записи» внутрь этой группировки, если вы хотите видеть только одну итоговую строку по сотруднику.

Почему поле может быть пустым? Анализ типичных ошибок

Рассмотрим ситуацию, когда вы все настроили, но поле в отчете остается пустым или данные не объединяются. Выясним возможные причины:

Сложные случаи: удаление дублей и сортировка

Иногда один и тот же период может встретиться в данных дважды. Чтобы не выводить дублирующиеся периоды через запятую, можно использовать ключевое слово Distinct (Различные) внутри выражения массива, если это позволяет версия платформы. Однако более надежным способом является использование собственного метода в Общем модуле.

Рассмотрим, как это реализовать через программный код. Создадим функцию в общем модуле с флагом «Сервер, Внешнее соединение»:


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

В СКД в поле ресурса формула примет вид:


ИмяОбщегоМодуля.СоединитьПериоды(ВычислитьВыражениеСГруппировкойМассив("Формат(ДатаНачала, ""ДФ=dd.MM.yyyy"")", "СотрудникФИО"))

Такой подход позволяет реализовать любую сложную логику: сортировку периодов по дате, удаление пересекающихся интервалов или выделение периодов особым цветом с помощью HTML-форматирования (если отчет выводится в табличный документ с поддержкой HTML).

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

← На главную