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

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

В практике разработчика 1С нередко возникают задачи, выходящие за рамки стандартного школьного округления. Одной из таких задач является округление «вверх» до определенного порога или кратности. Например, когда клиент требует, чтобы любое значение, превышающее целое число (даже на копейку), превращалось в следующую тысячу: 2001 должно стать 3000, а 2100 — также 3000. В этой статье мы разберем, зачем это нужно бизнесу и как технически реализовать такие алгоритмы в коде 1С.

Бизнес-логика: почему клиенты просят «странное» округление

Прежде чем переходить к написанию кода, проанализируем ситуацию и выясним причину таких запросов. Округление «в пользу продавца» — это не всегда попытка обмануть покупателя, зачастую это жесткая необходимость, продиктованная особенностями учета или физическими свойствами товара.

  1. Логистические единицы (кванты поставки): Если товар отпускается только целыми коробками или паллетами, система должна округлить заказ клиента вверх. Если покупателю нужно 2.1 коробки плитки, склад все равно выдаст 3 целых коробки, так как вскрывать заводскую упаковку запрещено.
  2. Учет материалов (обрезь и брак): При расчете погонных метров (ткани, линолеума, металлопроката) или листовых материалов всегда возникают остатки, которые невозможно использовать повторно. Программа должна закладывать это в стоимость, округляя расчетное количество до целой единицы закупки.
  3. Биллинг услуг: В аренде техники или почасовой оплате консультаций часто применяется правило «любой начатый час оплачивается как полный». Это классический пример трансформации «1 час 5 минут» в «2 часа».
  4. Коммерческие предложения: Часто продавцы округляют итоговые суммы до «красивых» чисел (тысяч или сотен), чтобы упростить восприятие цены или заложить в этот «хвост» возможные дополнительные расходы на логистику.

Метод 1: Использование функции Окр() со смещением

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

Стандартная функция Окр() работает по правилам арифметики. Чтобы «заставить» её всегда округлять вверх до тысяч, мы можем прибавить к числу 499 (или 500 в зависимости от точности) перед округлением. Разберем пример кода:


// Округление до ближайшей 1000 вверх
// Если Цена = 2100, то Результат будет 3000
// Если Цена = 2000, то Результат останется 2000
Цена = 2100;
Результат = Окр(Цена + 499, -3); 

В данном примере параметр -3 указывает функции Окр(), что округление происходит до сотен (три знака до запятой). Прибавление 499 гарантирует, что любое число от 2001 до 2500 перешагнет порог, при котором стандартное округление отправило бы его вверх.

Метод 2: Округление материалов через добавление коэффициента

Проанализируем ситуацию с расчетом материалов. Бывает необходимо реализовать логику, когда, например, значение 1.3 превращается в 2, а 1.299 остается единицей. Это часто используется при расчете «квантов» материала.

Для этого можно использовать простую формулу с добавлением дробного коэффициента:


// КвантыЦелые = Окр(КвантыРасчетные + КоэффициентСдвига)
// Например, при Коэффициенте = 0.3
РасчетноеКоличество = 1.3;
ИтоговоеКоличество = Цел(РасчетноеКоличество + 0.7); // Получим 2

Однако более универсальным и надежным способом реализации функции «Потолок» (Ceiling) в 1С является использование отрицательного преобразования с функцией Цел().

Метод 3: Реализация функции «Потолок» (Ceiling)

В большинстве языков программирования есть встроенная функция Ceil(), которая возвращает ближайшее целое число, которое больше или равно заданному. В классическом 1С такой функции долгое время не было в явном виде. Посмотрим на элегантный способ её реализации через отрицательные числа:


// Функция всегда округляет вверх до целого
ЧислоДляОкругления = 2.1;
Результат = -Цел(-ЧислоДляОкругления); // Получим 3

Как это работает? Проанализируем пошагово:

  1. Берем число 2.1, превращаем в -2.1.
  2. Функция Цел(-2.1) отсекает дробную часть и возвращает -2 (так как это ближайшее целое в сторону нуля).
  3. Меняем знак обратно: -(-2) = 2.

Важное замечание: Чтобы округление всегда шло именно в большую сторону (от 2.1 к 3), данный метод нужно комбинировать с проверкой остатка или использовать формулу кратности.

Метод 4: Округление до произвольной кратности (Шаг округления)

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


// Результат = Цел((Значение + Шаг - 0.000001) / Шаг) * Шаг
Значение = 2100;
Шаг = 1000;
Результат = Цел((Значение + Шаг - 0.001) / Шаг) * Шаг; // Получим 3000

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

Что такое «Банковское округление»?

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

Согласно международному стандарту ISO 80000-1, если число заканчивается ровно на .5, оно округляется до ближайшего четного числа.

Это позволяет сбалансировать итоговую сумму чека или отчета, так как стандартное округление всегда немного завышает общий результат. В 1С стандартная функция Окр() имеет третий параметр — РежимОкругления, который позволяет выбрать способ обработки ситуации «0.5».

Заключение и рекомендации

Подведем итоги нашего анализа. Выбор метода округления в 1С зависит от конкретной бизнес-задачи:

Помните, что любые манипуляции с округлением в бухгалтерском учете должны строго соответствовать законодательству (НК РФ), в то время как в управленческом учете вы вольны внедрять любые «хотелки» бизнеса для оптимизации логистики и прибыли.

← На главную