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