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

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

Разработка отчетов и обработок в 1С часто требует формирования строковых представлений, состоящих из нескольких заполненных реквизитов. Одной из самых частых задач является склейка полей через разделитель (например, запятую) с условием, что если поле пустое, то запятая не должна добавляться. Разберем, почему попытки сделать это «в лоб» через вложенные конструкции ВЫБОР часто приводят к ошибкам и как решить эту задачу правильно.

Почему не стоит усложнять текст запроса

Многие разработчики при попытке решить данную задачу используют вложенные операторы ВЫБОР КОГДА. Это приводит к созданию громоздких и плохо читаемых конструкций, в которых легко допустить опечатку (например, пропустить ключевое слово КОНЕЦ или неправильно расставить кавычки). Более того, такая логика внутри запроса не учитывает все комбинации заполненности полей, что в итоге оставляет «висячие» запятые в конце строки или двойные запятые при пропуске промежуточных значений.

Рассмотрим основные подходы к решению этой задачи, от оптимизации запроса до переноса логики в модуль.

Вариант 1: Оптимизация запроса с использованием ЕСТЬNULL

Если вам критически важно выполнить объединение именно внутри запроса, можно использовать проверку на пустое значение для каждого поля отдельно. Однако помните, что такой подход требует тщательной проверки каждого случая. Замените двойные кавычки "" (которые часто путают с пустой строкой в консоли) на корректные одиночные кавычки.


ВЫБОР 
    КОГДА ЕСТЬNULL(ФТ_Финал.ЗначениеХарактерт, 0) <> 0 
       ИЛИ ЕСТЬNULL(ФТ_Финал.ЗначениеОткрытыйВоздух, 0) <> 0 
       ИЛИ ЕСТЬNULL(ФТ_Финал.ЗначениеКатегория, 0) <> 0 
    ТОГДА 
        ВЫБОР КОГДА ЕСТЬNULL(ФТ_Финал.ФОТ1Категорию, "") = "" ТОГДА "" ИНАЧЕ ФТ_Финал.ФОТ1Категорию + ", " КОНЕЦ + 
        ВЫБОР КОГДА ЕСТЬNULL(ФТ_Финал.ФОТ1ОткрытыйВоздух, "") = "" ТОГДА "" ИНАЧЕ ФТ_Финал.ФОТ1ОткрытыйВоздух + ", " КОНЕЦ + 
        ЕСТЬNULL(ФТ_Финал.ФОТ1Характер, "") 
КОНЕЦ КАК Свойства

Важное замечание: Этот метод не избавляет от проблемы лишней запятой, если последнее поле (ФОТ1Характер) окажется пустым. Использование такой конструкции рекомендуется только в простых случаях, когда структура данных жестко задана.

Вариант 2: Использование функции СоединитьСтроки (для СКД)

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

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

Вариант 3: Рекомендуемый подход — обработка в модуле (для отчетов)

Поскольку формирование отчетов и вывод данных в макет — это стандартная задача, мы рекомендуем выносить логику склеивания из текста запроса в модуль объекта. Это делает код поддерживаемым, легко отлаживаемым и полностью избавляет от проблем с лишними запятыми.

  1. Выберите нужные поля в запросе отдельно друг от друга (без попыток склеить их внутри ВЫБОР).
  2. В модуле отчета, при обходе выборки результата запроса, сформируйте массив заполненных значений.
  3. Используйте метод СтрСоединить для получения итоговой строки.

Рассмотрим пример кода для обработки выборки:


МассивЗначений = Новый Массив;

Если ЗначениеЗаполнено(Выборка.ФОТ1Категорию) Тогда
    МассивЗначений.Добавить(Выборка.ФОТ1Категорию);
КонецЕсли;

Если ЗначениеЗаполнено(Выборка.ФОТ1ОткрытыйВоздух) Тогда
    МассивЗначений.Добавить(Выборка.ФОТ1ОткрытыйВоздух);
КонецЕсли;

Если ЗначениеЗаполнено(Выборка.ФОТ1Характер) Тогда
    МассивЗначений.Добавить(Выборка.ФОТ1Характер);
КонецЕсли;

РезультатСклеивания = СтрСоединить(МассивЗначений, ", ");

Почему это решение лучшее:

Применяйте этот подход при разработке отчетов, и вы навсегда забудете о проблемах с некорректным отображением строковых данных в макетах 1С!

← На главную