В практике разработчика 1С нередко возникают задачи, выходящие за рамки стандартного школьного округления. Одной из таких задач является округление «вверх» до определенного порога или кратности. Например, когда клиент требует, чтобы любое значение, превышающее целое число (даже на копейку), превращалось в следующую тысячу: 2001 должно стать 3000, а 2100 — также 3000. В этой статье мы разберем, зачем это нужно бизнесу и как технически реализовать такие алгоритмы в коде 1С.
Прежде чем переходить к написанию кода, проанализируем ситуацию и выясним причину таких запросов. Округление «в пользу продавца» — это не всегда попытка обмануть покупателя, зачастую это жесткая необходимость, продиктованная особенностями учета или физическими свойствами товара.
Рассмотрим первый способ, предложенный в обсуждении. Если нам нужно округлить число до ближайшей тысячи вверх (например, превратить 2100 в 3000), можно воспользоваться математическим смещением границы округления.
Стандартная функция Окр() работает по правилам арифметики. Чтобы «заставить» её всегда округлять вверх до тысяч, мы можем прибавить к числу 499 (или 500 в зависимости от точности) перед округлением. Разберем пример кода:
// Округление до ближайшей 1000 вверх
// Если Цена = 2100, то Результат будет 3000
// Если Цена = 2000, то Результат останется 2000
Цена = 2100;
Результат = Окр(Цена + 499, -3);
В данном примере параметр -3 указывает функции Окр(), что округление происходит до сотен (три знака до запятой). Прибавление 499 гарантирует, что любое число от 2001 до 2500 перешагнет порог, при котором стандартное округление отправило бы его вверх.
Проанализируем ситуацию с расчетом материалов. Бывает необходимо реализовать логику, когда, например, значение 1.3 превращается в 2, а 1.299 остается единицей. Это часто используется при расчете «квантов» материала.
Для этого можно использовать простую формулу с добавлением дробного коэффициента:
// КвантыЦелые = Окр(КвантыРасчетные + КоэффициентСдвига)
// Например, при Коэффициенте = 0.3
РасчетноеКоличество = 1.3;
ИтоговоеКоличество = Цел(РасчетноеКоличество + 0.7); // Получим 2
Однако более универсальным и надежным способом реализации функции «Потолок» (Ceiling) в 1С является использование отрицательного преобразования с функцией Цел().
В большинстве языков программирования есть встроенная функция Ceil(), которая возвращает ближайшее целое число, которое больше или равно заданному. В классическом 1С такой функции долгое время не было в явном виде. Посмотрим на элегантный способ её реализации через отрицательные числа:
// Функция всегда округляет вверх до целого
ЧислоДляОкругления = 2.1;
Результат = -Цел(-ЧислоДляОкругления); // Получим 3
Как это работает? Проанализируем пошагово:
Цел(-2.1) отсекает дробную часть и возвращает -2 (так как это ближайшее целое в сторону нуля).Важное замечание: Чтобы округление всегда шло именно в большую сторону (от 2.1 к 3), данный метод нужно комбинировать с проверкой остатка или использовать формулу кратности.
Если нам нужно округлить число вверх до произвольного шага (например, до ближайших 500 рублей или до ближайшей упаковки по 12 штук), воспользуемся универсальной формулой:
// Результат = Цел((Значение + Шаг - 0.000001) / Шаг) * Шаг
Значение = 2100;
Шаг = 1000;
Результат = Цел((Значение + Шаг - 0.001) / Шаг) * Шаг; // Получим 3000
Эта формула работает безотказно для любых положительных чисел. Вычитание малой доли (0.001) необходимо для того, чтобы числа, которые уже кратны шагу (например, ровно 2000), не округлялись до следующего шага (до 3000).
В обсуждении упоминалось так называемое «банковское округление» (Гауссово округление). Разберем, чем оно отличается от обычного. Его суть заключается в минимизации погрешности при расчете больших массивов данных.
Согласно международному стандарту ISO 80000-1, если число заканчивается ровно на .5, оно округляется до ближайшего четного числа.
Это позволяет сбалансировать итоговую сумму чека или отчета, так как стандартное округление всегда немного завышает общий результат. В 1С стандартная функция Окр() имеет третий параметр — РежимОкругления, который позволяет выбрать способ обработки ситуации «0.5».
Подведем итоги нашего анализа. Выбор метода округления в 1С зависит от конкретной бизнес-задачи:
Окр(Цена + 499, -3).Цел() с проверкой остатка.Помните, что любые манипуляции с округлением в бухгалтерском учете должны строго соответствовать законодательству (НК РФ), в то время как в управленческом учете вы вольны внедрять любые «хотелки» бизнеса для оптимизации логистики и прибыли.