К статье
Практический материал

Разработка и Конфигурация · 11 мин

Преобразование текста в число в запросе 1С

Как в запросе 1С преобразовать строку в число: функция ВЫРАЗИТЬ как число, ограничения, работа с разделителями, проверка результата и типичные ошибки.

В языке запросов 1С нет прямой функции приведения строки к числу вроде Число(), которая есть во встроенном языке платформы. Из-за этого задача «текст как число» в запросе регулярно ставит в тупик: поле хранится как строка, а сортировать, суммировать или сравнивать его нужно как числовое значение. Ситуация типична для данных, загруженных из Excel, веб-сервисов или внешних систем, где числовые реквизиты оказались строковыми.

Основной рабочий инструмент — функция ВЫРАЗИТЬ(... КАК ЧИСЛО(...)). Однако у неё есть важное ограничение: она корректно работает только со строками, содержащими «чистое» числовое представление, и ведёт себя по-разному в зависимости от содержимого. Понимание этих нюансов избавляет от неожиданных NULL в итоговой выборке и ошибок сортировки.

Ниже разобраны способы преобразования строки в число прямо в запросе, обходные приёмы для «грязных» данных (пробелы, неразрывные пробелы, запятые вместо точек), проверка результата и типичные ошибки, которые приводят к потере данных или падению производительности.

Базовый способ: функция ВЫРАЗИТЬ как число

Функция ВЫРАЗИТЬ приводит значение к указанному типу. Для преобразования строки в число синтаксис выглядит так:

ВЫБРАТЬ

ВЫРАЗИТЬ(Данные.КодСтрокой КАК ЧИСЛО(10, 0)) КАК КодЧислом

ИЗ

РегистрСведений.ВнешниеКоды КАК Данные

Параметры типа ЧИСЛО(Длина, Точность) задают максимальную длину числа и количество знаков после запятой. Если реальное значение не помещается в указанную разрядность, запрос может вернуть ошибку или обрезанное значение — зависит от СУБД. Поэтому длину лучше задавать с запасом: ЧИСЛО(15, 2) подходит для большинства учётных величин.

Важно понимать: ВЫРАЗИТЬ — это не «умный» парсер. Она ожидает, что строка уже содержит корректное числовое представление с точкой в качестве разделителя дробной части и без посторонних символов. Строка "123.45" преобразуется успешно, а вот "123,45" или "1 234.5" — с высокой вероятностью дадут NULL.

Почему результат преобразования равен NULL

NULL вместо числа — самый частый симптом при таком преобразовании. Причины обычно следующие:

  • в строке есть неразрывные пробелы (частый подарок из Excel и веб-страниц);
  • дробная часть отделена запятой, а не точкой;
  • встречаются буквы, валютные символы, единицы измерения («100 кг»);
  • строка пустая или содержит только пробелы;
  • используются разделители разрядов: «1 000 000».

Диагностика проста: выберите исходное строковое поле и результат преобразования рядом, отсортируйте по результату и посмотрите, какие значения «выпали» в NULL. Для проверки на нечисловые строки удобен оператор ПОДОБНО:

ВЫБРАТЬ

Данные.ЗначениеСтрокой

ИЗ

РегистрСведений.Данные КАК Данные

ГДЕ

НЕ Данные.ЗначениеСтрокой ПОДОБНО "[0-9]%"

Шаблон ПОДОБНО в запросах 1С ограничен (нет полноценных регулярных выражений), но для выявления строк, начинающихся не с цифры, его достаточно.

Результат NULLСтрока не является чистым числом

Проверить пробелы, запятые, посторонние символы

Число обрезаноНе хватает разрядности ЧИСЛО(Длина, Точность)

Увеличить параметры типа

Сортировка «1, 10, 2»Поле сортируется как строка

Применить ВЫРАЗИТЬ к числу в УПОРЯДОЧИТЬ ПО

Ошибка выполнения запросаЗначение не помещается в тип на конкретной СУБД

