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

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

При разработке отчетов в Системе компоновки данных (СКД) разработчики часто сталкиваются с необходимостью красивого оформления выводимых данных. Классический пример — формирование динамических заголовков колонок или представлений периодов. Например, когда на основе числового параметра &Год (например, 2024) нужно получить строковое представление сезона: "Зима 2023/2024" или "Лето 2024".

Исторически в языке запросов «1С:Предприятия» отсутствовала прямая возможность преобразования числа в строку. Попытки использовать конструкцию ВЫРАЗИТЬ(Число КАК СТРОКА) вызывают ошибку компиляции запроса, а функция ПРЕДСТАВЛЕНИЕ() предназначена исключительно для получения текстового описания ссылочных типов на стороне клиента и не позволяет производить операции конкатенации (сложения) строк на уровне базы данных.

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

Способ 1. Использование вычисляемых полей СКД (Классический метод)

Если отчет должен быть совместим со старыми версиями платформы «1С:Предприятие» (ниже версии 8.3.20), то самым надежным и гибким решением будет использование вкладки «Вычисляемые поля» в схеме компоновки данных.

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

Рассмотрим по шагам, как реализовать такую логику:

  1. Откроем схему компоновки данных нашего отчета и перейдем на вкладку «Вычисляемые поля».
  2. Добавим новую строку, нажав на кнопку с плюсом.
  3. Зададим имя поля (например, ПредставлениеПериода) и путь к данным (под этим именем поле будет доступно для вывода в отчет).
  4. В колонке «Выражение» напишем алгоритм формирования строки.

Проанализируем пример кода, предложенный автором темы на форуме:


Выбор когда Интервал = "ОСЕНЬ" 
Тогда "ОСЕНЬ " + Строка(Формат(&Год,"ЧГ=0"))
когда Интервал = "ЛЕТО" 
Тогда "ЛЕТО " + Строка(Формат(&Год,"ЧГ=0"))
когда Интервал = "ВЕСНА" 
Тогда "ВЕСНА " + Строка(Формат(&Год,"ЧГ=0"))
когда Интервал = "ЗИМА_ДО" 
Тогда "ЗИМА " + Строка(Формат(&Год-1,"ЧГ=0")) + "/" + Строка(Формат(&Год,"ЧГ=0"))
когда Интервал = "ЗИМА_ПОСЛЕ" 
Тогда "ЗИМА " + Строка(Формат(&Год,"ЧГ=0")) + "/" + Строка(Формат(&Год+1,"ЧГ=0"))
Конец

Этот код отлично решает задачу, но его можно оптимизировать. Обратите внимание на конструкцию Строка(Формат(&Год, "ЧГ=0")). Функция Формат() во встроенном языке 1С изначально возвращает значение типа Строка. Дополнительное обертывание в функцию Строка() здесь является избыточным и лишь тратит ресурсы процессора. Также важно использовать форматную строку ЧГ=0 (Численные Группы = 0), чтобы платформа не разделяла тысячи пробелами (чтобы не получилось "2 018" вместо "2018").

Оптимизированный вариант выражения будет выглядеть следующим образом:


Выбор когда Интервал = "ОСЕНЬ" 
Тогда "ОСЕНЬ " + Формат(&Год,"ЧГ=0")
когда Интервал = "ЛЕТО" 
Тогда "ЛЕТО " + Формат(&Год,"ЧГ=0")
когда Интервал = "ВЕСНА" 
Тогда "ВЕСНА " + Формат(&Год,"ЧГ=0")
когда Интервал = "ЗИМА_ДО" 
Тогда "ЗИМА " + Формат(&Год-1,"ЧГ=0") + "/" + Формат(&Год,"ЧГ=0")
когда Интервал = "ЗИМА_ПОСЛЕ" 
Тогда "ЗИМА " + Формат(&Год,"ЧГ=0") + "/" + Формат(&Год+1,"ЧГ=0")
Конец

Способ 2. Современный подход в платформе (Начиная с версии 8.3.20)

Если вы работаете на современной платформе «1С:Предприятие» версии 8.3.20 и выше, необходимость в переносе логики в вычисляемые поля СКД отпадает. Разработчики платформы совершили долгожданную революцию, добавив полноценную поддержку строковых функций непосредственно в язык запросов.

