В процессе разработки отчетов часто возникает задача: собрать информацию из нескольких полей разных типов (например, серия и номер паспорта, дата, кем выдан) в одно информативное текстовое поле. Рассмотрим, как правильно выполнить такую конкатенацию строк на примере формирования поля "ПаспортныеДанные" в отчете.
Существует несколько подходов к решению этой задачи, но наиболее гибким и предпочтительным является использование вычисляемых полей в Системе Компоновки Данных (СКД). Также разберем альтернативные варианты, такие как программная обработка и ограничения языка запросов.
Этот метод является самым удобным и правильным для отчетов, созданных с помощью СКД. Он не усложняет текст запроса и предоставляет мощные функции для форматирования данных прямо в конструкторе отчета.
Разберем по шагам, как создать составное поле:
ПаспортныеДанные.+.Ключевой момент: нельзя просто сложить поля разных типов (например, число и дату). Каждое поле необходимо предварительно преобразовать в строку с помощью специальных функций языка выражений СКД.
Основные функции для преобразования типов:
<strong>Формат(Значение, ФорматнаяСтрока)</strong> — самая универсальная функция. Используется для преобразования чисел, дат и булевых значений в строку по заданным правилам. Например, Формат(ДатаВыдачи, "ДФ=dd.MM.yyyy") вернет дату в привычном виде "21.10.2023".<strong>Представление(Значение)</strong> — незаменима для полей ссылочного типа (справочники, документы, перечисления). Она возвращает понятное пользователю текстовое представление объекта. Например, для поля ПодразделениеОрганизации вернет его наименование.<strong>Строка(Значение)</strong> — универсальная функция для приведения значения к строковому типу.Посмотрим на пример. Допустим, у нас есть поля: Серия (Число), Номер (Число), КемВыдан (Строка) и ДатаВыдачи (Дата). Выражение для вычисляемого поля ПаспортныеДанные будет выглядеть так:
"Серия " + Формат(Серия, "ЧГ=0") + " № " + Формат(Номер, "ЧГ=0") + ", выдан " + КемВыдан + " " + Формат(ДатаВыдачи, "ДФ=dd.MM.yyyy")
Здесь ЧГ=0 в функции Формат указывает, что число нужно выводить без разделителей групп (тысяч), что актуально для серий и номеров документов.
Еще один полезный пример из обсуждения на форуме — объединение должности и подразделения:
Представление(Должность) + "; " + Представление(ПодразделениеОрганизации)
Обработка пустых значений (NULL)
Если одно из полей в строке окажется незаполненным (NULL), то вся итоговая строка тоже может стать NULL. Чтобы этого избежать и вывести пустую строку вместо отсутствующего значения, используйте функцию ЕстьNULL().
<strong>ЕстьNULL(ПроверяемоеВыражение, ЧемЗаменить)</strong> — если первое выражение равно NULL, функция вернет второе.
Модифицируем наш пример с паспортными данными для корректной обработки пустых полей:
"Серия " + ЕстьNULL(Формат(Серия, "ЧГ=0"), "") + " № " + ЕстьNULL(Формат(Номер, "ЧГ=0"), "") + ", выдан " + ЕстьNULL(КемВыдан, "") + " " + ЕстьNULL(Формат(ДатаВыдачи, "ДФ=dd.MM.yyyy"), "")
Этот способ применяется, когда отчет формируется без СКД или требуется сложная логика, которую трудно реализовать в компоновке. Суть метода в том, чтобы получить "сырые" данные запросом, а затем в цикле обойти результат и сформировать нужные строки программно.
Проанализируем пример кода:
"""" КАК Итог.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументСерия КАК Серия,
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументНомер КАК Ном,
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументДатаВыдачи КАК Дата,
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументКемВыдан КАК Кто
|ИЗ
| РегистрСведений.ПаспортныеДанныеФизЛиц.СрезПоследних(&Дата, ) КАК ПаспортныеДанныеФизЛицСрезПоследних";
Пока Выборка.Следующий() Цикл.+ и функцию Строка() для преобразования нестроковых типов.
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Заполняем параметры области макета из выборки
ОбластьДетальныхЗаписей.Параметры.Заполнить(ВыборкаДетальныеЗаписи);
// Собираем итоговую строку программно
ИтоговаяСтрока = "Серия " + ВыборкаДетальныеЗаписи.Серия +
", номер " + ВыборкаДетальныеЗаписи.Ном +
", дата выдачи " + Формат(ВыборкаДетальныеЗаписи.Дата, "ДФ=dd.MM.yyyy") +
", кем выдан " + ВыборкаДетальныеЗаписи.Кто;
// Передаем сформированную строку в параметр макета
ОбластьДетальныхЗаписей.Параметры.Результат = ИтоговаяСтрока;
ТабДок.Вывести(ОбластьДетальныхЗаписей);
КонецЦикла;
Этот метод дает полный контроль над формированием строки, но он более трудоемкий и менее гибок для пользователя, который не сможет изменить логику отчета без программиста.
Многие начинающие разработчики пытаются объединить строки прямо в тексте запроса. Однако язык запросов 1С имеет строгую типизацию и не позволяет напрямую "складывать" поля разных типов.
Конструкции вида "Строка" + ПолеСДатой или ПолеЧисло + ПолеСтрока приведут к ошибке. Для преобразования типов в запросе существует оператор ВЫРАЗИТЬ.
ВЫБРАТЬ
ВЫРАЗИТЬ(Таблица.Серия КАК СТРОКА(10)) + " " + ВЫРАЗИТЬ(Таблица.Номер КАК СТРОКА(10)) КАК СерияНомер
...
Этот подход работает для полей одного или приводимых к строке типов. Однако преобразовать дату в нужный формат (например, ДД.ММ.ГГГГ) или получить представление ссылочного поля средствами одного лишь запроса крайне затруднительно. Поэтому данный способ не рекомендуется для сборки сложных строк из полей разных типов.
Итог: для задачи объединения нескольких полей в одно текстовое в отчетах на СКД наилучшим решением является использование вычисляемых полей с функциями Формат(), Представление() и ЕстьNULL(). Это гибкий, мощный и правильный подход, который сохраняет читаемость запроса и позволяет легко модифицировать логику отчета.