Как округлить дробные значения до рубля?

Округление дробных значений до рубля (целого числа) — важный шаг при распределении денежных сумм в 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

Как решить эту проблему

Используется методика контролируемого округления с компенсацией:

  1. Округлить каждое значение вниз (Цел(Значение)).

  2. Посчитать, сколько рублей не хватает до исходной суммы.

  3. Добавить по одному рублю в строки с наибольшими остатками после округления.

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;
Для каждого Стр Из Таблица Цикл
КонтрольСумма = КонтрольСумма + Стр.Результат;
КонецЦикла;
Если КонтрольСумма <> ОбщаяСумма Тогда
Сообщить("Сумма после округления не совпадает с ожидаемой!");
КонецЕсли;

Это поможет отлавливать критические ошибки ещё до проведения документа или формирования движения по регистрам.