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

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

При расчете цен, скидок, сумм к выплате или параметров логистики разработчикам регулярно приходится решать задачу приведения чисел к определенному шагу (кратности). Например, требуется округлить сумму 183 до ближайшего числа, кратного 5 в большую сторону (получив 185), либо округлить число 192 до 195. Стандартная функция платформы Окр() предназначена только для округления до заданного десятичного разряда, поэтому для произвольной кратности требуется применять специальные формулы и функции.

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

Вариант 1. Базовый математический принцип «разделить — округлить — умножить»

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

Результат = Окр(ИсходноеЧисло / Кратность, 0) * Кратность;

Если же стоит задача округлить число всегда в большую сторону (например, в пользу предприятия), простая прибавка 0.5 вида Окр(Сумма / 5 + 0.5) * 5 содержит скрытую ошибку: число, которое уже кратно 5 (например, 190), превратится в 195. Чтобы избежать этого, перед округлением необходимо проверять кратность либо использовать функцию Цел() с вычитанием минимальной погрешности.

Вариант 2. Быстрое округление вверх через функцию Цел()

Рассмотрим лаконичную формулу, которая позволяет округлить положительное число строго вверх до нужного шага без ветвлений Если ... Тогда:


Результат = Цел((ИсходноеЧисло + Кратность - 0.000000001) / Кратность) * Кратность;

Посмотрим на логику работы формулы:

  1. Если исходное число равно 183, а кратность 5: Цел((183 + 5 - 0.000000001) / 5) * 5 = Цел(187.999999999 / 5) * 5 = Цел(37.5999999) * 5 = 37 * 5 = 185.
  2. Если исходное число уже кратно шагу (например, 190): Цел((190 + 5 - 0.000000001) / 5) * 5 = Цел(194.999999999 / 5) * 5 = Цел(38.9999999) * 5 = 38 * 5 = 190. Число остается неизменным.

Вариант 3. Универсальная функция с использованием операции остатка от деления

Для создания гибкого и читаемого кода в модулях конфигурации рекомендуется использовать универсальную функцию. Она обрабатывает четыре основных режима: математическое округление (с направлением 0.5 вверх или вниз), округление строго вниз (в пользу покупателя) и строго вверх (в пользу продавца).

Разберем реализацию функции:


Функция ОкруглитьДоКратности(ИсходноеЧисло, РазрядОкругления = 1, РежимОкругления = 1) Экспорт
    
    // Если число уже кратно шагу, возвращаем его без изменений
    ОстатокОтДеления = ИсходноеЧисло % РазрядОкругления;
    Если ОстатокОтДеления = 0 Тогда 
        Возврат ИсходноеЧисло;
    КонецЕсли;
    
    Если РежимОкругления = 1 Тогда
        // Обычный по математическим правилам (0.5 вверх)
        Результат = ИсходноеЧисло - ?(ОстатокОтДеления >= (РазрядОкругления / 2), -РазрядОкругления + ОстатокОтДеления, ОстатокОтДеления);
    ИначеЕсли РежимОкругления = 2 Тогда
        // Обычный по математическим правилам (0.5 вниз)
        Результат = ИсходноеЧисло - ?(ОстатокОтДеления > (РазрядОкругления / 2), -РазрядОкругления + ОстатокОтДеления, ОстатокОтДеления);
    ИначеЕсли РежимОкругления = 3 Тогда
        // Всегда в меньшую сторону (к полу)
        Результат = ИсходноеЧисло - ОстатокОтДеления;
    ИначеЕсли РежимОкругления = 4 Тогда
        // Всегда в большую сторону (к потолку)
        Результат = ИсходноеЧисло - ОстатокОтДеления + РазрядОкругления;
    КонецЕсли;
    
    Возврат Результат;
    
КонецФункции

Посмотрим на примеры вызова данной функции:


// Округление вверх до 5: возвращает 185
Сумма1 = ОкруглитьДоКратности(183, 5, 4); 

// Округление вверх уже кратного числа: возвращает 190
Сумма2 = ОкруглитьДоКратности(190, 5, 4); 

// Округление вниз до 10: возвращает 190
Сумма3 = ОкруглитьДоКратности(197, 10, 3);

Вариант 4. Округление до кратности в тексте запроса 1С

В языке запросов платформы 1С оператор взятия остатка от деления % и функция Цел() отсутствуют. Приведение к целому через ВЫРАЗИТЬ(... КАК ЧИСЛО(15, 0)) выполняет стандартное арифметическое округление. Для вычисления кратности вверх в запросе применяется конструкция ВЫБОР КОГДА:


ВЫБОР
    КОГДА Таблица.Сумма / &Кратность = ВЫРАЗИТЬ(Таблица.Сумма / &Кратность КАК ЧИСЛО(15, 0))
        ТОГДА Таблица.Сумма
    КОГДА Таблица.Сумма / &Кратность > ВЫРАЗИТЬ(Таблица.Сумма / &Кратность КАК ЧИСЛО(15, 0))
        ТОГДА (ВЫРАЗИТЬ(Таблица.Сумма / &Кратность КАК ЧИСЛО(15, 0)) + 1) * &Кратность
    ИНАЧЕ (ВЫРАЗИТЬ(Таблица.Сумма / &Кратность КАК ЧИСЛО(15, 0))) * &Кратность
КОНЕЦ

Важные практические нюансы

  1. Работа с отрицательными числами: Обратите внимание, что стандартная функция Цел() в платформе 1С отбрасывает дробную часть по направлению к нулю (Цел(-1.8) = -1). Если в расчетах могут появиться отрицательные числа (например, корректировки или скидки), округление следует производить по модулю через функцию Abs() / Число < 0, либо явно контролировать знак.
  2. Типовые конфигурации (ERP, КА, УТ, Розница): В типовых решениях механизм правил округления цен уже реализован в подсистеме ценообразования (справочник порядков округления). Перед разработкой собственного алгоритма проверьте наличие типовых методов в общих модулях ценообразования.
  3. Округление строк документов и НДС: При построчном округлении цен в табличной части итоговая сумма документа при умножении на количество может разойтись с расчетом контрагента. В розничной торговле округление итоговой суммы чека в пользу продавца также может быть ограничено правилами защиты прав потребителей.
← На главную