В типовой конфигурации 1С:Бухгалтерия предприятия 3.0 поле «Всего» в документе «Реализация (акты, накладные, УПД)» является вычисляемым. Это часто создает неудобства для бухгалтеров: если на руках есть первичный документ, в котором указана итоговая сумма с учетом налога, пользователю приходится вручную вычислять сумму без НДС на калькуляторе, чтобы корректно заполнить табличную часть. В данной статье мы подробно рассмотрим, как автоматизировать этот процесс, добавив поле для ввода итоговой суммы, и разберем различные технические подходы к решению этой задачи.
Прежде чем приступать к разработке, проанализируем штатные возможности программы. В 1С:БП 3.0 уже заложен механизм, который позволяет вводить суммы сразу с учетом НДС. Для этого в форме документа над табличной частью необходимо нажать на гиперссылку Цены и валюта. В открывшемся окне следует установить флажок НДС включать в стоимость.
При активации этого режима логика работы табличной части меняется:
Цена начинает подразумевать цену, включающую НДС.Сумма становится эквивалентна сумме «Всего».Это самый безопасный путь, так как он не требует внесения изменений в код и не создает проблем при обновлении конфигурации. Однако, если бухгалтеру принципиально видеть и колонку «Сумма без НДС», и отдельную колонку «Сумма с НДС» одновременно, перейдем к программным методам.
Рассмотрим наиболее правильный с точки зрения архитектуры способ — создание расширения конфигурации. Мы не будем менять структуру табличной части самого документа, чтобы не увеличивать объем базы данных избыточной информацией. Вместо этого мы добавим реквизит формы, который будет служить «калькулятором».
Для реализации этого метода выполним следующие шаги:
РеализацияТоваровУслуг.Услуги и добавим в нее новый реквизит СуммаВсего (тип: Число, 15, 2).ПриИзменении для этого поля.Проанализируем программный код, который должен обеспечивать пересчет. Важно учитывать, включен ли в документе флаг «НДС внутри» или нет, однако для упрощения жизни пользователю мы напишем универсальный алгоритм обратного счета.
&НаКлиенте
Процедура Расширение_СуммаВсегоПриИзменении(Элемент)
ТекущаяСтрока = Элементы.Услуги.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
// Предположим, ставка НДС известна (например, 20%)
// Получаем ставку из данных строки (в 1С это обычно перечисление или справочник)
СтавкаНДС = УчетНДСКлиентСервер.ПолучитьСтавкуНДС(ТекущаяСтрока.СтавкаНДС);
// Рассчитываем сумму без НДС из итоговой суммы
// Формула: СуммаСНДС / (1 + Ставка/100)
ТекущаяСтрока.Сумма = Окр(ТекущаяСтрока.СуммаВсего / (1 + СтавкаНДС / 100), 2);
// Сумма НДС - это разница между итогом и чистой суммой
// Это исключает ошибку округления в 1 копейку
ТекущаяСтрока.СуммаНДС = ТекущаяСтрока.СуммаВсего - ТекущаяСтрока.Сумма;
// Пересчитываем цену, если указано количество
Если ТекущаяСтрока.Количество <> 0 Тогда
ТекущаяСтрока.Цена = ТекущаяСтрока.Сумма / ТекущаяСтрока.Количество;
КонецЕсли;
КонецПроцедуры
Профессиональная разработка в 1С подразумевает использование типовых общих модулей. В «Бухгалтерии предприятия» за расчеты отвечают модули типа ОбработкаТабличнойЧастиКлиент. Выясним, почему это важно: типовые процедуры учитывают множество нюансов (валюту, скидки, спецрежимы налогообложения).
Вместо написания собственных формул, мы можем программно изменять стандартные поля Цена или Сумма и вызывать процедуру, которая «обновит» всю строку так, как это сделала бы сама программа при ручном вводе. Рассмотрим пример, где мы меняем Сумму, а программа сама доначисляет НДС:
&НаКлиенте
Процедура СуммаВсегоПриИзменении(Элемент)
СтрокаТаблицы = Элементы.Услуги.CurrentData;
// Рассчитываем СуммуБезНДС для передачи в типовой механизм
Процент = УчетНДСКлиентСервер.ПолучитьСтавкуНДС(СтрокаТаблицы.СтавкаНДС);
ЧистаяСумма = СтрокаТаблицы.СуммаВсего / (1 + Процент / 100);
// Устанавливаем значение в стандартное поле
СтрокаТаблицы.Сумма = Окр(ЧистаяСумма, 2);
// Вызываем типовой пересчет НДС
СтруктураПересчета = ОбработкаТабличнойЧастиКлиент.ПараметрыПересчетаНДС(Объект);
ОбработкаТабличнойЧастиКлиент.РассчитатьСуммуНДС(СтрокаТаблицы, СтруктураПересчета);
// Пересчитываем цену относительно новой суммы
ОбработкаТабличнойЧастиКлиент.РассчитатьЦенуВСтрокеТабличнойЧасти(СтрокаТаблицы);
КонецПроцедуры
Разберем ситуацию, когда при обратном расчете возникает математическая погрешность. Например, при итоговой сумме 100 рублей и ставке 20%, чистая сумма составит 83.3333... рубля. При округлении до двух знаков мы получим 83.33. Если затем программа применит прямую формулу 83.33 * 0.20, то сумма НДС составит 16.666, что округлится до 16.67. Итого: 83.33 + 16.67 = 100.00. В данном случае все сходится.
Однако на больших объемах или других ставках (например, 10%) возможны расхождения. Рекомендуем всегда устанавливать Сумму НДС как разность между Суммой Всего и Суммой без НДС. Это гарантирует, что итоговый реестр документов и печатная форма будут строго соответствовать введенным пользователем данным.
Так как наше поле СуммаВсего является реквизитом формы и не хранится в базе данных, при открытии документа оно будет пустым. Чтобы пользователь видел актуальные данные, проанализируем событие формы ПриЧтенииНаСервере или ПриОткрытии.
Необходимо обойти табличную часть циклом и заполнить расчетное поле:
&НаСервере
Процедура ЗаполнитьСуммыВсегоНаСервере()
Для Каждого СтрокаУслуги Из Объект.Услуги Цикл
СтрокаУслуги.СуммаВсего = СтрокаУслуги.Сумма + СтрокаУслуги.СуммаНДС;
КонецЦикла;
КонецПроцедуры
Такой подход позволяет поддерживать интерфейс в актуальном состоянии, не затрагивая при этом структуру хранения данных в типовой конфигурации. Это значительно упрощает последующие обновления программы, так как расширение практически не вступает в конфликт с обновлениями основного кода 1С.
Мы рассмотрели три основных пути решения задачи. Первый (типовой) — самый простой и надежный. Второй (кастомный реквизит формы) — наиболее удобный для пользователя, желающего видеть все колонки одновременно. Третий (вызов типовых модулей) — наиболее профессиональный, так как он минимизирует риск ошибок в налоговом учете. Выясним потребности бухгалтерии: если им достаточно штатного механизма «НДС в сумме», лучше остановиться на нем. Если же требуется именно кастомное поле, используйте механизм расширений и обязательно делайте проверку на деление на ноль при пересчете цены.