Многие разработчики, переходящие с классического MS SQL на 1С:Предприятие, сталкиваются с необходимостью объединения нескольких записей в одну строку (например, вывод списка всех штрихкодов для одной номенклатуры через запятую). В SQL для этих целей часто используют конструкцию FOR XML PATH или функцию STRING_AGG. Однако в языке запросов 1С подобные механизмы на уровне СУБД отсутствуют.
Давайте разберем, почему так происходит и какие инструменты мы можем использовать для решения этой задачи в современных реалиях платформы.
Платформа 1С:Предприятие — это кроссплатформенная среда. Она должна одинаково работать как на MS SQL Server, так и на PostgreSQL, IBM DB2 или Oracle. Поскольку способ агрегации строк в этих СУБД принципиально отличается, разработчики платформы абстрагировали язык запросов от специфических функций конкретных баз данных. Введение «сквозной» функции для конкатенации потребовало бы глубокой переработки движка для каждой поддерживаемой СУБД.
Важно помнить: начиная с версии 8.3.20, в языке запросов расширились возможности приведения типов и работы с подстроками, но это не превращает запрос в полноценный инструмент для групповой агрегации строк.
Это самый производительный и прозрачный способ. Мы получаем детальный список данных запросом, сортируем его по группирующему полю (например, Номенклатура) и собираем строки в цикле.
Рассмотрим пошаговый алгоритм реализации:
Номенклатура и Штрихкод, обязательно добавляя УПОРЯДОЧИТЬ ПО Номенклатура.Пример программного кода для обхода выборки:
// Предположим, РезультатЗапроса уже получен
Выборка = РезультатЗапроса.Выбрать();
ТекущаяНоменклатура = Неопределено;
СписокШтрихкодов = "";
Пока Выборка.Следующий() Цикл
Если ТекущаяНоменклатура <> Выборка.Номенклатура Тогда
// Здесь мы можем обработать сформированный ранее список
// (например, записать в структуру или ТЧ)
ТекущаяНоменклатура = Выборка.Номенклатура;
СписокШтрихкодов = Выборка.Штрихкод;
Иначе
СписокШтрихкодов = СписокШтрихкодов + ", " + Выборка.Штрихкод;
КонецЕсли;
КонецЦикла;
Если задача стоит в рамках формирования отчета, использование СКД является предпочтительным. Мы можем создать вычисляемое поле, в котором будет вызываться функция общего модуля для конкатенации.
Хотя вызов функций в запросах (или из них) при больших объемах данных может привести к проблеме N+1 (когда сервер выполняет отдельный запрос на каждую строку), в СКД это часто является допустимым компромиссом для получения нужного визуального результата.
Для реализации в СКД:
ОбщиеФункции.ПолучитьСписокШтрихкодов(Номенклатура).Анализируя ситуацию, важно подчеркнуть несколько моментов:
СтрСоединить для работы с массивами данных — это современный и быстрый метод сборки строк в коде 1С.XML-сериализацию, что крайне сложно поддерживать.Подводя итог, можно сказать, что отсутствие FOR XML PATH в языке запросов 1С — это особенность архитектуры. Мы рекомендуем всегда выбирать метод постобработки в коде как наиболее надежный, легко отлаживаемый и поддерживаемый в будущем. Надеемся, что этот разбор поможет вам найти оптимальное решение для вашей задачи!