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