В процессе разработки в среде 1С:Предприятие 8.3 часто возникают задачи, связанные с расчетом цен, налогов или лимитов, где требуется привести число к кратному значению. Одной из популярных задач является округление в большую сторону до тысяч (например, чтобы из 236 получить 1000, а из 1236 получить 2000). Стандартная арифметика не всегда справляется с этой задачей "из коробки", так как большинство функций настроены на математическое округление к ближайшему целому.
В этой статье мы подробно разберем несколько способов решения этой задачи: от использования встроенных функций платформы до написания универсальных алгоритмов, которые можно применять в любых модулях системы. Мы проанализируем ситуацию с разных сторон, включая работу в запросах и обработку отрицательных чисел. Чтобы проверить корректность работы новых алгоритмов, можно автоматически сверять бухгалтерские и налоговые проводки между информационными базами.
Рассмотрим самый быстрый и элегантный способ, который предоставляет платформа 1С. Функция Окр (округлить) имеет второй параметр — Разрядность. Мало кто знает, что этот параметр может быть отрицательным.
Если мы укажем разрядность -3, система будет округлять число до тысяч. Однако по умолчанию Окр работает по арифметическим правилам (от 5 — вверх, до 5 — вниз). Чтобы гарантированно получить округление вверх, нам нужно прибавить к числу "смещение".
Разберем пример кода:
// Обычное арифметическое округление до тысяч
Результат = Окр(1236, -3); // Вернет 1000
// Округление всегда в большую сторону
ЧислоДляОкругления = 1236;
РезультатВверх = Окр(ЧислоДляОкругления + 499.999999, -3); // Вернет 2000
В данном примере мы добавляем 499.999999. Почему именно столько? Это позволяет "подтолкнуть" любое число, которое чуть больше предыдущей тысячи, к следующему порогу округления. Если число уже равно 1000, прибавление 499.99 не превратит его в 2000 (так как 1499.99 округляется до 1000), что обеспечивает корректность логики.
Иногда использование дробных добавок кажется "грязным" кодом. В таком случае мы можем реализовать чистую математическую функцию. Разберем по шагам логику: разделим число на 1000, округлим вверх до целого и умножим обратно на 1000.
Для реализации округления вверх до целого в 1С нет встроенной функции "Потолок" (Ceil), но мы можем использовать функцию Цел (целая часть). Посмотрим на пример реализации:
Функция ОкруглитьВБольшуюСторонуДоТысячи(Значение) Экспорт
// Проверяем, делится ли число на 1000 без остатка
Если Значение % 1000 = 0 Тогда
Возврат Значение;
Иначе
// Берем целую часть от деления и прибавляем 1
Возврат (Цел(Значение / 1000) + 1) * 1000;
КонецЕсли;
КонецФункции
Этот метод считается более надежным, так как он не зависит от количества "девяток" в дробной части смещения и работает прозрачно для любого разработчика.
В современных конфигурациях, таких как УТ 11, ERP или БП 3.0, разработчики фирмы "1С" уже предусмотрели подобные механизмы. Часто они вынесены в общие модули, связанные с ценообразованием или расчетом зарплаты. Рассмотрим алгоритм, который часто встречается в типовых решениях. Он позволяет задавать произвольный порядок округления (не только до тысяч, но и до 50, 100 или 500).
Функция глОкруглитьВверх(Число, ПорядокОкругления) Экспорт
Если ПорядокОкругления = 0 Тогда
Возврат Число;
КонецЕсли;
КоличествоИнтервалов = Число / ПорядокОкругления;
КоличествоЦелыхИнтервалов = Цел(КоличествоИнтервалов);
Если КоличествоИнтервалов = КоличествоЦелыхИнтервалов Тогда
Возврат Число;
Иначе
Возврат ПорядокОкругления * (КоличествоЦелыхИнтервалов + 1);
КонецЕсли;
КонецФункции
// Применение:
Результат = глОкруглитьВверх(1236, 1000); // Вернет 2000
Преимущество этого метода: вы можете передать в ПорядокОкругления любое число. Если вам завтра понадобится округлять до 500, вам не придется переписывать код, достаточно изменить параметр.
Часто задачу округления нужно решить прямо в тексте запроса, чтобы не перебирать тысячи строк в цикле. В языке запросов нет функции Окр с разрядностью и нет функции Цел. Но мы можем использовать функцию ВЫРАЗИТЬ.
Проанализируем ситуацию: ВЫРАЗИТЬ(Число КАК Число(15, 0)) выполняет арифметическое округление. Чтобы реализовать округление вверх до тысяч в запросе, используем следующую конструкцию:
ВЫБРАТЬ
(ВЫРАЗИТЬ((МояТаблица.Сумма + 499.99) / 1000 КАК ЧИСЛО(15, 0))) * 1000 КАК СуммаОкругленно
ИЗ
Справочник.Номенклатура КАК МояТаблица
Здесь мы сначала смещаем число, превращаем его в "тысячные доли", округляем до целого через ВЫРАЗИТЬ и возвращаем масштаб, умножая на 1000.
При реализации округления важно учитывать несколько критических моментов, которые могут привести к неверным расчетам в боевой базе:
-236 — это 0. Но в бизнесе часто имеют в виду округление по модулю, то есть -1000. Если нужно округление по модулю, используйте Abs() (модуль числа) перед расчетом.Число. При получении данных из текстовых полей или внешних источников всегда используйте преобразование Число().+499.99, помните, что если число имеет много знаков после запятой (например, 1000.000000001), то смещение должно быть максимально точным, иначе результат останется 1000.Подводя итог, можно сказать, что для простых задач в коде идеально подходит метод Окр(ч + 499.99, -3), а для сложных системных механизмов лучше написать свою или использовать типовую функцию с параметром ПорядокОкругления. Это обеспечит гибкость и читаемость вашего кода.