Как округлить число в сумме документа в 1С:Управление торговлей 10.3?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При работе в программе «1С:Управление торговлей 10.3» пользователи часто сталкиваются с проблемой появления копеек в итоговой сумме документов (например, в счетах на оплату или реализациях товаров и услуг). Даже если базовые цены номенклатуры установлены в целых рублях, при применении процентной скидки (например, 5% или 7%) в результирующей сумме неизбежно возникают дробные части. Это усложняет расчеты с клиентами и не всегда устраивает бухгалтерию, которой требуются «круглые» суммы без копеек.

В этой статье мы подробно разберем, как решить задачу округления суммы документа до целого рубля, проанализируем критические ошибки, которые могут «поставить раком» весь учет, и рассмотрим несколько вариантов правильной реализации — от простых до профессиональных.

Критическая ошибка: изменение разрядности реквизита в метаданных

Выясним причину, почему способ, к которому прибегают многие начинающие специалисты (изменение точности реквизита Сумма в конфигураторе с 2 до 0 знаков), является крайне опасным. На первый взгляд, это кажется самым простым решением: зайти в свойства табличной части документа, установить точность в ноль, и копейки исчезнут. Однако делать это категорически запрещено по следующим причинам:

  1. Разрушение исторических данных: При сохранении конфигурации платформа выполнит физическую реструктуризацию таблиц базы данных SQL или файловой базы. Это означает, что копейки будут безвозвратно удалены во всех документах прошлых (уже закрытых и сданных) периодов. Это приведет к несовпадению взаиморасчетов с контрагентами и искажению актов сверки.
  2. Проблемы с НДС и налоговой отчетностью: Даже если вы работаете без НДС, при обмене данными с «1С:Бухгалтерией» округленные «в лоб» суммы вызовут расхождения в расчетах налога и контрольных соотношениях деклараций. Налоговая служба требует точности до копеек.
  3. Сбои при интеграции с онлайн-кассами (ФЗ-54): Фискальные регистраторы жестко контролируют математическое равенство: Цена * Количество = Сумма. Если округлить сумму строки до целого рубля, нарушив это равенство, кассовый аппарат заблокирует пробитие чека с ошибкой расхождения позиций и итога.

Поэтому рассмотрим только безопасные и правильные методы округления.

Решение №1: Округление только в печатной форме (без изменения данных в базе)

Если копейки мешают исключительно при отправке документов клиенту (например, в счете на оплату), самый лучший и безопасный метод — оставить документы в базе с копейками, но убрать их отображение в печатных формах. Разберем, как это сделать.

Для этого мы можем использовать форматную строку. Откроем макет печатной формы документа, найдем ячейку, в которую выводится сумма, и настроим ее формат:

  1. Выделите ячейку макета с параметром суммы (например, СуммаДокумента).
  2. Откройте свойства ячейки (клавиша F4).
  3. Найдите свойство Формат, нажмите кнопку выбора и в открывшемся конструкторе форматной строки укажите количество десятичных знаков (ЧДЦ) равным 0.

В коде модуля печати вывод суммы можно принудительно преобразовать с помощью встроенной функции Формат(). Рассмотрим пример кода:


// Пример округления суммы при выводе в печатную форму
СуммаДляПечати = Формат(Шапка.СуммаДокумента, "ЧДЦ=0; ЧГ=3,0");
// Теперь переменная СуммаДляПечати содержит строку без копеек, с разделителями групп

Решение №2: Динамический пересчет табличной части по кнопке на форме

Если вам необходимо, чтобы именно сам документ содержал округленные суммы, мы можем добавить на форму документа кнопку, при нажатии на которую программа автоматически обойдет все строки табличной части и округлит цены и суммы математическим путем.

Рассмотрим по шагам реализацию этого метода в обычной форме документа «Реализация товаров и услуг»:

  1. Откроем форму документа в конфигураторе.
  2. Добавим на командную панель табличной части «Товары» новую кнопку (например, с действием ДействиеОкруглитьКопейки и заголовком «Округлить копейки»).
  3. В модуле формы напишем процедуру-обработчик для этой кнопки:

Процедура ДействиеОкруглитьКопейкиНажатие(Кнопка)
    
    // Получаем табличную часть товары текущего документа
    ТабличнаяЧастьТовары = ЭтотОбъект.Товары;
    
    Для Каждого СтрокаТЧ Из ТабличнаяЧастьТовары Цикл
        
        // Округляем сумму строки по правилам математики до целого рубля
        СтрокаТЧ.Сумма = Окр(СтрокаТЧ.Сумма, 0);
        
        // Чтобы не нарушать логику "Цена * Количество = Сумма", пересчитаем цену
        Если СтрокаТЧ.Количество <> 0 Тогда
            СтрокаТЧ.Цена = Окр(СтрокаТЧ.Сумма / СтрокаТЧ.Количество, 2);
        КонецЕсли;
        
        // Если в документе рассчитывается НДС, пересчитаем и его
        // (Используем стандартные механизмы конфигурации УТ 10.3)
        ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТЧ, ЭтотОбъект);
        
    КонецЦикла;
    
    // Пересчитываем общие итоги документа (сумму документа и сумму НДС)
    ЗаполнениеДокументов.РассчитатьИтогиДокумента(ЭтотОбъект);
    
КонецПроцедуры

Этот способ хорош тем, что он не затрагивает старые документы, работает точечно по требованию пользователя и корректно пересчитывает сопутствующие показатели (например, НДС).

Решение №3: Комплексная доработка с реквизитом «Округлять копейки» (Профессиональный подход)

