При разработке отчетов и печатных форм нередко возникает задача представить два числовых показателя в одной ячейке или колонке (например, вывести строку вида «32 из 35» на основе полей ФактКол и ПланКол). Начинающие разработчики часто пытаются решить эту задачу непосредственно в тексте запроса с помощью оператора конкатенации или конструкции приведения типов. Разберем, почему такой подход вызывает синтаксическую ошибку и какими способами можно правильно объединить данные.
Проанализируем базовые правила работы с типами данных в языке запросов платформы «1С:Предприятие»:
+ в тексте запроса работает исключительно со строковыми операндами. Если хотя бы одно из полей имеет тип Число, Дата, Булево или ссылочный тип, выполнение запроса завершится ошибкой несовместимости типов.ВЫРАЗИТЬ: данная конструкция не выполняет преобразование между базовыми типами. Она не умеет конвертировать число или дату в строку. Конструкция ВЫРАЗИТЬ предназначена только для уточнения ссылочного типа в составных полях (например, ВЫРАЗИТЬ(Ссылка КАК Документ.РеализацияТоваровУслуг)) либо для явного ограничения длины строк и чисел неограниченной длины (например, ВЫРАЗИТЬ(Комментарий КАК Строка(100))).ПРЕДСТАВЛЕНИЕ: возвращает системное строковое представление объекта или значения, однако полученный результат нельзя использовать внутри других выражений запроса (его нельзя соединять через + с другими строками или полями).Таким образом, объединить два числовых поля в строку непосредственно в самом запросе невозможно. Рассмотрим правильные архитектурные решения этой задачи на различных уровнях платформы.
Если задача решается в рамках отчета на СКД, переносить форматирование в запрос нет необходимости. Язык выражений компоновки данных существенно богаче языка запросов СУБД и поддерживает функции преобразования типов.
Итоги) и в колонке «Выражение» укажем формулу преобразования:
Формат(ФактКол, "ЧГ=0") + " из " + Формат(ПланКол, "ЧГ=0")
Или более простой вариант:
Строка(ФактКол) + " из " + Строка(ПланКол)
[ФактКол] из [ПланКол], связав параметры ячейки с числовыми полями набора данных.
МойОбщийМодульКлиентСервер.СформироватьСтрокуПланФакт(ФактКол, ПланКол)
Когда результат запроса обрабатывается программно (например, при формировании печатной формы или заполнении табличного документа), конкатенацию выполняют в цикле обхода выборки. Разберем пример реализации:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Таблица.Номенклатура КАК Номенклатура,
| Таблица.ФактКол КАК ФактКол,
| Таблица.ПланКол КАК ПланКол
|ИЗ
| РегистрНакопления.ПланыИФакты КАК Таблица";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Вариант 1: Использование функции СтрШаблон
СтрокаИтога = СтрШаблон("%1 из %2", Формат(Выборка.ФактКол, "ЧГ=0"), Формат(Выборка.ПланКол, "ЧГ=0"));
// Вариант 2: Явное сложение отформатированных строк
// СтрокаИтога = Формат(Выборка.ФактКол, "ЧГ=0") + " из " + Формат(Выборка.ПланКол, "ЧГ=0");
// Заполняем область табличного документа или выводим результат
ОбластьДанные.Параметры.Номенклатура = Выборка.Номенклатура;
ОбластьДанные.Параметры.Итоги = СтрокаИтога;
ТабДок.Вывести(ОбластьДанные);
КонецЦикла;
Если по логике алгоритма требуется передать готовый массив данных в виде ТаблицыЗначений, добавим строковую колонку после выполнения запроса и заполним ее значениями:
ТаблицаРезультат = Запрос.Выполнить().Выгрузить();
ТаблицаРезультат.Колонки.Добавить("Итоги", Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(50)));
Для Каждого Стр Из ТаблицаРезультат Цикл
Стр.Итоги = СтрШаблон("%1 из %2", Формат(Стр.ФактКол, "ЧГ=0"), Формат(Стр.ПланКол, "ЧГ=0"));
КонецЦикла;
Запрос динамического списка в управляемых формах подчиняется тем же ограничениям, что и обычный запрос 1С. Чтобы склеить два числовых значения в колонке динамического списка без потери производительности:
ПриПолученииДанныхНаСервере.
&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(Элемент, ОформленияСтрок)
Для Каждого Оформление Из ОформленияСтрок Цикл
Факт = Оформление.ДанныеСтроки.ФактКол;
План = Оформление.ДанныеСтроки.ПланКол;
Оформление.Ячейки.КолонкаИтоги.УстановитьТекст(СтрШаблон("%1 из %2", Формат(Факт, "ЧГ=0"), Формат(План, "ЧГ=0")));
КонецЦикла;
КонецПроцедуры
Таким образом, запрос должен отвечать исключительно за извлечение исходных данных, а операции форматирования и склеивания разнородных типов данных следует делегировать инструментам представления — СКД, коду встроенного языка или событиям формы.