Как округлить дробные значения до рубля?
Округление дробных значений до рубля (целого числа) — важный шаг при распределении денежных сумм в 1С, особенно в тех случаях, когда нужно строго соответствовать исходной общей сумме после округлений. При этом используются стандартные функции платформы, и задача усложняется, если после округления возникает расхождение между суммой округлённых значений и исходной суммой. Ниже подробно описываются методы округления, проблемы и способы их решения.
1. Зачем округлять до рубля
В большинстве случаев денежные операции (особенно в документах бухгалтерии, кассе, расчётах с поставщиками и покупателями) требуют округления до целых рублей. При этом округление может быть:
-
Математическим — до ближайшего целого;
-
В меньшую сторону (отсечение);
-
В большую сторону.
2. Округление стандартными средствами 1С
Функция Окр()
В 1С используется функция Окр(), которая позволяет округлить число до заданной точности:
ОкругленноеЗначение = Окр(Число, 0);
-
Второй параметр — количество знаков после запятой.
-
0 означает округление до целого.
Примеры:
Окр(12.7, 0) // 13
Окр(12.4, 0) // 12
Окр(-3.5, 0) // -4 (округление от нуля, если включено округление по IEEE)
3. Особенности округления и проблемы
Сумма после округления отличается от исходной
Проблема: если округлить каждое дробное значение до целого, сумма всех округлённых значений может не совпасть с исходной общей суммой.
Пример:
Исходные суммы:
\[3.3, 3.3, 3.4\] → итог 10
Округлённые:
\[3, 3, 3\] → итог 9
ИЛИ
\[3, 3, 4\] → итог 10
Как решить эту проблему
Используется методика контролируемого округления с компенсацией:
-
Округлить каждое значение вниз (Цел(Значение)).
-
Посчитать, сколько рублей не хватает до исходной суммы.
-
Добавить по одному рублю в строки с наибольшими остатками после округления.
4. Пример алгоритма в 1С
// Исходные данные
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Доля");
Таблица.Колонки.Добавить("Результат");
Таблица.Колонки.Добавить("Остаток");
ОбщаяСумма = 40;
// Пример значений
Таблица.Добавить(Новый СтрокаТаблицыЗначений(2.7));
Таблица.Добавить(Новый СтрокаТаблицыЗначений(3.3));
Таблица.Добавить(Новый СтрокаТаблицыЗначений(4.0));
// 1. Округляем вниз
СуммаЦелых = 0;
Для Каждого Стр Из Таблица Цикл
ЦелаяЧасть = Цел(Стр.Доля);
Стр.Результат = ЦелаяЧасть;
Стр.Остаток = Стр.Доля - ЦелаяЧасть;
СуммаЦелых = СуммаЦелых + ЦелаяЧасть;
КонецЦикла;
// 2. Определяем, сколько добавить
НеХватает = ОбщаяСумма - СуммаЦелых;
// 3. Сортируем по остаткам (по убыванию)
Таблица.Сортировать("Остаток Убыв");
// 4. Добавляем 1 рубль в строки с наибольшим остатком
Для Индекс = 0 По НеХватает - 1 Цикл
Таблица\[Индекс\].Результат = Таблица\[Индекс\].Результат + 1;
КонецЦикла;
Этот алгоритм гарантирует:
-
сумма всех Результат = 40;
-
минимальное и наиболее "справедливое" искажение пропорций.
5. Альтернативные способы округления
- Окр(Число, 0, РежимОкругления.ОтБольшеКМеньшему) — округление всегда вниз;
- Окр(Число, 0, РежимОкругления.ОтМеньшегоКБольшему) — всегда вверх;
- Окр(Число, 0, РежимОкругления.КБлижайшему) — математическое (по умолчанию).
6. Учет знаков при округлении
Округление отрицательных чисел может вести к другим результатам:
Окр(-2.5, 0) → -2 (если платформа настроена на округление к ближайшему чётному)
Чтобы избежать путаницы, особенно в деньгах — рекомендуется использовать строго заданный режим округления.
7. Влияние округления на бизнес-логику
-
При составлении актов, расчёте налогов, зарплат — важна точность.
-
Ошибки в округлении могут привести к непрохождению проверок, рассогласованию с бухгалтерией или ошибке при проверке суммы документа и табличной части.
-
При импорте/экспорте — округления могут не совпадать с внешними системами (например, при обмене XML с банками, ЕГАИС и т.д.).
8. Контроль итоговой суммы
После округления необходимо суммировать все значения и сравнить с исходной суммой:
КонтрольСумма = 0;
Для каждого Стр Из Таблица Цикл
КонтрольСумма = КонтрольСумма + Стр.Результат;
КонецЦикла;
Если КонтрольСумма <> ОбщаяСумма Тогда
Сообщить("Сумма после округления не совпадает с ожидаемой!");
КонецЕсли;
Это поможет отлавливать критические ошибки ещё до проведения документа или формирования движения по регистрам.