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

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

Как преобразовать строку в число в запросе 1С 8.3

Способы преобразования строки в число в запросе 1С 8.3: ВЫРАЗИТЬ, соединение со справочником, ВЫБОР с ПОДСТРОКА. Примеры кода, ограничения и типичные ошибки.

Задача преобразовать строку в число прямо в тексте запроса возникает регулярно: данные пришли из обмена в строковом виде, код или артикул хранится как строка, а сравнивать и сортировать нужно как числа. Проблема в том, что язык запросов 1С 8.3 не содержит функции прямого приведения строки к числу — в отличие от встроенного языка, где есть Число().

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

Ниже разобраны рабочие варианты: соединение со справочником, разбор строки через ПОДСТРОКА и ВЫБОР, перенос преобразования на уровень встроенного языка, а также способ «не преобразовывать вовсе», изменив постановку задачи. Для каждого приёма указано, когда он оправдан и где подводит.

Почему ВЫРАЗИТЬ не решает задачу

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

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

Способ 1. Соединение со справочником или регистром

Самый надёжный приём — не преобразовывать строку, а найти соответствующее числовое значение в другой таблице. Типичный сценарий: строка — это код или артикул, по которому в справочнике есть числовой реквизит. Тогда вместо преобразования выполняется левое соединение, и в результат попадает уже число.

ВЫБРАТЬ

Товары.Артикул КАК Артикул,

СправочникАртикулов.ПорядковыйНомер КАК Номер

ИЗ

Документ.Реализация.Товары КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Артикулы КАК СправочникАртикулов

ПО Товары.Артикул = СправочникАртикулов.Код

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

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

Способ 2. Разбор строки через ПОДСТРОКА и ВЫБОР

Если строка гарантированно состоит из цифр известной длины, число можно собрать посимвольно: каждый символ через ВЫБОР превращается в цифру, которая умножается на разрядный вес и суммируется. Приём громоздкий, но работает полностью на стороне СУБД.

ВЫБРАТЬ

ВЫБОР

КОГДА ПОДСТРОКА(Данные.Код, 1, 1) = "1" ТОГДА 1000

КОГДА ПОДСТРОКА(Данные.Код, 1, 1) = "2" ТОГДА 2000

ИНАЧЕ 0

КОНЕЦ

+ ВЫБОР

КОГДА ПОДСТРОКА(Данные.Код, 2, 1) = "1" ТОГДА 100

КОГДА ПОДСТРОКА(Данные.Код, 2, 1) = "2" ТОГДА 200

ИНАЧЕ 0

КОНЕЦ КАК КодЧислом

ИЗ

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

Для полного перебора цифр 0–9 в каждом разряде потребуется по десять веток КОГДА. Реальный текст запроса быстро разрастается, поэтому такой код обычно генерируют программно — циклом встроенного языка собирают строку запроса под нужную длину числа.

Ограничения приёма существенные: длина строки должна быть фиксированной и небольшой (практически — до 6–8 разрядов), дробные числа и знак «минус» обрабатывать придётся отдельными ветками, а любой нецифровой символ молча превратится в ноль. Если в данных возможны «грязные» значения, результат нужно обязательно проверять.

Способ 3. Преобразование встроенным языком до или после запроса

Часто правильное решение — вынести преобразование за пределы запроса. Если строка участвует в условии отбора, преобразуйте параметр до выполнения: Запрос.УстановитьПараметр("Код", Число(СтрокаКода)). Функция Число() встроенного языка корректно разбирает строку, а при нечисловом значении выдаёт понятную ошибку, которую можно перехватить через Попытка...Исключение.

Второй вариант — обойти результат запроса и добавить вычисляемую колонку. Для таблицы значений это делается так: добавляется колонка с типом «Число», затем в цикле Для Каждого Строка Из Таблица Цикл заполняется через Число(Строка.СтроковоеПоле). Для СКД аналогичная задача решается вычисляемым полем на вкладке «Вычисляемые поля», где в выражении доступен встроенный язык.

Порядок действий при обходе результата
  1. 1
    Выполните запрос и выгрузите результат в таблицу значений
  2. 2
    Добавьте колонку с описанием типа Число нужной длины и точности
  3. 3
    В цикле заполните колонку через Число() с обработкой исключений для нечисловых значений
  4. 4
    Проверьте выборочно несколько строк: число должно совпадать со строковым представлением

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

Способ 4. Перевернуть задачу: привести число к строке

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

Практический смысл: преобразование «число → строка» обычно выполняется один раз для параметра встроенным языком (Формат(ЧисловоеЗначение, "ЧГ=")), а не для каждой строки таблицы. Это на порядки дешевле, чем собирать числа из строк в каждой записи. Перед тем как строить сложный запрос, проверьте, нельзя ли переформулировать условие отбора таким образом.

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

Соединение со справочником

Подходит, когда есть таблица соответствий строка-число. Быстро и надёжно, но требует такой таблицы

ПОДСТРОКА + ВЫБОР

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

Число() до или после запроса

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

Преобразование параметра в строку

Оптимально для условий отбора: одна операция вместо преобразования всей таблицы

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

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

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

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

Соответствие строки и числа на контрольных записях
Норма

Число равно значению строки, включая ведущие нули в исходнике

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

Число отличается или равно нулю там, где строка содержит цифры

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

Совпадает с количеством до соединения

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

Записей стало больше — дубли в таблице соответствий

Обработка нечисловых строк
Норма

Такие строки явно помечены или отфильтрованы

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

Нечисловые строки молча стали нулём

Отдельно стоит помнить про ведущие нули: строки «00123» и «0123» после преобразования дадут одно и то же число 123. Если это коды разных объектов, преобразование в число уничтожит различие между ними — и соединения по числовому полю начнут давать ложные совпадения.

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

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

Можно ли в запросе 1С отсортировать строковые коды как числа?

Напрямую — нет, сортировка строк идёт лексикографически: «10» окажется раньше «2». Варианты: добавить в запрос вычисляемое числовое поле одним из описанных способов и сортировать по нему, либо дополнить строки ведущими нулями до одинаковой длины ещё при записи данных — тогда строковая сортировка совпадёт с числовой.

Что вернёт Число() для строки с буквами?

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

Работает ли посимвольный разбор для дробных чисел?

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

Можно ли преобразовать строку в число в СКД?

Да, и это удобнее, чем в запросе. На закладке «Вычисляемые поля» добавьте поле с выражением на встроенном языке, например Число(СтроковоеПоле). Выражение выполняется для каждой строки результата, поэтому для больших выборок учитывайте стоимость обхода.

Почему соединение по строковому коду не находит совпадения?

Чаще всего причины в расхождении форматов: ведущие или конечные пробелы, разная длина кода с ведущими нулями, неразрывные пробелы из выгрузок, отличия регистра букв. Сравните значения через вычисление длины строки и посимвольный вывод — расхождение обычно видно сразу.

Есть ли разница в поведении на разных СУБД?

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

Итог

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

Прямого приведения строки к числу в запросе 1С 8.3 нет. Выбирайте приём по ситуации: соединение со справочником — если есть таблица соответствий, ПОДСТРОКА с ВЫБОР — для коротких строк из чистых цифр, Число() встроенного языка — как универсальный вариант. Всегда проверяйте результат на контрольных записях и помните про ведущие нули.