При работе с Системой Компоновки Данных (СКД) в 1С часто возникает задача, когда нам необходимо не просто сгруппировать данные по какому-либо полю, но и собрать строковые значения из нескольких записей в одну объединенную строку. Например, мы хотим увидеть список всех товаров в одном документе или перечень всех услуг по одному договору, представленный в одной ячейке отчета.
Давайте вместе разберем, как мы можем эффективно решить эту задачу, используя различные подходы в СКД, включая современные функции платформы и методы, основанные на временных таблицах.
Самый прямой и рекомендуемый способ для объединения строковых значений в современных версиях платформы 1С:Предприятие – это использование функции ОБЪЕДИНИТЬСТРОКИ, которая также известна как STRING_AGG в англоязычной версии. Эта функция позволяет собрать строковые значения из нескольких записей в одну строку, разделяя их указанным разделителем.
Мы выясним, что эта функция доступна, начиная с платформы 1С:Предприятие 8.3.10. Если вы используете более раннюю версию, вам потребуется рассмотреть альтернативные методы.
Добавление вычисляемого поля в набор данных:
Для начала нам потребуется добавить новое вычисляемое поле в ваш набор данных СКД. Перейдите на вкладку «Наборы данных» в схеме компоновки данных, выберите нужный набор и добавьте новое поле на вкладке «Вычисляемые поля» или «Ресурсы» (если это итоговое поле).
Указание выражения для вычисляемого поля:
В выражении для нового поля мы будем использовать функцию ОБЪЕДИНИТЬСТРОКИ. Рассмотрим пример, где мы хотим объединить наименования товаров из табличной части документа по каждому документу. Допустим, у нас есть поле НаименованиеТовара, и мы хотим объединить его значения, разделяя запятой и пробелом.
ОБЪЕДИНИТЬСТРОКИ(НаименованиеТовара, ", ")
Здесь:
НаименованиеТовара – это поле, значения которого мы хотим собрать.", " – это строка-разделитель, которая будет вставляться между объединенными значениями. Вы можете использовать любой другой разделитель, например, "; ", РАЗДЕЛИТЕЛЬСТРОК или даже перенос строки Символы.ПС, если это необходимо.Важно: Если вы используете эту функцию в ресурсах, убедитесь, что в качестве поля для объединения вы указали поле из детальных записей, а не из группировки.
Настройка группировок в отчете:
Чтобы функция ОБЪЕДИНИТЬСТРОКИ работала корректно, нам нужно настроить соответствующие группировки в отчете СКД. Функция будет объединять строки в рамках той группировки, к которой она применяется. Например, если вы хотите объединить товары по документу, убедитесь, что у вас есть группировка по полю Документ, и ваше вычисляемое поле с функцией ОБЪЕДИНИТЬСТРОКИ находится на уровне этой группировки или выше.
Если мы добавили вычисляемое поле в набор данных, то в настройках отчета (на вкладке "Настройки") мы можем добавить это поле в выбранные поля и поместить его в нужную группировку (например, в детальные записи или в ресурс группировки).
Если функция ОБЪЕДИНИТЬСТРОКИ недоступна (например, вы работаете на старой версии платформы 1С) или ваша задача требует более сложной предварительной обработки данных, мы можем использовать подход с временными таблицами (ВТ) и группировками в запросе. Этот метод чаще применяется для агрегации числовых данных, но принципы его работы могут быть адаптированы и для подготовки данных к строковой конкатенации, если ее выполнять программно, или для распределения сумм по детальным записям.
Рассмотрим, как мы можем использовать временные таблицы для предварительной обработки данных. Этот подход демонстрируется в нескольких примерах запросов, которые мы можем проанализировать.
Создание временной таблицы с исходными данными:
Сначала мы формируем временную таблицу, содержащую все необходимые детальные данные. Это позволяет нам работать с очищенными или предварительно отфильтрованными данными.
ВЫБРАТЬ
АвансовыйОтчетПрочиеРасходы.Ссылка КАК Документ,
АвансовыйОтчетПрочиеРасходы.НомерСтроки КАК НомерСтроки,
АвансовыйОтчетПрочиеРасходы.Содержание КАК Содержание,
АвансовыйОтчетПрочиеРасходы.Ссылка.СуммаОтклонено КАК СуммаОтклонено
ПОМЕСТИТЬ втДанные
ИЗ
Документ.АвансовыйОтчет.ПрочиеРасходы КАК АвансовыйОтчетПрочиеРасходы
В этом примере мы получаем детальные записи из табличной части документа АвансовыйОтчет.ПрочиеРасходы.
Создание временной таблицы для агрегации (например, подсчета количества):
Далее мы можем создать вторую временную таблицу, в которой выполним агрегацию по нужным нам полям. В нашем случае, если бы мы хотели подготовить данные для дальнейшего объединения строк, мы могли бы подсчитать количество уникальных строк или других агрегированных значений, которые затем используем для распределения или принятия решений.
ВЫБРАТЬ
втДанные.Документ КАК Документ,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ втДанные.НомерСтроки) КАК КоличествоСодержаний
ПОМЕСТИТЬ втКоличествоСодеражний
ИЗ
втДанные КАК втДанные
СГРУППИРОВАТЬ ПО
втДанные.Документ
Здесь мы сгруппировали данные по Документ и подсчитали КОЛИЧЕСТВО(РАЗЛИЧНЫЕ втДанные.НомерСтроки). Это числовое агрегирование, но сам принцип создания агрегированной ВТ по группирующему полю очень важен.
Объединение временных таблиц и получение конечного результата:
На последнем шаге мы объединяем наши временные таблицы, чтобы получить конечный результат. Это позволяет нам связать агрегированные данные (например, количество строк по документу) с детальными записями и выполнить дополнительные расчеты или вывести информацию.
ВЫБРАТЬ
втДанные.Документ КАК Документ,
втДанные.НомерСтроки КАК НомерСтроки,
втДанные.Содержание КАК Содержание,
втДанные.СуммаОтклонено / втКоличествоСодеражний.КоличествоСодержаний КАК СуммаОтклоненоНормированая
ИЗ
втДанные КАК втДанные
ВНУТРЕННЕЕ СОЕДИНЕНИЕ втКоличествоСодеражний КАК втКоличествоСодеражний
ПО втДанные.Документ = втКоличествоСодеражний.Документ
ИТОГИ
СУММА(СуммаОтклоненоНормированая)
ПО
ОБЩИЕ,
Документ
В этом примере мы видим, как исходная сумма СуммаОтклонено делится на агрегированное КоличествоСодержаний. Это демонстрирует, как мы можем использовать агрегированные данные из одной ВТ для выполнения расчетов с детальными данными из другой ВТ.
Примечание: Если бы нам нужно было объединить строковые значения в старых версиях 1С, мы бы использовали этот подход для получения всех необходимых детальных строк, а затем программно обходили бы результат запроса на стороне 1С, формируя нужную строку с конкатенацией.
Группировки в СКД: Мы всегда должны помнить, что корректная настройка группировок в СКД является ключом к правильной работе любой агрегирующей функции, включая ОБЪЕДИНИТЬСТРОКИ. Убедитесь, что поле, по которому вы хотите объединять строки, является частью группировки или находится на уровне, позволяющем агрегировать данные.
Производительность: Функция ОБЪЕДИНИТЬСТРОКИ, реализованная на уровне СУБД, как правило, является наиболее производительным способом для объединения строк. Использование временных таблиц в запросах также оптимизировано, но программная обработка большого объема данных для конкатенации может быть менее эффективной.
Использование наборов данных: Мы можем использовать несколько наборов данных в СКД и связывать их между собой. Это может быть полезно, если часть данных для объединения строк берется из одного источника, а группировочные поля – из другого. Однако, для простой конкатенации в рамках одного набора данных, обычно достаточно вычисляемого поля.
Мы рассмотрели основные подходы к объединению строковых значений по полю в отчетах 1С на СКД. Выбор конкретного метода будет зависеть от версии вашей платформы, сложности задачи и требуемой производительности. В большинстве современных сценариев функция ОБЪЕДИНИТЬСТРОКИ будет нашим лучшим выбором.