При расчете отпускных цен, скидок или формировании итоговых сумм в документах часто возникает задача округлить число не до стандартных сотых или целых единиц, а до определенного шага — например, чтобы цена всегда оканчивалась на 0 или 5 (числа 127.67 округлялись до 130, а 127.4 — до 125). Разберем по шагам, какими способами можно реализовать такое округление во встроенном языке 1С и в запросах.
Математический принцип округления до произвольного шага строится на трех действиях: мы делим исходное число на шаг округления (в нашем случае 5), округляем результат до целого по стандартным правилам математики и затем умножаем обратно на величину шага.
Посмотрим на пример реализации в коде 1С:
// Исходные данные
ИсходноеЧисло1 = 127.67;
ИсходноеЧисло2 = 127.4;
ШагОкругления = 5;
// Выполняем расчет
Результат1 = Окр(ИсходноеЧисло1 / ШагОкругления) * ШагОкругления; // Получим 130
Результат2 = Окр(ИсходноеЧисло2 / ШагОкругления) * ШагОкругления; // Получим 125
Проанализируем, как работает эта формула:
25.534. Функция Окр(25.534) возвращает 26. При умножении 26 * 5 получаем итоговое значение 130.25.48. Функция Окр(25.48) возвращает 25. При умножении 25 * 5 получаем итоговое значение 125.Рассмотрим подробнее поведение формулы на граничных значениях, когда дробная часть делителя равна ровно 0.5 (например, для числа 127.5 деление на 5 дает ровно 25.5). В платформе 1С функция Окр() принимает третий параметр — системное перечисление РежимОкругления:
РежимОкругления.Окр15как20 (применяется по умолчанию) — значение 0.5 округляется в большую сторону по модулю. В таком случае Окр(127.5 / 5, 0, РежимОкругления.Окр15как20) * 5 вернет 130.РежимОкругления.Окр15как10 — значение 0.5 округляется в меньшую сторону по модулю. В таком случае Окр(127.5 / 5, 0, РежимОкругления.Окр15как10) * 5 вернет 125.Посмотрим на программный пример вызова с явным указанием режима:
Цена = 127.5;
ОкругленнаяЦена = Окр(Цена / 5, 0, РежимОкругления.Окр15как20) * 5;
В торговых операциях и ценообразовании нередко требуется не классическое математическое округление, а строго направленное — «в пользу покупателя» (всегда вниз) или «в пользу предприятия» (всегда вверх).
Разберем, как реализовать такие правила с помощью функции Цел():
Шаг = 5;
Число = 127.4;
// Округление всегда вниз (в меньшую сторону)
ЦенаВниз = Цел(Число / Шаг) * Шаг; // Вернет 125
// Округление всегда вверх (в большую сторону)
ЦенаВверх = ?(Число % Шаг = 0, Число, (Цел(Число / Шаг) + 1) * Шаг); // Вернет 130
Важный момент: функция Цел() отбрасывает дробную часть по направлению к нулю. Если вы работаете с отрицательными числами (например, при расчете корректировок цен или скидок), учитывайте влияние знака на результат вычислений.
В языке запросов 1С отсутствует встроенная функция ОКР(). Если вам требуется выполнить расчет и округление цен непосредственно в выборке данных СУБД, используйте приведение типов через конструкцию ВЫРАЗИТЬ.
Посмотрим на пример фрагмента запроса:
ВЫБРАТЬ
Товары.Номенклатура КАК Номенклатура,
ВЫРАЗИТЬ(Товары.Цена / 5 КАК ЧИСЛО(15, 0)) * 5 КАК ЦенаОкругленная
ИЗ
Справочник.Номенклатура КАК Товары
Обратите внимание на особенности работы с запросами:
ВЫРАЗИТЬ(... КАК ЧИСЛО(15, 0)) на уровне СУБД может использовать банковское округление (округление половины к ближайшему четному числу).Если вы настраиваете расчет отпускных цен в типовых решениях (1С:ERP, 1С:Комплексная автоматизация, 1С:Управление торговлей или 1С:УНФ), писать собственный программный код не требуется. В типовом функционале подсистемы ценообразования предусмотрен специальный справочник правил округления цен, в котором можно настроить: