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

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

При разработке отчетов и печатных форм нередко возникает задача представить два числовых показателя в одной ячейке или колонке (например, вывести строку вида «32 из 35» на основе полей ФактКол и ПланКол). Начинающие разработчики часто пытаются решить эту задачу непосредственно в тексте запроса с помощью оператора конкатенации или конструкции приведения типов. Разберем, почему такой подход вызывает синтаксическую ошибку и какими способами можно правильно объединить данные.

Ограничения языка запросов 1С

Проанализируем базовые правила работы с типами данных в языке запросов платформы «1С:Предприятие»:

  1. Оператор сложения (конкатенации) строк: оператор + в тексте запроса работает исключительно со строковыми операндами. Если хотя бы одно из полей имеет тип Число, Дата, Булево или ссылочный тип, выполнение запроса завершится ошибкой несовместимости типов.
  2. Конструкция ВЫРАЗИТЬ: данная конструкция не выполняет преобразование между базовыми типами. Она не умеет конвертировать число или дату в строку. Конструкция ВЫРАЗИТЬ предназначена только для уточнения ссылочного типа в составных полях (например, ВЫРАЗИТЬ(Ссылка КАК Документ.РеализацияТоваровУслуг)) либо для явного ограничения длины строк и чисел неограниченной длины (например, ВЫРАЗИТЬ(Комментарий КАК Строка(100))).
  3. Функция ПРЕДСТАВЛЕНИЕ: возвращает системное строковое представление объекта или значения, однако полученный результат нельзя использовать внутри других выражений запроса (его нельзя соединять через + с другими строками или полями).

Таким образом, объединить два числовых поля в строку непосредственно в самом запросе невозможно. Рассмотрим правильные архитектурные решения этой задачи на различных уровнях платформы.

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

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

  1. Вычисляемые поля: перейдем на вкладку «Вычисляемые поля» схемы компоновки данных, добавим новое поле (например, Итоги) и в колонке «Выражение» укажем формулу преобразования: Формат(ФактКол, "ЧГ=0") + " из " + Формат(ПланКол, "ЧГ=0") Или более простой вариант: Строка(ФактКол) + " из " + Строка(ПланКол)
  2. Пользовательские поля (Поле-выражение): аналогичное выражение можно прописать непосредственно в пользовательских настройках отчета без изменения самой схемы данных.
  3. Использование макета поля: на вкладке «Макеты» создадим макет поля, установим для ячейки тип «Шаблон» и укажем текст вида [ФактКол] из [ПланКол], связав параметры ячейки с числовыми полями набора данных.
  4. Вызов функции общего модуля: в выражении вычисляемого поля СКД можно вызвать экспортную функцию серверного общего модуля: МойОбщийМодульКлиентСервер.СформироватьСтрокуПланФакт(ФактКол, ПланКол)

Решение 2. Форматирование в коде при обходе выборки

Когда результат запроса обрабатывается программно (например, при формировании печатной формы или заполнении табличного документа), конкатенацию выполняют в цикле обхода выборки. Разберем пример реализации:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Таблица.Номенклатура КАК Номенклатура,
    |   Таблица.ФактКол КАК ФактКол,
    |   Таблица.ПланКол КАК ПланКол
    |ИЗ
    |   РегистрНакопления.ПланыИФакты КАК Таблица";

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    // Вариант 1: Использование функции СтрШаблон
    СтрокаИтога = СтрШаблон("%1 из %2", Формат(Выборка.ФактКол, "ЧГ=0"), Формат(Выборка.ПланКол, "ЧГ=0"));
    
    // Вариант 2: Явное сложение отформатированных строк
    // СтрокаИтога = Формат(Выборка.ФактКол, "ЧГ=0") + " из " + Формат(Выборка.ПланКол, "ЧГ=0");
    
    // Заполняем область табличного документа или выводим результат
    ОбластьДанные.Параметры.Номенклатура = Выборка.Номенклатура;
    ОбластьДанные.Параметры.Итоги = СтрокаИтога;
    ТабДок.Вывести(ОбластьДанные);
КонецЦикла;

Решение 3. Постобработка в Таблице Значений

Если по логике алгоритма требуется передать готовый массив данных в виде ТаблицыЗначений, добавим строковую колонку после выполнения запроса и заполним ее значениями:


ТаблицаРезультат = Запрос.Выполнить().Выгрузить();
ТаблицаРезультат.Колонки.Добавить("Итоги", Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(50)));

Для Каждого Стр Из ТаблицаРезультат Цикл
    Стр.Итоги = СтрШаблон("%1 из %2", Формат(Стр.ФактКол, "ЧГ=0"), Формат(Стр.ПланКол, "ЧГ=0"));
КонецЦикла;

Решение 4. Отображение в Динамическом Списке формы

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

  1. Добавим в таблицу формы пользовательскую колонку (без привязки к реквизиту списка).
  2. В свойствах таблицы формы назначим обработчик события ПриПолученииДанныхНаСервере.
  3. Заполним текст ячеек для отображаемых на экране строк:

&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(Элемент, ОформленияСтрок)
    Для Каждого Оформление Из ОформленияСтрок Цикл
        Факт = Оформление.ДанныеСтроки.ФактКол;
        План = Оформление.ДанныеСтроки.ПланКол;
        
        Оформление.Ячейки.КолонкаИтоги.УстановитьТекст(СтрШаблон("%1 из %2", Формат(Факт, "ЧГ=0"), Формат(План, "ЧГ=0")));
    КонецЦикла;
КонецПроцедуры

Таким образом, запрос должен отвечать исключительно за извлечение исходных данных, а операции форматирования и склеивания разнородных типов данных следует делегировать инструментам представления — СКД, коду встроенного языка или событиям формы.

← На главную