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

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

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

Разберем причины такого поведения платформы, проанализируем ограничения языка запросов 1С и рассмотрим практические способы решения этой задачи.

Почему нельзя объединить число и строку в запросе 1С

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

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

Поскольку в самом запросе сложить число и строку не получится, рассмотрим рабочие альтернативные подходы.

Способ 1. Объединение колонок в таблице формы («В ячейке»)

Наиболее простое и быстрое решение, не требующее написания программного кода, заключается в раздельном получении данных в запросе и их визуальном объединении на уровне элементов формы.

Разберем по шагам реализацию данного способа:

  1. В запросе динамического списка выбираем числовое значение веса и единицу измерения отдельными полями:
    
    ВЫБРАТЬ
        СпрНоменклатура.Ссылка КАК Ссылка,
        СпрНоменклатура.Наименование КАК Наименование,
        ВЫБОР
            КОГДА СпрНоменклатура.ВесИспользовать
                ТОГДА СпрНоменклатура.ВесЧислитель / ВЫБОР
                        КОГДА СпрНоменклатура.ВесЗнаменатель = 0
                            ТОГДА 1
                        ИНАЧЕ СпрНоменклатура.ВесЗнаменатель
                    КОНЕЦ
            ИНАЧЕ 0
        КОНЕЦ КАК Вес,
        СпрНоменклатура.ВесЕдиницаИзмерения КАК ВесЕдиницаИзмерения
    ИЗ
        Справочник.Номенклатура КАК СпрНоменклатура
    
  2. В редакторе формы открываем состав элементов таблицы динамического списка. Создаем новый элемент — Группа колонок (тип ГруппаКолонок).
  3. В свойствах созданной группы устанавливаем свойство Группировка в значение В ячейке. Задаем заголовок группы, например: Вес.
  4. Переносим внутрь этой группы оба поля: поле веса и поле единицы измерения.
  5. Чтобы избавиться от дублирования названий в шапке (когда платформа формирует заголовок вида «Вес, Единица измерения веса»), для элемента формы поля единицы измерения находим свойство ПоложениеЗаголовка и переключаем его в значение Нет.

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

Способ 2. Использование пользовательских полей СКД

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

Рассмотрим, как настроить расчетное поле программно при инициализации формы. В обработчике ПриСозданииНаСервере можно добавить вычисляемое пользовательское поле в настройки списка:


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

Этот способ позволяет получить строковое значение, доступное для добавления в список стандартными пользовательскими настройками.

Способ 3. Формирование строки в событии «ПриПолученииДанныхНаСервере»

Если необходимо сформировать сложное строковое представление с точным форматом чисел и без автоматических разделителей платформы, используем серверный обработчик таблицы.

Разберем алгоритм настройки:

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

Обратите внимание: текст, выведенный через свойство Ячейки...Текст, является исключительно визуальным оформлением. По нему не будет работать стандартный поиск платформы по списку и сортировка по клику на заголовок колонки (сортировку в таком случае следует настраивать по исходному числовому полю Вес).

← На главную