Убираем разницу в копейках в расчетах НДС

05.11.25

Задачи пользователя - Адаптация типовых решений

Убираем разницу в копейках между расчетной суммой НДС от суммы документа и построчного расчета НДС в документах: Реализация товаров и услуг, Заказ покупателя.

Вводные данные: 1С "Управление торговлей", редакция 10.3 (10.3.8.9), 8 организаций (4 с НДС).

Задача: Убрать разницу в копейках. Сумма НДС от суммы документа не равна сумме всех строк сумма НДС в документе.

Решаем: Так как программа дорабатывалась много раз, кое-что используется нестандартно. Ставки НДС по организациям находятся в регистре сведений "СтавкаНДСОрганизации".

Был создан общий модуль (серверный) - "ПересчетНДСРавенство" с процедурой "ВыровнятьНДСПоДокументуТоварыУслуги" в качестве параметра будем передавать "ДокОбъект".

 

// Выравнивание НДС по документу с двумя ТЧ: "Товары" и "Услуги".
// Единая ставка НДС (5% или 20%) на документ, расчет от брутто.
// Округляем только СуммаНДС в строках до 2 знаков.
// Распределение разницы методом дробных частей, шаг ±0,01, минимум по строке 0,00.

Процедура ВыровнятьНДСПоДокументуТоварыУслуги(ДокОбъект, ПорогМалойСтроки = 0.01) Экспорт

    // Получаем ставку НДС как число 5 или 20
	НовыйНабор = РегистрыСведений.СтавкаНДСОрганизации.СоздатьНаборЗаписей();
	НовыйНабор.Отбор.Организация.Установить(ДокОбъект.Организация);
	НовыйНабор.Прочитать();
	Ставка = УчетНДС.ПолучитьСтавкуНДС(НовыйНабор[0].СтавкаНДС);    
	Если (Ставка <> 5) И (Ставка <> 20) Тогда
        ВызватьИсключение "Поддерживаются ставки НДС 5% и 20%. Текущая: " + Строка(Ставка);
    КонецЕсли;

    Коэф = Ставка / (100 + Ставка);
    ТочностьКопеек = 2;

    // Сбор строк из двух табличных частей
    Т = Новый ТаблицаЗначений;
    Т.Колонки.Добавить("Источник");       // "Товары" или "Услуги"
    Т.Колонки.Добавить("Индекс");          // порядок ввода
    Т.Колонки.Добавить("Строка");          // объект строки ТЧ
    Т.Колонки.Добавить("СуммаСтроки");     // с НДС
    Т.Колонки.Добавить("НДСНеОкр");
    Т.Колонки.Добавить("НДСОкр");
    Т.Колонки.Добавить("Остаток");         // НДСНеОкр - НДСОкр

    СуммаДок = 0;
    Инд = 0;

    // Товары
    Если ДокОбъект.Метаданные().ТабличныеЧасти.Найти("Товары") <> Неопределено Тогда
        Для Каждого СтрТ Из ДокОбъект.Товары Цикл
            СуммаДок = СуммаДок + СтрТ.Сумма;

            НДСНеОкрЛок = СтрТ.Сумма * Коэф;
            НДСОкрЛок   = Окр(НДСНеОкрЛок, ТочностьКопеек);

            Н = Т.Добавить();
            Н.Источник     = "Товары";
            Н.Индекс       = Инд;
            Н.Строка       = СтрТ;
            Н.СуммаСтроки  = СтрТ.Сумма;
            Н.НДСНеОкр     = НДСНеОкрЛок;
            Н.НДСОкр       = НДСОкрЛок;
            Н.Остаток      = НДСНеОкрЛок - НДСОкрЛок;

            Инд = Инд + 1;
        КонецЦикла;
    КонецЕсли;

    // Услуги
    Если ДокОбъект.Метаданные().ТабличныеЧасти.Найти("Услуги") <> Неопределено Тогда
        Для Каждого СтрУ Из ДокОбъект.Услуги Цикл
            СуммаДок = СуммаДок + СтрУ.Сумма;

            НДСНеОкрЛок = СтрУ.Сумма * Коэф;
            НДСОкрЛок   = Окр(НДСНеОкрЛок, ТочностьКопеек);

            Н = Т.Добавить();
            Н.Источник     = "Услуги";
            Н.Индекс       = Инд;
            Н.Строка       = СтрУ;
            Н.СуммаСтроки  = СтрУ.Сумма;
            Н.НДСНеОкр     = НДСНеОкрЛок;
            Н.НДСОкр       = НДСОкрЛок;
            Н.Остаток      = НДСНеОкрЛок - НДСОкрЛок;

            Инд = Инд + 1;
        КонецЦикла;
    КонецЕсли;

    Если Т.Количество() = 0 Тогда
        Возврат; // нечего выравнивать
    КонецЕсли;

    // НДС по документу
    НДСДокНеОкр = СуммаДок * Коэф;
    НДСДок = Окр(НДСДокНеОкр, ТочностьКопеек);

    // Сумма округленного НДС по строкам
    СумОкрНДС = 0;
    Для Каждого Р Из Т Цикл
        СумОкрНДС = СумОкрНДС + Р.НДСОкр;
    КонецЦикла;

    Разница = НДСДок - СумОкрНДС;

    // Если разницы нет — записываем значения в строки
    Если Макс(Разница, -Разница) < 0.005 Тогда
        Для Каждого Р Из Т Цикл
            Р.Строка.СуммаНДС = Окр(Р.НДСОкр, ТочностьКопеек);
        КонецЦикла;
        Возврат;
    КонецЕсли;

    // Количество копеек для распределения
    Копеек = Цел(Окр(Макс(Разница, -Разница) * 100, 0));

    // Таблица кандидатов
    Кандидаты = Новый ТаблицаЗначений;
    Кандидаты.Колонки.Добавить("Остаток");
    Кандидаты.Колонки.Добавить("СуммаСтроки");
    Кандидаты.Колонки.Добавить("Индекс");
    Кандидаты.Колонки.Добавить("Ссылка"); // ссылка на строку Т

    Если Разница > 0 Тогда
        // Нужно добавить копейки
        Для Каждого Р Из Т Цикл
            Если Р.НДСОкр >= ПорогМалойСтроки Тогда
                НК = Кандидаты.Добавить();
                НК.Остаток = Р.Остаток;
                НК.СуммаСтроки = Р.СуммаСтроки;
                НК.Индекс = Р.Индекс;
                НК.Ссылка = Р;
            КонецЕсли;
        КонецЦикла;

        // Если после фильтра никого — берём все строки
        Если Кандидаты.Количество() = 0 Тогда
            Для Каждого Р Из Т Цикл
                НК = Кандидаты.Добавить();
                НК.Остаток = Р.Остаток;
                НК.СуммаСтроки = Р.СуммаСтроки;
                НК.Индекс = Р.Индекс;
                НК.Ссылка = Р;
            КонецЦикла;
        КонецЕсли;

        Кандидаты.Сортировать("Остаток Убыв, СуммаСтроки Убыв, Индекс Возр");

        Пока Копеек > 0 Цикл
            Изменено = Ложь;
            Для Каждого К Из Кандидаты Цикл
                К.Ссылка.НДСОкр = К.Ссылка.НДСОкр + 0.01;
                Копеек = Копеек - 1;
                Изменено = Истина;
                Если Копеек = 0 Тогда Прервать; КонецЕсли;
            КонецЦикла;
            Если НЕ Изменено Тогда Прервать; КонецЕсли;
        КонецЦикла;

    Иначе // Разница < 0 — нужно отнять копейки
        Для Каждого Р Из Т Цикл
            Если Р.НДСОкр >= 0.01 И Р.НДСОкр >= ПорогМалойСтроки Тогда
                НК = Кандидаты.Добавить();
                НК.Остаток = Р.Остаток;
                НК.СуммаСтроки = Р.СуммаСтроки;
                НК.Индекс = Р.Индекс;
                НК.Ссылка = Р;
            КонецЕсли;
        КонецЦикла;

        // Если никого — ослабим фильтр (все, где НДСОкр >= 0.01)
        Если Кандидаты.Количество() = 0 Тогда
            Для Каждого Р Из Т Цикл
                Если Р.НДСОкр >= 0.01 Тогда
                    НК = Кандидаты.Добавить();
                    НК.Остаток = Р.Остаток;
                    НК.СуммаСтроки = Р.СуммаСтроки;
                    НК.Индекс = Р.Индекс;
                    НК.Ссылка = Р;
                КонецЕсли;
            КонецЦикла;
        КонецЕсли;

        Кандидаты.Сортировать("Остаток Возр, СуммаСтроки Убыв, Индекс Возр");

        Пока Копеек > 0 Цикл
            Изменено = Ложь;
            Для Каждого К Из Кандидаты Цикл
                Если К.Ссылка.НДСОкр >= 0.01 Тогда
                    К.Ссылка.НДСОкр = К.Ссылка.НДСОкр - 0.01;
                    Копеек = Копеек - 1;
                    Изменено = Истина;
                    Если Копеек = 0 Тогда Прервать; КонецЕсли;
                КонецЕсли;
            КонецЦикла;
            Если НЕ Изменено Тогда Прервать; КонецЕсли;
        КонецЦикла;

    КонецЕсли;

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

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

Вызывать будем из модуля документа из процедуры "ПередЗаписью", проверку на ставку "БезНДС", оформим там же, так как нам нужно обсчитывать только 5% и 20%

	НовыйНабор = РегистрыСведений.СтавкаНДСОрганизации.СоздатьНаборЗаписей();
	НовыйНабор.Отбор.Организация.Установить(Организация);
 	НовыйНабор.Прочитать();
 
 Если НовыйНабор[0].СтавкаНДС <> Перечисления.СтавкиНДС.БезНДС Тогда
  ПересчетНДСРавенство.ВыровнятьНДСПоДокументуТоварыУслуги(ЭтотОбъект);
 КонецЕсли;

Проверено на релизе 10.3.8.9.

PS - может, кому будет полезно.

Вступайте в нашу телеграмм-группу Инфостарт

См. также

Адаптация типовых решений 1С v8.3 1С:Документооборот Россия Платные (руб)

Расширение конфигурации для «1С:Документооборот КОРП», редакция 3.0. позволяет: 1.использовать произвольные табличные части в качестве дополнительных реквизитов к документу; 2 использовать произвольные табличные части в шаблонах в формате docx для автоматического заполнения таблиц.

31800 руб.

29.06.2023    9752    30    15    

38

Банковские операции Адаптация типовых решений Бухгалтер Пользователь 1С v8.3 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

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

9600 руб.

17.06.2025    1726    5    0    

5

Логистика, склад и ТМЦ Адаптация типовых решений Пользователь 1С v8.3 1С:Управление нашей фирмой 1.6 1С:Управление нашей фирмой 3.0 Россия Управленческий учет Платные (руб)

Чтобы не допустить путаницы с обещаниями клиентам и для четкого контроля исполнения заказов мы используем резервирование товаров. Расширение для УНФ, чтобы автоматически отменять старые резервы и не мешалть эффективно продавать.

9000 руб.

02.08.2023    6445    23    5    

39

Адаптация типовых решений Бухгалтер 1С v8.3 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бюджетный учет Платные (руб)

Разработка для упрощения процедуры передачи данных о выплатах для конфигурации 1С:ЗиКГУ. Данное расширение предоставляет возможность экспортировать данные «Распоряжения» непосредственно из документа "Ведомость в банк" в формате XML.

3840 руб.

13.11.2024    2427    3    4    

4

Адаптация типовых решений Программист 1С v8.3 1С:Бухгалтерия 3.0 1С:Зарплата и Управление Персоналом 3.x Россия Абонемент ($m)

Маленькая заметка (в трех разных масштабах) для тех, кто часто видит окно при входе в ЗУП «Новые сообщения для расшифровки по 1С-Отчетность», которое появляется через 60 секунд после запуска программы, как раз когда вы уже добрались до интересующей вас формы и начали в ней что-то активно делать:

1 стартмани

17.06.2024    7872    82    Znata_PI    12    

22

Адаптация типовых решений Программист Пользователь 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Абонемент ($m)

Каждый из нас сталкивается с ситуацией, когда какой-нибудь менеджер показывает свой Excel и рассказывает, как он что-то из 1С копирует в него, снабжает пояснениями, выделяет цветом и т.д. и т.п. Заканчивается все просьбой сделать вот чтобы также было в 1С. И оказывается такой человек (почти с гарантией) либо лучшим продажником, либо каким-то важным, за все отвечающим, - на ком все держится.

2 стартмани

22.04.2024    7329    dimanich70    17    

22

БСП (Библиотека стандартных подсистем) Адаптация типовых решений Программист 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Понадобилось в подменю "Создать на основании" добавить свою команду, которая открывает обработку. В процессе доработок появилась проблема двух подменю "Создать на основании". В статье о том, как решились проблемы.

01.03.2024    17898    dimanich70    11    

26
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. V.Nikonov 124 05.11.25 12:20 Сейчас в теме
А разве штатно Сумма НДС Документа не равна Сумме НДС в строках?
2. weart 05.11.25 12:22 Сейчас в теме
В УТ сумма строк по столбцу СуммаНДС там из за округления разница в копейках. По факту нет.
3. suepifanov 1216 05.11.25 12:24 Сейчас в теме
После вот таких видимо доработок потом получаешь претензии от бухов - у вас тут все неправильно, переделывайте нам документы...
4. weart 05.11.25 12:28 Сейчас в теме
Как не странно, это именно бухи и просили сделать
5. suepifanov 1216 05.11.25 12:28 Сейчас в теме
(4) вот их надо отправить гуглить как это работает
Для отправки сообщения требуется регистрация/авторизация