Сузить выборку, найти выбивающиеся значения

Очистка «грязных» строк прямо в запросе

Если исходные данные содержат неразрывные пробелы или разделители разрядов, их можно убрать вложенными вызовами ПОДСТРОКА — но это громоздко. Практичнее заменить символы заранее. В чистом запросе доступна функция ПОДСТРОКА, но функции замены подстроки в языке запросов нет. Поэтому рабочие варианты такие:

Замена запятой на точку

Трюк с конкатенацией и ПОДСТРОКА помогает только для простых случаев. Надёжнее привести данные к одному формату ещё на этапе загрузки — во встроенном языке функцией СтрЗаменить до записи в базу.

Удаление пробелов

Обычные пробелы по краям убирает приведение типа автоматически в большинстве случаев, но неразрывный пробел (символ 160) — нет. Если данные грузятся извне, лучшая практика — при загрузке выполнить СтрЗаменить(Значение, Символ(160), "") и записывать уже очищенное значение.

Промежуточная таблица с обработкой

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

Порядок действий для «грязных» данных
  1. 1
    Выберите исходные строки и найдите значения, дающие NULL после ВЫРАЗИТЬ
  2. 2
    Определите мешающие символы: неразрывный пробел, запятая, единицы измерения
  3. 3
    Очистите данные на встроенном языке: СтрЗаменить, СокрЛП, затем Число()
  4. 4
    Поместите очищенные значения во временную таблицу и передайте в запрос
  5. 5
    Соедините временную таблицу с основной выборкой и работайте уже с числами

Сортировка и сравнение строк как чисел

Частая задача — упорядочить строковый код или номер как число. Без преобразования сортировка идёт лексикографически: «1», «10», «2», «25». Решение — применить ВЫРАЗИТЬ прямо в секции УПОРЯДОЧИТЬ ПО:

ВЫБРАТЬ

Номенклатура.Артикул

ИЗ

Справочник.Номенклатура КАК Номенклатура

УПОРЯДОЧИТЬ ПО

ВЫРАЗИТЬ(Номенклатура.Артикул КАК ЧИСЛО(10, 0))

Тот же приём работает в условиях сравнения: ГДЕ ВЫРАЗИТЬ(Поле КАК ЧИСЛО(10, 0)) > 100. Но здесь есть подводный камень: преобразование в условии отключает использование индекса по этому полю, и на больших таблицах запрос заметно замедлится. Если такие сравнения нужны постоянно, правильнее добавить в объект отдельный числовой реквизит и заполнять его при записи.

Альтернативы и смежные приёмы

Если ВЫРАЗИТЬ не справляется, есть несколько обходных путей. Выбор зависит от того, где возникает задача и насколько «грязные» данные.

Первый вариант — обработка на встроенном языке: функция Число() умеет больше, чем приведение в запросе, а в связке со СтрЗаменить и ОписаниеТипов позволяет безопасно распарсить почти любой формат. Результат передаётся в запрос через временную таблицу или параметр.

Второй вариант — вычисляемое поле в СКД или выражение в запросе с конструкцией ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ 0 КОНЕЦ, чтобы заменить NULL на ноль и не ломать итоги:

ВЫБОР

КОГДА ВЫРАЗИТЬ(Данные.Значение КАК ЧИСЛО(15, 2)) ЕСТЬ NULL

ТОГДА 0

ИНАЧЕ ВЫРАЗИТЬ(Данные.Значение КАК ЧИСЛО(15, 2))

КОНЕЦ КАК ЗначениеЧислом

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

Сравнение вариантов

ВЫРАЗИТЬ в запросе

Быстро для чистых данных; не справляется с запятыми, пробелами и буквами

Обработка кодом + временная таблица

Гибко, работает с любым форматом; требует больше кода и двух этапов

Числовой реквизит в объекте

Лучшее решение на перспективу; требует изменения конфигурации и конвертации данных

