При работе в программе «1С:Управление торговлей 10.3» пользователи часто сталкиваются с проблемой появления копеек в итоговой сумме документов (например, в счетах на оплату или реализациях товаров и услуг). Даже если базовые цены номенклатуры установлены в целых рублях, при применении процентной скидки (например, 5% или 7%) в результирующей сумме неизбежно возникают дробные части. Это усложняет расчеты с клиентами и не всегда устраивает бухгалтерию, которой требуются «круглые» суммы без копеек.
В этой статье мы подробно разберем, как решить задачу округления суммы документа до целого рубля, проанализируем критические ошибки, которые могут «поставить раком» весь учет, и рассмотрим несколько вариантов правильной реализации — от простых до профессиональных.
Выясним причину, почему способ, к которому прибегают многие начинающие специалисты (изменение точности реквизита Сумма в конфигураторе с 2 до 0 знаков), является крайне опасным. На первый взгляд, это кажется самым простым решением: зайти в свойства табличной части документа, установить точность в ноль, и копейки исчезнут. Однако делать это категорически запрещено по следующим причинам:
Цена * Количество = Сумма. Если округлить сумму строки до целого рубля, нарушив это равенство, кассовый аппарат заблокирует пробитие чека с ошибкой расхождения позиций и итога.Поэтому рассмотрим только безопасные и правильные методы округления.
Если копейки мешают исключительно при отправке документов клиенту (например, в счете на оплату), самый лучший и безопасный метод — оставить документы в базе с копейками, но убрать их отображение в печатных формах. Разберем, как это сделать.
Для этого мы можем использовать форматную строку. Откроем макет печатной формы документа, найдем ячейку, в которую выводится сумма, и настроим ее формат:
СуммаДокумента).0.В коде модуля печати вывод суммы можно принудительно преобразовать с помощью встроенной функции Формат(). Рассмотрим пример кода:
// Пример округления суммы при выводе в печатную форму
СуммаДляПечати = Формат(Шапка.СуммаДокумента, "ЧДЦ=0; ЧГ=3,0");
// Теперь переменная СуммаДляПечати содержит строку без копеек, с разделителями групп
Если вам необходимо, чтобы именно сам документ содержал округленные суммы, мы можем добавить на форму документа кнопку, при нажатии на которую программа автоматически обойдет все строки табличной части и округлит цены и суммы математическим путем.
Рассмотрим по шагам реализацию этого метода в обычной форме документа «Реализация товаров и услуг»:
ДействиеОкруглитьКопейки и заголовком «Округлить копейки»).
Процедура ДействиеОкруглитьКопейкиНажатие(Кнопка)
// Получаем табличную часть товары текущего документа
ТабличнаяЧастьТовары = ЭтотОбъект.Товары;
Для Каждого СтрокаТЧ Из ТабличнаяЧастьТовары Цикл
// Округляем сумму строки по правилам математики до целого рубля
СтрокаТЧ.Сумма = Окр(СтрокаТЧ.Сумма, 0);
// Чтобы не нарушать логику "Цена * Количество = Сумма", пересчитаем цену
Если СтрокаТЧ.Количество <> 0 Тогда
СтрокаТЧ.Цена = Окр(СтрокаТЧ.Сумма / СтрокаТЧ.Количество, 2);
КонецЕсли;
// Если в документе рассчитывается НДС, пересчитаем и его
// (Используем стандартные механизмы конфигурации УТ 10.3)
ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТЧ, ЭтотОбъект);
КонецЦикла;
// Пересчитываем общие итоги документа (сумму документа и сумму НДС)
ЗаполнениеДокументов.РассчитатьИтогиДокумента(ЭтотОбъект);
КонецПроцедуры
Этот способ хорош тем, что он не затрагивает старые документы, работает точечно по требованию пользователя и корректно пересчитывает сопутствующие показатели (например, НДС).
Проанализируем более гибкий и изящный вариант, который позволяет пользователю самому решать, нужно ли округлять копейки в конкретной сделке. Для этого мы добавим в документ реквизит типа Булево и изменим логику стандартного расчета сумм.
Шаг 1. Добавление реквизита.
В конфигураторе найдем документ РеализацияТоваровУслуг (или ЗаказПокупателя), добавим новый реквизит с именем ОкруглятьКопейки и типом Булево. Выведем его на форму документа в виде флажка (флага).
Шаг 2. Изменение общего модуля.
В УТ 10.3 расчет сумм в строках происходит централизованно в общем модуле ОбработкаТабличныхЧастей. Найдем процедуру РассчитатьСуммуTabЧасти и модифицируем ее код так, чтобы при установленном флаге программа округляла скидки и суммы строк.
Посмотрим на пример изменения стандартного кода процедуры:
Процедура РассчитатьСуммуТабЧасти(СтрокаТабличнойЧасти, ДокументОбъект, СпособРасчета = Неопределено, ЧекККМ = 0) Экспорт
МетаданныеДокумента = ДокументОбъект.Метаданные;
// Проверяем наличие нашего реквизита округления в документе
ФлагОкругления = Ложь;
Если ОбщегоНазначения.ЕстьРеквизитДокумента("ОкруглятьКопейки", МетаданныеДокумента) Тогда
ФлагОкругления = ДокументОбъект.ОкруглятьКопейки;
КонецЕсли;
ИмяТабличнойЧасти = ОбщегоНазначения.ПолучитьИмяТабличнойЧастиПоСсылкеНа строку(СтрокаТабличнойЧасти);
Сумма = СтрокаТабличнойЧасти.Цена * СтрокаТабличнойЧасти.Количество;
СуммаСкидки = 0;
Если (СпособРасчета = Неопределено)
Или (СпособРасчета = Перечисления.СпособРасчетаСуммыДокумента.СУчетомВсехСкидок)
Или (СпособРасчета = Перечисления.СпособРасчетаСуммыДокумента.БезУчетаРучнойСкидки) Тогда
// Расчет автоматических скидок
Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("ПроцентАвтоматическихСкидок", МетаданныеДокумента, ИмяТабличнойЧасти) Тогда
СуммаСкидки = Сумма * СтрокаТабличнойЧасти.ПроцентАвтоматическихСкидок / 100;
КонецЕсли;
// Расчет ручных скидок с учетом округления
Если (СпособРасчета <> Перечисления.СпособРасчетаСуммыДокумента.БезУчетаРучнойСкидки) Тогда
Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("ПроцентСкидкиНаценки", МетаданныеДокумента, ИмяТабличнойЧасти) Тогда
ТекущаяСкидка = Сумма * СтрокаТабличнойЧасти.ПроцентСкидкиНаценки / 100;
Если ФлагОкругления Тогда
// Округляем скидку так, чтобы итоговая сумма получилась без копеек
СуммаСкидки = СуммаСкидки + Окр(ТекущаяСкидка, 2);
Иначе
СуммаСкидки = СуммаСкидки + ТекущаяСкидка;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Вычисляем конечную сумму строки
КонечнаяСумма = Сумма - СуммаСкидки;
Если ФлагОкругления Тогда
СтрокаТабличнойЧасти.Сумма = Окр(КонечнаяСумма, 0);
// Корректируем скидку, чтобы баланс сошелся
СтрокаТабличнойЧасти.СуммаСкидки = Сумма - СтрокаТабличнойЧасти.Сумма;
Иначе
СтрокаТабличнойЧасти.Сумма = КонечнаяСумма;
КонецЕсли;
КонецПроцедуры
Шаг 3. Обработка изменения флажка на форме.
При изменении состояния флажка на форме документа нам нужно запустить полный пересчет табличной части. Напишем обработчик события кнопки или флажка:
Процедура ОкруглятьКопейкиПриИзменении(Элемент)
// Обходим все строки и пересчитываем суммы по обновленной логике общего модуля
Для Каждого СтрокаТовары Из ЭтотОбъект.Товары Цикл
ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(СтрокаТовары, ЭтотОбъект);
ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТовары, ЭтотОбъект);
КонецЦикла;
// Обновляем итоги на форме
ЗаполнениеДокументов.РассчитатьИтогиДокумента(ЭтотОбъект);
КонецПроцедуры
Этот подход является наиболее гибким: он позволяет менеджерам выписывать документы как с копейками (например, при расчете в валюте или у.е.), так и без них, просто установив один флажок на форме.
При округлении сумм строк по отдельности может возникнуть ситуация, когда сумма округленных строк не совпадает с математически округленной общей суммой всего документа. Разница может составлять несколько копеек. Это называется накоплением погрешности округления.
Проанализируем правильный алгоритм распределения этой погрешности:
Этот метод гарантирует, что итоговая сумма документа всегда будет идеально круглой, а математическая связь между строками и итогом не нарушится.