Разработка и Конфигурация · 10 мин
1С 8: как выразить значение как число в запросе
Как использовать ВЫРАЗИТЬ КАК ЧИСЛО в запросе 1С 8: синтаксис, длина и точность, приведение строк в число, обрезание дробной части, типичные ошибки и примеры.
Функция ВЫРАЗИТЬ в языке запросов 1С 8 приводит значение поля к указанному типу данных. Конструкция ВЫРАЗИТЬ(Поле КАК ЧИСЛО(длина, точность)) используется, когда нужно сменить тип поля, обрезать дробную часть, привести строковое представление числа к числовому типу или убрать лишнюю разрядность перед сравнением и группировкой.
Типичные ситуации: реквизит хранится как строка, а по нему нужно считать сумму; число имеет слишком большую точность и мешает соединению таблиц; значение составного типа нужно жёстко зафиксировать как число, чтобы оптимизатор запроса построил эффективный план. Во всех этих случаях приведение типа выполняется прямо в тексте запроса, без обращения к коду на встроенном языке.
Важно понимать ограничение: ВЫРАЗИТЬ не выполняет «умный» разбор строки. Если строковое поле содержит нечисловые символы, результат зависит от СУБД и настроек, чаще всего это будет NULL или ошибка выполнения запроса. Поэтому перед приведением строк стоит убедиться, что данные чистые, либо обрабатывать их предварительно.
Синтаксис ВЫРАЗИТЬ КАК ЧИСЛО
Общий вид конструкции:
ВЫРАЗИТЬ(Выражение КАК ЧИСЛО(Длина, Точность))
Параметр Длина задаёт общее количество цифр в числе, включая знаки после запятой. Параметр Точность — количество знаков дробной части. Например, ЧИСЛО(15, 2) означает число длиной до 15 цифр, из которых 2 — после запятой. Если точность не указана, используется ЧИСЛО(Длина), то есть целое число.
Простейший пример — приведение строкового реквизита к числу:
ВЫБРАТЬ
ВЫРАЗИТЬ(Товары.АртикулСтрокой КАК ЧИСЛО(10, 0)) КАК АртикулЧисло
ИЗ
Справочник.Товары КАК Товары
Если значение не помещается в указанную длину, поведение зависит от СУБД: чаще всего лишние разряды дробной части отсекаются, а переполнение целой части приводит к ошибке или NULL. Поэтому длину разумно задавать с запасом относительно реальных данных.
Обрезание дробной части и округление
Частая задача — отбросить копейки или лишние знаки после запятой. Для этого поле выражают как число с меньшей точностью:
ВЫБРАТЬ
ВЫРАЗИТЬ(Продажи.Сумма КАК ЧИСЛО(15, 0)) КАК СуммаБезКопеек
ИЗ
РегистрНакопления.Продажи КАК Продажи
Здесь дробная часть просто отсекается — это не математическое округление. Значение 123,99 превратится в 123, а не в 124. Если нужно именно округление, применяют приём с добавлением 0,5 перед приведением:
ВЫРАЗИТЬ(Продажи.Сумма + 0.5 КАК ЧИСЛО(15, 0))
Такой приём работает для положительных чисел. Для отрицательных значений логика сложнее: корректнее выполнять округление в коде на встроенном языке функцией Окр() уже после получения результата запроса, если точность критична для расчётов.
Приведение строки к числу
Когда числовые данные хранятся в строковых реквизитах (например, после обмена или загрузки из Excel), их можно привести к числу прямо в запросе:
ВЫБРАТЬ
ВЫРАЗИТЬ(Данные.ЗначениеСтрокой КАК ЧИСЛО(15, 2)) КАК ЗначениеЧисло
ИЗ
РегистрСведений.ЗагруженныеДанные КАК Данные
Приведение сработает корректно только если строка содержит число в ожидаемом формате: без пробелов, букв, разделителей тысяч и с правильным разделителем дробной части. Строки вида «1 200,50» или «12шт» дадут NULL либо вызовут ошибку в зависимости от платформы и СУБД.
Практическая рекомендация — очищать данные на этапе загрузки: убирать пробелы и нечисловые символы средствами встроенного языка (СтрЗаменить, регулярные проверки через СтрЧислоВхождений или перебор символов), а в запросе выполнять только финальное приведение типа.
Приведение типов в соединениях и условиях
Приведение к числу часто нужно для корректного соединения таблиц, когда в одной таблице поле числовое, а в другой — строковое или составного типа:
ВЫБРАТЬ
Заказы.Номер,
Оплаты.Сумма
ИЗ
Документ.ЗаказПокупателя КАК Заказы
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Оплаты КАК Оплаты
ПО Заказы.КодОплаты = ВЫРАЗИТЬ(Оплаты.КодСтрокой КАК ЧИСЛО(10, 0))
Учтите: приведение типа в условии соединения обычно мешает использованию индексов, и на больших таблицах запрос может выполняться заметно дольше. Если такое соединение используется постоянно, правильнее привести типы данных в самой конфигурации или создать промежуточную временную таблицу с уже приведёнными значениями.
В условиях ГДЕ приведение тоже допустимо, но с тем же ограничением по производительности. Сравнение ГДЕ ВЫРАЗИТЬ(Поле КАК ЧИСЛО(10, 0)) > 100 заставит СУБД вычислять выражение для каждой строки.
Если приведение типа нужно в условии соединения или отбора и таблица большая, сначала поместите приведённые данные во временную таблицу, проиндексируйте её и соединяйтесь уже с ней. Это заметно сокращает время выполнения запроса.
Работа с составными типами и NULL
Если реквизит имеет составной тип (например, «Число или Строка»), ВЫРАЗИТЬ КАК ЧИСЛО зафиксирует тип поля результата как числовой. Значения, которые не являются числами, превратятся в NULL. Это удобно для последующей агрегации: функции СУММА, СРЕДНЕЕ корректно работают с числовым типом и игнорируют NULL.
Чтобы вместо NULL получить ноль, оберните выражение в ЕСТЬNULL:
ВЫБРАТЬ
ЕСТЬNULL(ВЫРАЗИТЬ(Данные.Показатель КАК ЧИСЛО(15, 2)), 0) КАК Показатель
ИЗ
РегистрСведений.Показатели КАК Данные
Порядок вложения важен: сначала приведение типа, затем подмена NULL. Обратная последовательность бессмысленна, потому что ЕСТЬNULL не меняет тип значения.
- 1Определите исходный тип поля: строка, составной тип или число с избыточной точностью
- 2Подберите параметры ЧИСЛО(Длина, Точность) с запасом по разрядности
- 3Напишите выражение ВЫРАЗИТЬ(Поле КАК ЧИСЛО(...)) и при необходимости оберните в ЕСТЬNULL(..., 0)
- 4Выполните запрос в консоли запросов и проверьте, что значения не превратились в NULL неожиданно
- 5Проверьте итоговые суммы и время выполнения на реальном объёме данных
Проверка результата и типичные ошибки
После написания запроса результат стоит проверить в консоли запросов на копии базы. Контролируйте три вещи: тип колонки результата, отсутствие неожиданных NULL и корректность итоговых сумм. Если итоги «похудели» после добавления приведения типа — почти наверняка часть значений не привелась и ушла в NULL.
Наиболее частые ошибки при использовании ВЫРАЗИТЬ КАК ЧИСЛО:
Отдельно отметим: ВЫРАЗИТЬ не умеет превращать ссылку в число или извлекать код из ссылки. Если нужен числовой код элемента справочника, обращайтесь к реквизиту Код и приводите уже его, либо меняйте тип кода в конфигураторе.
Как проверить результат
Колонка имеет тип Число с заданной длиной и точностью
Тип остался строковым или составным — приведение не применилось
Числа соответствуют исходным данным, NULL только там, где исходное значение было пустым
Массовые NULL на заполненных строках — данные содержат нечисловые символы
Суммы совпадают с контрольным расчётом без приведения
Итоги уменьшились — часть значений потеряна при приведении
Альтернативы приведению в запросе
Не всегда приведение типа нужно делать именно в запросе. Если значение требуется обработать один раз, проще получить выборку и преобразовать значения в коде функциями Число(), Окр() или Формат() — там доступна и обработка исключений, и полноценное округление.
Если приведение нужно постоянно и в разных отчётах, правильное решение — изменить тип реквизита в конфигураторе или добавить отдельный числовой реквизит, заполняемый при записи. Это убирает нагрузку на запросы и позволяет использовать индексы. ВЫРАЗИТЬ КАК ЧИСЛО остаётся инструментом для разовых выборок, временных таблиц и ситуаций, где менять структуру метаданных нельзя.
Что важно запомнить
ВЫРАЗИТЬ(Поле КАК ЧИСЛО(Длина, Точность)) приводит значение к числу, отсекая дробную часть без округления. Строки должны содержать чистое число, иначе получите NULL. Для подмены NULL используйте ЕСТЬNULL, для округления — добавление 0,5 или функцию Окр() в коде, а в соединениях больших таблиц применяйте временные таблицы.
Частые вопросы
Чем ВЫРАЗИТЬ КАК ЧИСЛО отличается от функции Число() во встроенном языке?
ВЫРАЗИТЬ работает на стороне СУБД внутри запроса и применяется ко всем строкам выборки сразу. Функция Число() выполняется в коде 1С для отдельного значения и позволяет перехватить ошибку через Попытка/Исключение. В запросе — ВЫРАЗИТЬ, при построчной обработке в коде — Число().
Как округлить число до двух знаков в запросе?
Прямой функции округления в языке запросов нет. Приём: умножьте значение на 100, добавьте 0,5, приведите к ЧИСЛО(15, 0) и разделите на 100. Для отрицательных чисел этот приём некорректен — используйте Окр() в коде после выполнения запроса.
Почему после ВЫРАЗИТЬ КАК ЧИСЛО появились NULL?
Наиболее вероятная причина — исходные строки содержат нечисловые символы: пробелы, буквы, разделители тысяч или другой разделитель дробной части. Отберите записи, где приведённое значение ЕСТЬ NULL, а исходное поле заполнено, — это и есть проблемные данные.
Какие значения длины и точности указывать?
Ориентируйтесь на реальные данные с запасом: для денежных сумм обычно достаточно ЧИСЛО(15, 2), для количеств — ЧИСЛО(15, 3). Слишком маленькая длина приведёт к переполнению, избыточная безопасна, но не влияет на точность хранения исходных данных.
Можно ли привести ссылку на документ к числу через ВЫРАЗИТЬ?
Нет. ВЫРАЗИТЬ не преобразует ссылочные типы в число. Если нужен числовой идентификатор, используйте реквизиты объекта (Номер, Код) с последующим приведением, либо обрабатывайте ссылку средствами встроенного языка.
Влияет ли ВЫРАЗИТЬ на скорость запроса?
В списке выборки влияние минимально. В условиях соединения и отбора приведение типа мешает СУБД использовать индексы, и на больших таблицах запрос может замедлиться в разы. В таких случаях выносите приведённые значения во временную таблицу с индексом.