Разработка и Конфигурация · 11 мин
1С запрос: как преобразовать строку в число
Как в запросе 1С преобразовать строку в число: ВЫРАЗИТЬ, ПОДСТРОКА, ВЫБОР, проверка результата, типичные ошибки и ограничения платформы.
Задача «1С запрос строку как число» возникает, когда числовые данные хранятся в строковом реквизите: артикулы с цифрами, суммы, загруженные из Excel, коды, по которым нужна сортировка или сравнение. В языке запросов 1С нет прямой функции приведения типа «строка → число» по аналогии с функцией Число() во встроенном языке, поэтому разработчику приходится выбирать обходные пути.
Ключевой момент, который нужно понять сразу: конструкция ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15,2)) не преобразует содержимое строки в число. Она выполняет приведение типов только между совместимыми типами — например, сужает составной тип или уточняет длину и точность числа. Если применить её к строковому полю, значение не «вычислится»: в зависимости от СУБД вы получите ошибку запроса либо NULL/некорректный результат.
Ниже разобраны рабочие способы: когда достаточно ВЫРАЗИТЬ, как собрать число из строки через ПОДСТРОКА и ВЫБОР, как проверить строку на «числовость», какие ограничения накладывает платформа и какие ошибки встречаются чаще всего.
Почему ВЫРАЗИТЬ(Строка КАК ЧИСЛО) не работает
Оператор ВЫРАЗИТЬ в языке запросов 1С предназначен для приведения типов, а не для преобразования значений. Он корректно работает в трёх случаях: уточнение типа поля составного типа (например, выбрать только числовую часть составного реквизита), изменение длины строки или точности числа, приведение ссылки к конкретному типу справочника или документа.
Строка и число — несовместимые для ВЫРАЗИТЬ типы. Попытка написать ВЫРАЗИТЬ(Номенклатура.Код КАК ЧИСЛО(10,0)) приведёт к ошибке исполнения запроса на большинстве используемых СУБД, потому что платформа не умеет интерпретировать символьное содержимое как число на уровне запроса. Это принципиальное ограничение, а не ошибка синтаксиса.
Способ 1. Преобразование во встроенном языке до запроса
Самый надёжный и производительный вариант — не мучить запрос, а подготовить данные заранее. Если строковые значения приходят из внешнего источника (файл, обмен, табличная часть), пройдитесь по ним во встроенном языке, примените функцию Число() и поместите результат во временную таблицу или таблицу значений, которую затем передаёте в запрос параметром.
Типовой фрагмент выглядит так: создаётся таблица значений с колонкой типа «Число», в цикле строки обрабатываются через Число(СокрЛП(СтрокаЗначение)) с защитой через Попытка/Исключение или предварительную проверку, затем таблица помещается во временную таблицу запроса командой ПОМЕСТИТЬ. Дальше в запросе работают уже настоящие числа: сортировка, сравнение, агрегаты — всё доступно.
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Значение", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
Для Каждого Стр Из ИсходныеДанные Цикл
Попытка
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Значение = Число(СокрЛП(Стр.СтрокаЧисло));
Исключение
// строка не является числом — пропускаем или фиксируем
КонецПопытки;
КонецЦикла;
Запрос.УстановитьПараметр("ТЗ", ТЗ);
Запрос.Текст = "ВЫБРАТЬ Т.Значение ПОМЕСТИТЬ ВТ ИЗ &ТЗ КАК Т";Плюсы подхода: полная корректность, контроль ошибок на уровне кода, высокая скорость запроса. Минус: требуется изменение модуля, а не только текста запроса, что не всегда возможно в типовых отчётах на СКД без расширения.
Способ 2. Посимвольный разбор через ПОДСТРОКА и ВЫБОР
Когда строка короткая и гарантированно состоит из цифр (например, код фиксированной длины), число можно собрать прямо в запросе. Идея: извлечь каждый символ функцией ПОДСТРОКА, через ВЫБОР сопоставить ему цифру и умножить на разряд — единицы, десятки, сотни и так далее.
Пример для строки длиной 3 символа:
ВЫБРАТЬ
ВЫБОР ПОДСТРОКА(Т.Код, 1, 1)
КОГДА "1" ТОГДА 1 КОГДА "2" ТОГДА 2 КОГДА "3" ТОГДА 3
КОГДА "4" ТОГДА 4 КОГДА "5" ТОГДА 5 КОГДА "6" ТОГДА 6
КОГДА "7" ТОГДА 7 КОГДА "8" ТОГДА 8 КОГДА "9" ТОГДА 9
ИНАЧЕ 0
КОНЕЦ <em> 100
+ ВЫБОР ПОДСТРОКА(Т.Код, 2, 1)
КОГДА "1" ТОГДА 1 КОГДА "2" ТОГДА 2 КОГДА "3" ТОГДА 3
КОГДА "4" ТОГДА 4 КОГДА "5" ТОГДА 5 КОГДА "6" ТОГДА 6
КОГДА "7" ТОГДА 7 КОГДА "8" ТОГДА 8 КОГДА "9" ТОГДА 9
ИНАЧЕ 0
КОНЕЦ </em> 10
+ ВЫБОР ПОДСТРОКА(Т.Код, 3, 1)
КОГДА "1" ТОГДА 1 КОГДА "2" ТОГДА 2 КОГДА "3" ТОГДА 3
КОГДА "4" ТОГДА 4 КОГДА "5" ТОГДА 5 КОГДА "6" ТОГДА 6
КОГДА "7" ТОГДА 7 КОГДА "8" ТОГДА 8 КОГДА "9" ТОГДА 9
ИНАЧЕ 0
КОНЕЦ КАК КодЧислом
ИЗ Справочник.Номенклатура КАК ТОграничения очевидны: конструкция громоздка, работает только для целых чисел известной максимальной длины, не понимает знак минус, десятичный разделитель и пробелы. Каждый нецифровой символ молча превращается в 0, что искажает результат: строка «1А2» даст 102 вместо ошибки. Поэтому способ применим только при жёстко контролируемом формате данных.
Проверка строки на числовое содержимое
Перед любым преобразованием полезно отфильтровать строки, которые не являются числами. В языке запросов нет функции «это число», поэтому проверка строится на тех же ПОДСТРОКА и ВЫБОР: строка считается числовой, если каждый её символ входит в множество цифр.
Практичный вариант — вычисляемое поле-признак: сумма ВЫБОР-конструкций, где за нецифровой символ начисляется 1. Если итог равен нулю, строка чистая. Дополнительно проверяйте пустую строку (пустая строка формально «пройдёт» такую проверку, но Число("") во встроенном языке вызовет ошибку) и лидирующие пробелы через СокрЛП-эквивалент — в запросе полноценного СокрЛП нет, есть только ПОДСТРОКА и сравнение с шаблоном через ПОДОБНО.
Как проверить результат преобразования
Все строки на месте, числа совпадают с исходными строками
Часть строк потерялась или значения обнулились
NULL отсутствуют или ожидаемы для пустых значений
NULL там, где в строке были цифры
Сумма чисел совпадает с контрольной суммой источника
Расхождение — есть искажённые значения
Сортировка строк как чисел без преобразования
Частая реальная задача за формулировкой «строку как число» — это сортировка: коды «1, 2, 10, 11» в строковом виде сортируются как «1, 10, 11, 2». Если данные менять нельзя, есть два обходных приёма, не требующих полноценного преобразования.
Первый — дополнить строку лидирующими нулями до фиксированной длины, тогда строковая сортировка совпадёт с числовой. В запросе это делается через ПОДСТРОКА с конкатенацией: например, ПОДСТРОКА("000000000" + Поле, ДЛИНАСТРОКИ(Поле), 9) — функция ДЛИНАСТРОКИ доступна в запросах и позволяет вычислить позицию начала. Второй приём — уже описанный посимвольный разбор, если длина кодов невелика.
Сравнение подходов
Универсально и надёжно, обрабатывает дробные и отрицательные числа. Требует изменения кода модуля.
Работает прямо в запросе, но только для коротких целых чисел строгого формата; молча искажает нецифровые символы.
Решает только задачу упорядочивания; для сравнения и агрегатов не подходит.
Правильное стратегическое решение, если данные по сути числовые; требует конвертации данных и анализа зависимостей.
Когда правильнее изменить тип реквизита
Если строковый реквизит постоянно используется как число — в отчётах, отборах, сортировках — это симптом ошибки проектирования. Постоянные обходные преобразования усложняют запросы, замедляют их и провоцируют ошибки в данных. В такой ситуации корректное решение — изменить тип реквизита на Число с подходящими длиной и точностью.
Порядок безопасной миграции: создать резервную копию, добавить новый числовой реквизит, написать обработку переноса значений через Число() с протоколированием неудачных строк, проверить результат на полной выборке, переключить отчёты и запросы на новый реквизит и только после этого удалять старый. В типовой конфигурации на поддержке используйте расширение, чтобы не снимать объекты с поддержки.
- 1Сделайте резервную копию информационной базы
- 2Добавьте новый числовой реквизит с нужной длиной и точностью
- 3Напишите обработку переноса через Число() с логом ошибок
- 4Сверьте контрольные суммы и количество перенесённых значений
- 5Переведите запросы и отчёты на новый реквизит, затем удалите старый
Типичные ошибки и ограничения платформы
Главная ошибка — ожидать от ВЫРАЗИТЬ поведения функции Число(). Вторая по частоте — забыть про региональные разделители: строки «1 234,56» с пробелом-разделителем разрядов и запятой не преобразуются корректно ни одним из способов без предварительной очистки. Третья — игнорировать пустые строки и NULL: агрегаты по результату преобразования внезапно «теряют» часть данных.
Из ограничений платформы стоит помнить: функции ДЛИНАСТРОКИ и ПОДСТРОКА работают в запросе, но нет аналогов СокрЛП, СтрЗаменить в полном объёме и регулярных выражений; вложенность и сложность ВЫБОР-конструкций раздувают текст запроса и замедляют его на больших таблицах; в СКД вычисляемые поля на языке выражений имеют свои отличия от языка запросов.
FAQ
Можно ли в запросе 1С написать аналог функции Число()?
Нет, в языке запросов такой функции не существует. Доступные инструменты — ВЫРАЗИТЬ (только приведение совместимых типов), ПОДСТРОКА, ДЛИНАСТРОКИ и ВЫБОР. Реальное преобразование содержимого строки в число выполняется только во встроенном языке функцией Число().
Что вернёт ВЫРАЗИТЬ(СтроковоеПоле КАК ЧИСЛО(10,2))?
Строка и число несовместимы для приведения, поэтому корректного преобразования не произойдёт: в зависимости от СУБД и контекста вы получите ошибку выполнения запроса либо непригодный результат. Не используйте эту конструкцию для конвертации значений.
Как отсортировать строковые коды «1, 2, 10» в числовом порядке?
Два рабочих приёма: дополнить значения лидирующими нулями до одинаковой длины (тогда строковая сортировка совпадёт с числовой) или вычислить числовой ключ посимвольным разбором через ПОДСТРОКА и ВЫБОР и сортировать по нему.
Как обработать строки с запятой как разделителем дробной части?
В запросе надёжного способа нет. Преобразуйте данные во встроенном языке: предварительно замените запятую на точку через СтрЗаменить, уберите пробелы и разделители разрядов, затем примените Число() внутри Попытка/Исключение.
Что делать со строками, которые не удалось преобразовать?
Не отбрасывайте их молча. Собирайте такие значения в отдельный протокол или таблицу ошибок, чтобы пользователь мог исправить исходные данные. Молчаливый пропуск приводит к расхождениям в отчётах, которые трудно расследовать.
Работает ли посимвольный разбор в СКД?
Да, конструкции ПОДСТРОКА и ВЫБОР допустимы в тексте запроса набора данных СКД, так как это стандартный язык запросов. Но для сложных преобразований удобнее использовать вычисляемые поля СКД или подготовить данные до формирования отчёта.
Что важно запомнить
Прямого преобразования строки в число в языке запросов 1С нет. ВЫРАЗИТЬ приводит типы, но не конвертирует содержимое. Для реальных задач используйте Число() во встроенном языке с передачей результата через временную таблицу, а посимвольный разбор в запросе оставьте для коротких кодов строгого формата. Если строка постоянно используется как число — меняйте тип реквизита.