Как реализовать Math.ceil() (округление вверх) в запросе 1С?

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

При написании запросов в платформе «1С:Предприятие» разработчики часто сталкиваются с ограничениями встроенного языка запросов по сравнению с полноценным SQL или языками высокого уровня (такими как Java или C#). Одной из таких проблем является отсутствие стандартной функции округления числа до ближайшего большего целого (вверх), которая в других языках представлена как Math.ceil() или CEILING().

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

Вариант 1. Современное и надежное решение (для платформ 8.3.20 и выше)

Начиная с версии платформы 8.3.20, в язык запросов 1С были добавлены встроенные математические функции, включая ЦЕЛ() (получение целой части числа путем отсечения дроби) и ОКР() (округление по математическим правилам).

Благодаря функции ЦЕЛ(), больше не нужно использовать неточные дробные прибавки. Мы можем реализовать полноценный и математически точный аналог Math.ceil() для любых чисел (положительных, отрицательных и целых) с помощью простого ветвления:


ВЫБРАТЬ
    ВЫБОР
        КОГДА ЦЕЛ(Таблица.ИсходноеЧисло) = Таблица.ИсходноеЧисло 
            ТОГДА Таблица.ИсходноеЧисло
        КОГДА Таблица.ИсходноеЧисло > 0 
            ТОГДА ЦЕЛ(Таблица.ИсходноеЧисло) + 1
        ИНАЧЕ ЦЕЛ(Таблица.ИсходноеЧисло)
    КОНЕЦ КАК РезультатОкругленияВверх
ИЗ
    РегистрСведений.НашиДанные КАК Таблица

Проанализируем, как работает этот алгоритм:

  1. Если исходное число уже является целым (например, 5.0 или -3.0), условие равенства выполняется, и запрос возвращает число без изменений.
  2. Если мы передаем положительное дробное число (например, 5.1), функция ЦЕЛ() возвращает 5. Так как число больше нуля, мы прибавляем единицу и получаем верный результат: 6.
  3. Если мы передаем отрицательное дробное число (например, -3.1), функция ЦЕЛ() просто отсекает дробную часть, возвращая -3. Математически число -3 больше, чем -3.1, поэтому для отрицательного диапазона это и есть округление вверх.

Вариант 2. Классический способ для старых платформ (через ВЫРАЗИТЬ и ВЫБОР)

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

Рассмотрим следующий рабочий шаблон запроса:


ВЫБРАТЬ
    ВЫБОР
        КОГДА ВЫРАЗИТЬ(Таблица.ИсходноеЧисло КАК ЧИСЛО(15, 0)) = Таблица.ИсходноеЧисло 
            ТОГДА Таблица.ИсходноеЧисло
        ИНАЧЕ ВЫРАЗИТЬ(Таблица.ИсходноеЧисло + 0.5 КАК ЧИСЛО(15, 0))
    КОНЕЦ КАК Ceil
ИЗ
    РегистрСведений.НашиДанные КАК Таблица

Разберем логику работы этого выражения по шагам:

Вариант 3. Краткий способ с использованием дельты

Иногда разработчики хотят избежать громоздких конструкций ВЫБОР...КОНЕЦ и стремятся написать максимально короткий код. Для этого можно прибавить к числу константу, чуть меньшую 0.5 (например, 0.4999999999):


ВЫБРАТЬ
    ВЫРАЗИТЬ(Таблица.ИсходноеЧисло + 0.4999999999 КАК ЧИСЛО(15, 0)) КАК Ceil
ИЗ
    РегистрСведений.НашиДанные КАК Таблица

Важное предупреждение: этот способ выглядит самым простым, однако он имеет скрытые недостатки:

Альтернативные варианты решения

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

← На главную