Теперь прямо в тексте запроса (в блоке ВЫБРАТЬ) мы можем использовать следующие функции:

Посмотрим, как будет выглядеть фрагмент запроса с формированием нашего представления:


ВЫБРАТЬ
    ВЫБОР
        КОГДА ТаблицаПериодов.Интервал = "ЗИМА_ДО"
            ТОГДА "Зима " + СТРОКА(ТаблицаПериодов.Год - 1) + "/" + СТРОКА(ТаблицаПериодов.Год)
        ИНАЧЕ "Лето " + СТРОКА(ТаблицаПериодов.Год)
    КОНЕЦ КАК ПредставлениеСезона
ИЗ
    ТаблицаПериодов КАК ТаблицаПериодов

Этот способ является наиболее производительным, так как преобразование типов и конкатенация выполняются непосредственно на стороне СУБД (SQL-сервера) при выборке данных, а СКД получает уже готовые строковые поля для вывода.

Способ 3. Использование функций общих модулей

Что делать, если алгоритм формирования представления периода слишком сложный, содержит много условий или требует обращения к сторонней бизнес-логике базы данных? Писать огромные конструкции ВЫБОР КОГДА в вычисляемых полях СКД становится неудобно и трудночитаемо.

В этом случае отличным архитектурным решением станет делегирование расчетов экспортной функции общего модуля 1С.

Выполним это по шагам:

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

Шаг 2. Написание функции преобразования
Добавим в модуль экспортную функцию:


Функция ПолучитьПредставлениеСезона(Интервал, Год) Экспорт
    
    Если Интервал = "ЗИМА_ДО" Тогда
        Возврат СтрШаблон("Зима %1/%2", Формат(Год - 1, "ЧГ=0"), Формат(Год, "ЧГ=0"));
    ИначеЕсли Интервал = "ЗИМА_ПОСЛЕ" Тогда
        Возврат СтрШаблон("Зима %1/%2", Формат(Год, "ЧГ=0"), Формат(Год + 1, "ЧГ=0"));
    Иначе
        Возврат СтрШаблон("%1 %2", Интервал, Формат(Год, "ЧГ=0"));
    КонецЕсли;
    
КонецФункции

Шаг 3. Вызов функции в СКД
Возвращаемся в схему компоновки данных на вкладку «Вычисляемые поля». В поле «Выражение» для нашего поля прописываем обращение к созданной функции общего модуля:

РаботаСОтчетамиВызовСервера.ПолучитьПредставлениеСезона(Интервал, &Год)

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


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    
    // Разрешаем использование функций общих модулей в СКД
    ИнициализаторМакета = Новый ИнициализаторМакетаКомпоновкиДанных;
    ИнициализаторМакета.ИспользоватьВнешниеФункции = Истина;
    
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКомпоновкиДанных, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Способ 4. Оптимизация параметров отчета (Архитектурный маневр)

Иногда лучшим решением проблемы является ее предотвращение. Как справедливо заметили участники форума в сообщениях №5 и №8, если параметр года нужен только для вывода красивого заголовка, почему бы изначально не передавать его в отчет в виде готового текстового значения? Например, передавать параметр &ГодСтрока со значением "2018".

Однако автор резонно возразил (сообщение №7), что исходный числовой параметр года активно используется в запросе для расчета дат, получения остатков регистров накопления и выполнения математических операций внутри виртуальных таблиц.

В такой ситуации рекомендуется использовать связанные параметры:

  1. Создаем для пользователя один доступный параметр (например, числовой &Год).
  2. Создаем второй параметр (например, строковый &ГодСтрока), но снимаем у него флаг «Доступен» на вкладке «Параметры» в СКД, чтобы пользователь его не видел.
  3. В поле выражения для скрытого строкового параметра пишем: Формат(&Год, "ЧГ=0").

Таким образом, пользователь выбирает понятное число, система автоматически преобразует его в нужную строку, и мы можем использовать строковую переменную в запросе без лишних вычислений «на лету».

Выбор конкретного метода зависит от версии вашей технологической платформы «1С:Предприятие» и сложности бизнес-логики отчета. Для простых отчетов на новых платформах оптимально использовать функцию СТРОКА() в самом запросе. Для сложных комплексных расчетов и старых версий платформы лучшим решением остаются вычисляемые поля СКД с привлечением функций общих модулей.

← На главную