Проанализируем более гибкий и изящный вариант, который позволяет пользователю самому решать, нужно ли округлять копейки в конкретной сделке. Для этого мы добавим в документ реквизит типа Булево и изменим логику стандартного расчета сумм.

Шаг 1. Добавление реквизита.
В конфигураторе найдем документ РеализацияТоваровУслуг (или ЗаказПокупателя), добавим новый реквизит с именем ОкруглятьКопейки и типом Булево. Выведем его на форму документа в виде флажка (флага).

Шаг 2. Изменение общего модуля.
В УТ 10.3 расчет сумм в строках происходит централизованно в общем модуле ОбработкаТабличныхЧастей. Найдем процедуру РассчитатьСуммуTabЧасти и модифицируем ее код так, чтобы при установленном флаге программа округляла скидки и суммы строк.

Посмотрим на пример изменения стандартного кода процедуры:


Процедура РассчитатьСуммуТабЧасти(СтрокаТабличнойЧасти, ДокументОбъект, СпособРасчета = Неопределено, ЧекККМ = 0) Экспорт

    МетаданныеДокумента = ДокументОбъект.Метаданные;
    
    // Проверяем наличие нашего реквизита округления в документе
    ФлагОкругления = Ложь;
    Если ОбщегоНазначения.ЕстьРеквизитДокумента("ОкруглятьКопейки", МетаданныеДокумента) Тогда
        ФлагОкругления = ДокументОбъект.ОкруглятьКопейки;
    КонецЕсли;

    ИмяТабличнойЧасти = ОбщегоНазначения.ПолучитьИмяТабличнойЧастиПоСсылкеНа строку(СтрокаТабличнойЧасти);
    Сумма = СтрокаТабличнойЧасти.Цена * СтрокаТабличнойЧасти.Количество;
    СуммаСкидки = 0;

    Если (СпособРасчета = Неопределено) 
        Или (СпособРасчета = Перечисления.СпособРасчетаСуммыДокумента.СУчетомВсехСкидок) 
        Или (СпособРасчета = Перечисления.СпособРасчетаСуммыДокумента.БезУчетаРучнойСкидки) Тогда
        
        // Расчет автоматических скидок
        Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("ПроцентАвтоматическихСкидок", МетаданныеДокумента, ИмяТабличнойЧасти) Тогда
            СуммаСкидки = Сумма * СтрокаТабличнойЧасти.ПроцентАвтоматическихСкидок / 100;
        КонецЕсли;

        // Расчет ручных скидок с учетом округления
        Если (СпособРасчета <> Перечисления.СпособРасчетаСуммыДокумента.БезУчетаРучнойСкидки) Тогда
            Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("ПроцентСкидкиНаценки", МетаданныеДокумента, ИмяТабличнойЧасти) Тогда
                
                ТекущаяСкидка = Сумма * СтрокаТабличнойЧасти.ПроцентСкидкиНаценки / 100;
                
                Если ФлагОкругления Тогда
                    // Округляем скидку так, чтобы итоговая сумма получилась без копеек
                    СуммаСкидки = СуммаСкидки + Окр(ТекущаяСкидка, 2);
                Иначе
                    СуммаСкидки = СуммаСкидки + ТекущаяСкидка;
                КонецЕсли;
                
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;

    // Вычисляем конечную сумму строки
    КонечнаяСумма = Сумма - СуммаСкидки;
    
    Если ФлагОкругления Тогда
        СтрокаТабличнойЧасти.Сумма = Окр(КонечнаяСумма, 0);
        // Корректируем скидку, чтобы баланс сошелся
        СтрокаТабличнойЧасти.СуммаСкидки = Сумма - СтрокаТабличнойЧасти.Сумма;
    Иначе
        СтрокаТабличнойЧасти.Сумма = КонечнаяСумма;
    КонецЕсли;

КонецПроцедуры

Шаг 3. Обработка изменения флажка на форме.
При изменении состояния флажка на форме документа нам нужно запустить полный пересчет табличной части. Напишем обработчик события кнопки или флажка:


Процедура ОкруглятьКопейкиПриИзменении(Элемент)
    
    // Обходим все строки и пересчитываем суммы по обновленной логике общего модуля
    Для Каждого СтрокаТовары Из ЭтотОбъект.Товары Цикл
        ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(СтрокаТовары, ЭтотОбъект);
        ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТовары, ЭтотОбъект);
    КонецЦикла;
    
    // Обновляем итоги на форме
    ЗаполнениеДокументов.РассчитатьИтогиДокумента(ЭтотОбъект);
    
КонецПроцедуры

Этот подход является наиболее гибким: он позволяет менеджерам выписывать документы как с копейками (например, при расчете в валюте или у.е.), так и без них, просто установив один флажок на форме.

Важный нюанс: математическое распределение погрешности

При округлении сумм строк по отдельности может возникнуть ситуация, когда сумма округленных строк не совпадает с математически округленной общей суммой всего документа. Разница может составлять несколько копеек. Это называется накоплением погрешности округления.

Проанализируем правильный алгоритм распределения этой погрешности:

  1. Сначала рассчитывается точная сумма документа со всеми копейками.
  2. Эта сумма округляется до целого рубля (получаем целевую сумму).
  3. Вычисляется разница между точной суммой и округленной целевой суммой.
  4. Полученная погрешность (например, +0.34 рубля или -0.12 рублей) прибавляется или вычитается из суммы строки с наибольшей стоимостью (или просто из последней строки документа).

Этот метод гарантирует, что итоговая сумма документа всегда будет идеально круглой, а математическая связь между строками и итогом не нарушится.

← На главную