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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с числовыми данными в запросах платформы 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда результатом деления или вычисления средних величин становится число с избыточной точностью. Например, вместо ожидаемых двух или трех знаков после запятой СУБД возвращает длинную дробь вида 0.948545632894753533. Это не только перегружает интерфейс отчета, но и усложняет восприятие информации пользователями.

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

Решение №1: Использование конструкции ВЫРАЗИТЬ в языке запросов

Для явного приведения типов и ограничения разрядности чисел в языке запросов 1С предусмотрена стандартная конструкция ВЫРАЗИТЬ. Она позволяет округлить исходное дробное число до нужного количества знаков после запятой по общепринятым математическим правилам.

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


ВЫБОР
    КОГДА ЕСТЬNULL(ПростойОборудования.ИтогоПростой, 0) > 0
        ТОГДА ОборудованиеСправочник.КоличествоЧасовРаботы / ПростойОборудования.ИтогоПростой
    ИНАЧЕ 0
КОНЕЦ

Чтобы ограничить точность результата деления тремя знаками после запятой, нам необходимо обернуть саму математическую операцию деления в функцию ВЫРАЗИТЬ. Посмотрим на правильную реализацию этой конструкции:


ВЫБОР
    КОГДА ЕСТЬNULL(ПростойОборудования.ИтогоПростой, 0) > 0
        ТОГДА ВЫРАЗИТЬ(ОборудованиеСправочник.КоличествоЧасовРаботы / ПростойОборудования.ИтогоПростой КАК ЧИСЛО(15, 3))
    ИНАЧЕ 0
КОНЕЦ

Обратите внимание на важную деталь: функция ВЫРАЗИТЬ применяется именно к результату математической операции (деления), а не ко всей конструкции ВЫБОР ... КОНЕЦ. Попытка поместить все условие внутрь функции приведения типов приведет к синтаксической ошибке в конструкторе запросов.

Важные правила работы с типом ЧИСЛО(Длина, Точность)

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

  1. Общая длина числа: Первый параметр — Длина (в нашем примере — 15) — определяет общее количество знаков в числе, включая как целую часть до запятой, так и дробную часть после нее.
  2. Точность дробной части: Второй параметр — Точность (в нашем примере — 3) — определяет жесткое количество знаков, которое будет оставлено после запятой.
  3. Опасность переполнения: Если реальное число превысит допустимую длину целой части, СУБД сгенерирует критическую ошибку арифметического переполнения. Рассчитать максимальное значение целой части можно по формуле: Длина - Точность. Например, для типа ЧИСЛО(5, 2) максимальное число, которое система сможет обработать, составляет всего 999.99. Если в результате расчетов получится 1000.00, произойдет сбой системы.

Именно поэтому мы рекомендуем всегда закладывать общую длину числа с запасом. Использование параметров вроде ЧИСЛО(15, 2) или ЧИСЛО(15, 3) является наиболее безопасным стандартом разработки в 1С.

Особенности округления во временных таблицах (ПОМЕСТИТЬ)

Давайте проанализируем поведение платформы при работе с временными таблицами. Многие разработчики замечают, что при записи результатов расчета во временную таблицу с помощью инструкции ПОМЕСТИТЬ, СУБД самостоятельно обрезает дробные числа до 8 знаков после запятой.

Выясним причину этого явления. Когда платформа 1С транслирует запрос к СУБД для создания временной таблицы, она должна явно определить типы полей создаваемой таблицы. Если колонка является результатом математического деления двух чисел и для нее не задан тип вручную, СУБД по умолчанию выделяет под нее числовой тип с фиксированной точностью в 8 знаков после запятой.

Если для бизнес-логики вашего приложения критически важна более высокая точность расчетов внутри временных таблиц (например, при сложных финансовых или технологических калькуляциях), вам необходимо явно указывать желаемую точность с помощью функции ВЫРАЗИТЬ еще на этапе первого запроса пакета, до помещения данных во временную таблицу.

Нестандартные варианты округления в запросах 1С

Оператор ВЫРАЗИТЬ всегда выполняет стандартное математическое округление (значения от 0.5 округляются в большую сторону). Однако в реальной практике нередко возникают задачи, требующие усечения («отрезания») лишних знаков без математического округления вверх либо, наоборот, всегда округления в большую сторону.

