Разработка и Конфигурация · 12 мин
Как в запросе 1С представить значение как число
Как в запросе 1С представить значение как число: функция ВЫРАЗИТЬ КАК ЧИСЛО, ограничения, приведение строк, типичные ошибки и проверка результата.
В языке запросов 1С нет привычных функций приведения типов вроде CAST или TO_NUMBER из классического SQL. Единственный штатный инструмент, позволяющий «представить как число» значение в запросе, — оператор ВЫРАЗИТЬ(... КАК ЧИСЛО(длина, точность)). Он работает иначе, чем ожидают разработчики с опытом T-SQL: это не преобразование строки «123» в число 123, а приведение значения к числовому типу с заданной разрядностью, причём с жёсткими ограничениями.
Понимание этих ограничений критично: попытка применить ВЫРАЗИТЬ к строке с текстом даст не число, а NULL, а попытка «склеить» число из подстрок потребует совсем других приёмов — вплоть до соединения с таблицей цифр. Ниже разобраны рабочие сценарии: когда ВЫРАЗИТЬ решает задачу, когда нужны обходные пути через СУММА и ВЫБОР, и как проверить результат, прежде чем запрос уйдёт в рабочую базу.
Как работает ВЫРАЗИТЬ КАК ЧИСЛО в запросе 1С
Оператор ВЫРАЗИТЬ в языке запросов 1С выполняет две разные задачи: сужение составного типа (например, оставить из составного поля только ссылки на конкретный справочник) и приведение примитивного типа к нужной разрядности. Для чисел синтаксис выглядит так:
ВЫБРАТЬ
ВЫРАЗИТЬ(Таблица.Количество КАК ЧИСЛО(15, 2)) КАК Количество
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Таблица
Первый параметр в скобках — общая длина числа (максимум 38), второй — количество знаков после запятой. Если исходное значение уже число, оператор просто обрежет или дополнит его до указанной разрядности. Это полезно, когда нужно унифицировать тип поля во временной таблице или в результате объединения: поля с разной точностью в ОБЪЕДИНИТЬ ВСЕ могут конфликтовать, и ВЫРАЗИТЬ приводит их к общему виду.
Важно понимать: ВЫРАЗИТЬ КАК ЧИСЛО корректно обрабатывает значения типа Число, Булево (Истина превращается в 1, Ложь — в 0) и Дата. Строковое значение, даже состоящее из одних цифр, оператор в число не превратит — результатом будет NULL. Это главное отличие от CAST в других СУБД и источник большинства ошибок у начинающих разработчиков.
Типовые сценарии применения
Унификация типа в объединениях и временных таблицах
Самый частый легитимный сценарий — приведение чисел к одинаковой разрядности при объединении выборок. Например, в одном документе количество хранится как ЧИСЛО(15,3), в другом — ЧИСЛО(10,0). Без явного приведения итоговое поле получит составную разрядность, что иногда ломает последующие вычисления и группировки.
ВЫБРАТЬ
ВЫРАЗИТЬ(Продажи.Количество КАК ЧИСЛО(15, 3)) КАК Количество
ПОМЕСТИТЬ Движения
ИЗ Документ.Реализация.Товары КАК Продажи
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ВЫРАЗИТЬ(Возвраты.Количество КАК ЧИСЛО(15, 3))
ИЗ Документ.ВозвратТоваров.Товары КАК Возвраты
Преобразование булева значения в число
ВЫРАЗИТЬ корректно превращает Истину в 1 и Ложь в 0. Это удобно для подсчёта признаков через СУММА без дополнительных конструкций ВЫБОР. Однако тот же результат чаще получают через ВЫБОР КОГДА Условие ТОГДА 1 ИНАЧЕ 0 КОНЕЦ — такой вариант читается однозначнее и не зависит от тонкостей приведения типов на конкретной СУБД.
Округление до нужной точности
Если в расчётах промежуточный результат имеет лишние знаки после запятой, ВЫРАЗИТЬ с меньшей точностью фактически выполняет округление по правилам арифметического округления. Это рабочий способ убрать «хвосты» в валютных суммах, но для явного округления лучше осознанно выбирать точность, а не полагаться на побочный эффект.
Как преобразовать строку с цифрами в число
Задача «строку "00123" представить как число» в чистом запросе решается трудно, потому что язык запросов 1С не содержит функции преобразования строки в число. Есть три практических подхода, и выбор зависит от объёма данных и места использования результата.
Первый и самый надёжный — выгрузить результат запроса и выполнить преобразование средствами встроенного языка: Число(СтрокаЗначение) в цикле по выборке или через Тип("Число"). Если обработка всё равно выполняется в коде, не стоит изобретать сложные запросные конструкции.
Второй подход — разбор строки посимвольно в запросе через ПОДСТРОКА и ВЫБОР. Для каждого разряда извлекается символ, сопоставляется с цифрой и умножается на вес разряда, затем всё суммируется:
ВЫБРАТЬ
ВЫБОР КОГДА ПОДСТРОКА(Данные.Код, 1, 1) = "1" ТОГДА 1
КОГДА ПОДСТРОКА(Данные.Код, 1, 1) = "2" ТОГДА 2
КОГДА ПОДСТРОКА(Данные.Код, 1, 1) = "3" ТОГДА 3
ИНАЧЕ 0 КОНЕЦ * 100
+ ВЫБОР КОГДА ПОДСТРОКА(Данные.Код, 2, 1) = "1" ТОГДА 1
ИНАЧЕ 0 КОНЕЦ * 10 КАК ЧисловоеЗначение
ИЗ Данные КАК Данные
Третий вариант — соединение с таблицей чисел (временной таблицей 0–9) и сборка значения через СУММА с группировкой. Такой приём встречается в публикациях по оптимизации, но он оправдан только при больших объёмах, когда выгрузка в код дороже сложного запроса. Для большинства прикладных задач преобразование в коде проще и прозрачнее.
Как выбрать подход
Приведение типов в параметрах и отборах
Отдельный класс задач — сравнение числового поля с параметром, тип которого заранее неизвестен, или отбор по составному полю. Если передать в параметр строку там, где ожидается число, сравнение не сработает: в запросах 1С значения разных типов не равны, и условие просто не отберёт записей.
Правильное решение — привести тип на стороне кода до передачи параметра: Запрос.УстановитьПараметр("Сумма", Число(ВходноеЗначение)). Если параметр может быть пустым, дополнительно обрабатывайте NULL через ЕСТЬNULL(Поле, 0), иначе арифметика с NULL даст NULL и «съест» строки результата.
В условиях соединения таблиц типы соединяемых полей тоже должны совпадать. Если одно поле — ЧИСЛО(10,0), а другое — ЧИСЛО(15,3), соединение обычно работает, но на некоторых СУБД различия в точности замедляют план выполнения. Явное ВЫРАЗИТЬ к общему типу снимает эту неоднозначность.
Проверка результата и контроль ошибок
После применения ВЫРАЗИТЬ всегда проверяйте три вещи: количество строк в результате, долю NULL-значений в приведённом поле и корректность округления. Самый быстрый способ — временно добавить в запрос агрегатную проверку:
ВЫБРАТЬ
КОЛИЧЕСТВО(*) КАК ВсегоСтрок,
СУММА(ВЫБОР КОГДА ПриведенноеПоле ЕСТЬ NULL ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК СтрокСNULL
Если доля NULL неожиданно велика — значит, в исходном поле есть значения, которые не приводятся к числу, и нужно разбираться с их происхождением, а не маскировать проблему через ЕСТЬNULL. Подмена NULL нулём допустима только там, где нулевое значение бизнес-смысла не искажает: для количества это обычно допустимо, для цены или курса валюты — нет.
Полезно также проверить результат в консоли запросов до переноса текста в модуль. Консоль сразу показывает тип колонки результата — если вместо «Число(15,2)» вы видите составной тип или строку, приведение не сработало так, как задумано.
Как проверить результат
Число с заданной длиной и точностью
Строка, составной тип или неожиданная точность
Числа соответствуют исходным данным, NULL только там, где ожидался
Массовые NULL или обрезанные значения
Совпадает с количеством до приведения
Строки пропали из-за условий или соединений с NULL
Типичные ошибки и ограничения
Главная ошибка — ожидание поведения CAST из T-SQL. Разработчик пишет ВЫРАЗИТЬ(Код КАК ЧИСЛО(10)) для строкового кода «00125», получает NULL и тратит время на поиск «глюка платформы», хотя поведение документировано: строка в число этим оператором не конвертируется.
Вторая частая ошибка — указание длины без учёта знаков после запятой. В ЧИСЛО(15, 2) общая длина 15 включает дробную часть: на целую часть остаётся 13 разрядов. Если значение не помещается, возможно переполнение или ошибка выполнения запроса на уровне СУБД.
Третья группа проблем — попытка применить ВЫРАЗИТЬ к результату агрегатной функции внутри ГДЕ или ИМЕЮЩИЕ без повторного вычисления. Агрегаты фильтруются в ИМЕЮЩИЕ, и приведение типа там тоже допустимо, но конструкция быстро становится нечитаемой; лучше вынести вычисление во временную таблицу.
Альтернативы и смежные приёмы
Когда задача — не приведение, а представление числа в нужном виде (например, вывод суммы с разделителями разрядов), запрос вообще не подходящее место: форматирование выполняется на стороне кода функцией Формат(Значение, "ЧГ=; ЧДЦ=2") или настройками поля компоновки данных. В СКД для поля можно задать форматную строку на закладке «Наборы данных», не меняя сам запрос.
Для сортировки строковых кодов как чисел (чтобы «2» шло раньше «10») применяют либо дополнение строки нулями слева до фиксированной длины, либо вычисляемое числовое поле через описанный выше разбор ПОДСТРОКА. В типовых конфигурациях коды справочников часто уже хранятся с лидирующими нулями именно ради корректной сортировки.
Наконец, если преобразование типов нужно массово и регулярно, задумайтесь о хранении данных в правильном типе изначально: строковое поле, по которому постоянно нужны числовые сравнения, — признак ошибки проектирования, и дешевле один раз изменить структуру, чем годами обходить её в запросах.
Что важно запомнить
ВЫРАЗИТЬ(Поле КАК ЧИСЛО(длина, точность)) — единственный способ представить значение как число в запросе 1С, но он не конвертирует строки. Для строк используйте Число() в коде или посимвольный разбор. Всегда проверяйте долю NULL в результате и корректность разрядности до переноса запроса в рабочий код.
Частые вопросы
Почему ВЫРАЗИТЬ(Строка КАК ЧИСЛО) возвращает NULL?
Потому что оператор ВЫРАЗИТЬ в языке запросов 1С не выполняет преобразование строки в число — он только приводит к числу значения совместимых типов (число, булево, дата). Строка считается несовместимой, и результатом становится NULL. Для строки из цифр используйте функцию Число() встроенного языка после выгрузки запроса.
Какая максимальная длина у ЧИСЛО в запросе?
Максимальная общая длина числа в языке запросов 1С — 38 разрядов, при этом точность (число знаков после запятой) входит в общую длину. На практике разрядность дополнительно ограничена настройками соответствующих полей в конфигурации и возможностями используемой СУБД.
Можно ли округлить число в запросе без ВЫРАЗИТЬ?
Отдельной функции округления в языке запросов нет. Стандартный приём — ВЫРАЗИТЬ с меньшей точностью, который округляет арифметически. Альтернатива — выражение вида ВЫРАЗИТЬ(Значение * 100 + 0.5 КАК ЧИСЛО(15, 0)) / 100 для явного контроля правила округления.
Как отсортировать строковый код как число?
Либо дополните строку лидирующими нулями до фиксированной длины, тогда строковая сортировка совпадёт с числовой, либо вычислите в запросе числовое представление через посимвольный разбор с ПОДСТРОКА и ВЫБОР и сортируйте по нему. Первый вариант проще и быстрее выполняется.
Работает ли ВЫРАЗИТЬ КАК ЧИСЛО в СКД и динамических списках?
Да, оператор доступен везде, где используется язык запросов: в наборах данных СКД, произвольных запросах динамических списков, временных таблицах. Ограничения те же — строки в число не преобразуются, а для отображения числа в нужном формате в СКД лучше использовать форматную строку поля, а не приведение типов.
Что делать, если после приведения появились NULL в расчётах?
Сначала выясните происхождение NULL: либо в исходном поле были нечисловые значения, либо NULL пришёл из соединения таблиц. Используйте ЕСТЬNULL(Поле, 0) только там, где нулевое значение не искажает смысл данных. Для диагностики добавьте в запрос подсчёт строк с NULL и сравните с ожиданиями.