Как в отчете СКД превратить строку с цифрами в полноценное число?

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

Часто возникает задача, когда в отчете на Системе Компоновки Данных (СКД) нужно выполнить математические операции, сортировку или группировку по полю, которое в базе данных хранится как строка, но по сути содержит число. Классический пример — наименование характеристики вида "цена 135" или "размер 42", из которого нужно извлечь числовое значение для дальнейшей работы.

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

Анализ проблемы: почему запрос в СКД не видит данные?

Прежде чем перейти к решениям, важно понять первоначальную трудность, с которой столкнулся автор вопроса. Попытка обработать строку в самом наборе данных-запросе в СКД не дала результата — поле на выходе было пустым. Причина кроется в механизме работы СКД.

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

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

Решение 1: Функция Вычислить() в вычисляемом поле — самый простой способ

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

Рассмотрим по шагам, как это сделать:

  1. Откройте схему компоновки данных и перейдите на закладку "Вычисляемые поля".
  2. Нажмите "Добавить", чтобы создать новое вычисляемое поле. Задайте ему понятное имя, например, ЦенаЧислом.
  3. В колонке "Выражение" напишите формулу, используя функцию Вычислить(). В качестве аргумента передайте то поле, которое содержит вашу строку с числом. Например, если поле называется НаименованиеХарактеристики: Вычислить(НаименованиеХарактеристики)
  4. В колонке "Заголовок" можно указать название, которое будет отображаться для пользователя, например, "Цена".

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

Особенность работы с дробными числами:
Функция Вычислить() ожидает, что десятичным разделителем в строке будет точка. Если в ваших данных используется запятая (например, "цена 135,50"), функция выдаст синтаксическую ошибку. В этом случае строку нужно предварительно обработать, заменив запятую на точку, например, с помощью функции Выразить(), если она доступна в контексте, или подготовить строку еще на уровне запроса.

Решение 2: Комбинированный подход — очистка строки в запросе и преобразование в СКД

Этот метод подходит для более сложных случаев, когда строка содержит не только числа, но и текст, который нужно удалить. Например, "цена 135 руб." или "Арт. 00-123". Логика здесь разделяется на два этапа:

  1. В запросе: с помощью строковых функций языка запросов "очищаем" исходную строку, оставляя только цифры.
  2. В вычисляемом поле СКД: применяем функцию Вычислить() к уже очищенной строке.

Посмотрим на пример. Допустим, у нас есть поле НаименованиеХарактеристики со значениями вида "цена 123", "цена 150" и т.д. Мы знаем, что цена всегда идет после 6-го символа.

Шаг 1: Модифицируем запрос.

В наборе данных-запросе добавим новое поле, в котором извлечем подстроку с числом.


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Номенклатура,
    ХарактеристикиНоменклатуры.Ссылка КАК Характеристика,
    ХарактеристикиНоменклатуры.Наименование КАК ИмяХарактеристики,
    ПОДСТРОКА(ХарактеристикиНоменклатуры.Наименование, 6, 10) КАК ЦенаСтрокой
ИЗ
    Справочник.ХарактеристикиНоменклатуры КАК ХарактеристикиНоменклатуры
    ...

Здесь мы создали поле ЦенаСтрокой, которое будет содержать только "123", "150" и т.д. Для более сложной логики можно использовать оператор ПОДОБНО или функцию СТРЗАМЕНИТЬ.

Шаг 2: Создаем вычисляемое поле.

Теперь на закладке "Вычисляемые поля" создаем поле ЦенаЧислом с выражением:

Вычислить(ЦенаСтрокой)

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

Решение 3: Использование функции из общего модуля — для самой сложной логики

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

Порядок действий:

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

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

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

← На главную