При работе с валютными документами или договорами в условных единицах (у.е.) разработчики и бухгалтеры регулярно сталкиваются с классической дилеммой: как правильно пересчитать рублевую сумму документа? На первый взгляд задача кажется тривиальной — достаточно умножить валютную сумму на курс. Однако на практике, когда в документе появляется несколько строк табличной части, возникает проблема округления копеек. Если считать каждую строку отдельно, итоговая рублевая сумма может не совпасть с рублевым эквивалентом общей суммы документа в валюте.
В этой статье мы подробно разберем суть проблемы, проанализируем три различных алгоритма расчета, выясним методологическую позицию бухгалтерского учета и посмотрим, как эта задача решается в типовых конфигурациях 1С с помощью встроенных механизмов Библиотеки стандартных подсистем (БСП).
---
Давайте проанализируем ситуацию на конкретном примере. Предположим, у нас есть документ отгрузки, в котором содержится 10 строк с товаром. Общая сумма документа составляет 100 USD. Курс пересчета на дату операции равен 60,15 руб. за 1 USD.
Если мы рассчитываем общую рублевую сумму от итога документа, то получаем:
100 USD * 60,15 = 6 015,00 руб.
А теперь представим, что в табличной части у нас 10 строк, в каждой из которых сумма составляет 10,01 USD (для упрощения предположим, что общая сумма чуть изменилась или распределена неравномерно). При построчном пересчете и последующем округлении каждой строки до двух знаков после запятой мы можем получить микрорасхождения. Например:
10,01 * 60,15 = 602,1015 -> округляем до 602,10 руб.10,01 * 60,15 = 602,1015 -> округляем до 602,10 руб.В сумме по строкам мы получим: 602,10 * 10 = 6 021,00 руб. При этом общая сумма в валюте составляет 100,10 USD. Прямой пересчет общей суммы дает: 100,10 * 60,15 = 6021,015 -> округляем до 6 021,02 руб.
Возникает разница в 2 копейки. На больших объемах данных, при расчете НДС или при сложных курсах с четырьмя знаками после запятой, эта погрешность может составлять от нескольких копеек до нескольких рублей. Это приводит к тому, что рублевый итог по накладной не сходится с рублевой суммой, которую покупатель должен оплатить по банку.
---
Давайте подробно рассмотрим три возможных алгоритма расчета рублевых сумм в многострочных документах.
При этом подходе мы берем каждую строку табличной части, умножаем валютную сумму строки на курс, округляем результат до копеек и записываем в рублевую сумму строки. Итог документа получается простым суммированием рублевых сумм строк.
Плюсы:
10 USD * 60,15 вдруг превратилось в 601,51 руб.Минусы:
ИтогоВалюта * Курс. Из-за этого «зависают» копейки во взаиморасчетах с контрагентами. При оплате общего счета в банке возникнет расхождение, которое бухгалтеру придется списывать вручную как курсовую или операционную разницу.Этот подход считается методологически верным в бухгалтерском и налоговом учете. Сначала мы берем общую сумму документа в валюте, умножаем ее на курс и получаем итоговую рублевую сумму, которую контрагент обязан нам заплатить. Затем эта общая сумма распределяется по строкам табличной части пропорционально их валютной стоимости.
Плюсы:
Минусы:
Интересной альтернативой является расчет рублевых сумм по мере обхода строк нарастающим итогом. Давайте разберем этот алгоритм по шагам:
Такой подход позволяет автоматически «размазывать» погрешность округления по строкам в процессе расчета, и финальная копейка гарантированно встанет на свое место, обеспечив идеальное равенство итогов.
---
Методология 1С однозначно требует применения Подхода №2 (распределение от общей суммы). В таких конфигурациях, как 1С:ERP, 1С:Комплексная автоматизация или 1С:Бухгалтерия, взаиморасчеты ведутся по договору или документу в целом. Поэтому рублевый итог документа имеет приоритет над построчным расчетом.
Более того, для подтверждения правильности расчетов перед аудиторами в документах предусмотрена печатная форма «Справка-расчет рублевых сумм документа в валюте». Она показывает, как именно общая сумма была пересчитана и распределена по товарным позициям.
Для технической реализации этого механизма разработчикам нет необходимости писать собственные циклы распределения погрешностей. В Библиотеке стандартных подсистем (БСП) есть готовая и оптимизированная функция. Давайте посмотрим на пример ее использования.
Для распределения сумм применяется метод ОбщегоНазначенияКлиентСервер.РаспределитьСуммуПропорциональноКоэффициентам. Проанализируем пример кода:
// Подготовим исходные данные
РаспределяемаяСумма = 6015.02; // Общая рублевая сумма, полученная пересчетом общего итога в у.е.
Коэффициенты = Новый Массив; // Массив валютных сумм по строкам табличной части
Для Каждого СтрокаТЧ Из СсылкаНаДокумент.Товары Цикл
Коэффициенты.Добавить(СтрокаТЧ.СуммаВВалюте);
КонецЦикла;
Точность = 2; // Округляем до копеек
// Вызываем стандартную функцию БСП
РаспределенныеСуммы = ОбщегоНазначенияКлиентСервер.РаспределитьСуммуПропорциональноКоэффициентам(
РаспределяемаяСумма,
Коэффициенты,
Точность
);
// Переносим распределенные рублевые суммы обратно в табличную часть
Индекс = 0;
Для Каждого СтрокаТЧ Из СсылкаНаДокумент.Товары Цикл
СтрокаТЧ.СуммаВРублях = РаспределенныеСуммы[Индекс];
Индекс = Индекс + 1;
КонецЦикла;
Функция БСП берет на себя всю математическую работу: она пропорционально делит рублевую сумму, а возникающую погрешность округления (те самые копейки расхождения) автоматически относит на строки с наибольшим удельным весом (или на последнюю строку), обеспечивая стопроцентное совпадение суммы строк с общим итогом документа.
---
Резюмируя наш анализ, дадим практические рекомендации для разработки собственных конфигураций или доработки типовых решений:
ОбщегоНазначенияКлиентСервер.РаспределитьСуммуПропорциональноКоэффициентам. Это гарантирует надежность кода и отсутствие ошибок «лишней копейки» при округлении.