ВЫБОР КОГДА ... ИНАЧЕ 0

Спасает итоги от NULL, но маскирует проблемные данные вместо их исправления

Типичные ошибки и ограничения

Первая ошибка — ожидание, что ВЫРАЗИТЬ «поймёт» любой формат. Она не парсер, а приведение типа, и требования к входной строке жёсткие. Вторая — слишком маленькая разрядность: ЧИСЛО(5, 0) для значений вроде 123456 приведёт к ошибке или обрезке. Третья — игнорирование NULL: при соединении таблиц по преобразованному полю строки с NULL просто выпадают из результата, и итоги не сходятся.

Отдельно стоит помнить про итоги и группировки: СУММА(ВЫРАЗИТЬ(...)) корректно работает только если все значения преобразовались. Один NULL не сломает сумму (NULL игнорируется агрегатными функциями), но результат будет занижен без какого-либо предупреждения.

Типичные ошибки
01
Указана малая разрядность ЧИСЛО(5,0) — большие значения обрезаются или вызывают ошибку
02
Игнорируются NULL: строки молча выпадают из соединений и занижают суммы
03
ВЫРАЗИТЬ в условии ГДЕ на большой таблице — потеря индекса и резкое падение скорости
04
Попытка преобразовать строку с запятой или неразрывным пробелом без предварительной очистки
05
Замена NULL нулём через ВЫБОР вместо исправления исходных данных

Проверка результата преобразования

После внедрения преобразования полезно выполнить контроль: сравнить количество строк исходной выборки и количество непустых значений после приведения. Расхождение покажет объём «потерянных» данных. Для финансовых величин дополнительно сверяют сумму до (по очищенным значениям кодом) и после (в запросе).

Контрольные точки

Как проверить результат

Количество строк до и после преобразования
Норма

Совпадает, NULL отсутствуют

Тревожный признак

Часть строк дала NULL — есть некорректные значения

Сортировка по числовому значению
Норма

Порядок 1, 2, 10, 25

Тревожный признак

Порядок 1, 10, 2, 25 — сортировка осталась строковой

Сумма по преобразованному полю
Норма

Совпадает с контрольной суммой, посчитанной кодом

Тревожный признак

Сумма занижена — часть значений не преобразовалась

Итог

Что важно запомнить

Текст в число в запросе 1С преобразуется через ВЫРАЗИТЬ(Поле КАК ЧИСЛО(Длина, Точность)). Функция требует чистого числового формата с точкой; грязные данные дают NULL и требуют очистки кодом. Для регулярных задач надёжнее хранить значения в числовом реквизите.

Частые вопросы

Можно ли в запросе 1С использовать функцию Число() как во встроенном языке?

Нет, в языке запросов такой функции нет. Приведение выполняется только через ВЫРАЗИТЬ(... КАК ЧИСЛО(...)). Функция Число() доступна во встроенном языке и применяется при обработке данных вне запроса.

Почему ВЫРАЗИТЬ возвращает NULL вместо ошибки?

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

Как преобразовать строку с запятой, например «123,45»?

В самом запросе надёжного способа нет. Очистите значение до запроса: во встроенном языке выполните СтрЗаменить(Значение, ",", ".") и передайте результат через временную таблицу, либо исправьте данные при загрузке в базу.

Влияет ли ВЫРАЗИТЬ на производительность запроса?

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

Как заменить NULL на ноль после преобразования?

Используйте функцию ЕСТЬNULL(ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15, 2)), 0) — это короче конструкции ВЫБОР. Учтите, что ноль замаскирует проблемные исходные значения, поэтому параллельно стоит найти и исправить сами данные.

Работает ли приём в динамических списках и СКД?

Да, ВЫРАЗИТЬ поддерживается в тексте запроса динамического списка и в выражениях СКД, включая вычисляемые поля и ресурсы. Ограничения те же: чистый формат строки и осторожность с условиями на больших выборках.