Поскольку в языке запросов 1С отсутствуют специализированные математические функции вроде ОКР(), ЦЕЛОЕ() или ВВЕРХ(), мы можем решить эти задачи с помощью несложных арифметических алгоритмов.

1. Округление в меньшую сторону («вниз» или усечение дробной части)

Чтобы отсечь знаки после запятой без округления в большую сторону, мы можем искусственно сместить число в меньшую сторону перед применением функции ВЫРАЗИТЬ. Для этого из исходного значения вычитается половина единицы младшего сохраняемого разряда.

Важное замечание: Данный метод корректно работает для положительных чисел. Если ваше поле может содержать отрицательные значения, логику смещения необходимо делать зеркальной, используя конструкцию ВЫБОР КОГДА.

2. Округление в большую сторону («вверх»)

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

ВЫРАЗИТЬ(Таблица.КоличествоУпаковок + 0.4999999999 КАК ЧИСЛО(15, 0))

Решение №2: Использование условного оформления в СКД

Вторым мощным инструментом борьбы с избыточной точностью дробных чисел является использование механизмов Системы компоновки данных. Если округленное число требуется только для вывода на экран пользователю и не участвует в последующих расчетах, правильнее наложить маску отображения.

Давайте пошагово рассмотрим, как настроить округление в интерфейсе СКД:

  1. Откройте схему компоновки данных вашего отчета.
  2. Перейдите на вкладку «Наборы данных».
  3. В таблице «Поля» найдите нужное числовое поле, разрядность которого необходимо ограничить.
  4. В колонке «Оформление» нажмите на кнопку выбора.
  5. В открывшемся окне параметров оформления найдите строку «Формат» и перейдите к его редактированию.
  6. В конструкторе форматной строки укажите параметр «ЧДЦ» (Число десятых знаков) и задайте его значение (например, 2 или 3). Платформа автоматически сгенерирует форматную строку вида ЧДЦ=3.

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

Сравнение подходов: Округление в запросе против СКД

Выбор места округления чисел — это не просто дело вкуса программиста, а серьезное архитектурное решение. Давайте детально проанализируем, в каких ситуациях следует применять каждый из подходов.

Рассмотрим классическую проблему расхождения копеек при суммировании округленных данных на практическом примере.

Предположим, в нашей базе данных хранятся две строки со значениями 1.4 и 1.4.

Сценарий А: Округление выполнено физически в запросе

Если мы применим функцию ВЫРАЗИТЬ(Число КАК ЧИСЛО(15, 0)) в тексте запроса, система вернет нам жестко округленные целые числа:

При расчете итогов (суммы) отчет послушно сложит эти значения и вернет результат: 2. Математическая логика отчета с точки зрения пользователя будет идеальной: 1 + 1 = 2. Однако реальная сумма данных в базе (2.8) в этот отчет не попадет, мы безвозвратно потеряли точность.

Сценарий Б: Округление выполнено визуально через формат СКД

Если мы оставим числа в запросе нетронутыми, а округление до целого настроим через формат вывода в СКД, расчеты будут происходить по следующему алгоритму:

В результате на экране появится таблица, в которой строки равны 1 и 1, а итоговая сумма равна 3. Это вызовет массу вопросов у пользователей и аудиторов, проверяющих отчеты.

Подведем краткий итог по выбору архитектуры округления:

Обработка значений NULL и пустых полей

Завершая разбор работы с дробными числами, нельзя обойти стороной проблему обработки пустых значений. Если в вашем запросе происходит деление полей, которые физически могут содержать значение NULL (например, при использовании левых соединений таблиц), применение функции ВЫРАЗИТЬ к результату деления без предварительной проверки приведет к аварийному завершению работы программы.

Перед округлением всегда используйте функцию ЕСТЬNULL для замены неопределенных значений на числовой ноль или единицу. Давайте посмотрим на эталонный пример безопасного округления:


ВЫРАЗИТЬ(ЕСТЬNULL(Таблица.СуммаДокумента, 0) / ЕСТЬNULL(Таблица.КурсВалюты, 1) КАК ЧИСЛО(15, 2))

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

← На главную