В процессе разработки и сопровождения самописных конфигураций на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда данные за прошлые периоды (например, за 2018 год) начинают «всплывать» в текущих расчетах. Особенно остро это проявляется в задачах учета НДФЛ и имущественных вычетов, где расчет должен строго соответствовать текущему налоговому периоду. Разберем детально, почему так происходит и как правильно настроить систему, чтобы старые остатки не искажали результат.
Прежде всего, нам необходимо понять природу возникновения ошибки. В системе 1С РегистрНакопления типа «Остатки» хранит итоги с момента начала ведения учета. Если в 2018 году по конкретному сотруднику был зафиксирован «Приход» по вычету, но не было соответствующего «Расхода» (например, из-за нехватки облагаемого дохода), эта сумма будет висеть в остатках вечно. Платформа 1С не обнуляет регистры автоматически при наступлении нового календарного года.
Проанализируем ситуацию с помощью стандартных средств платформы. Чтобы увидеть «виновника» ошибки, выполним следующие шаги:
РегистрНакопления.Если мы видим, что на начало января уже существует входящий остаток, хотя год только начался, значит, за прошлые годы (в нашем случае — 2018 год) остались незакрытые движения. Именно эта сумма прибавляется к текущим расчетам, вызывая математические ошибки.
Программисты часто допускают ошибку, обращаясь к виртуальной таблице ОстаткиИОбороты без указания жестких границ периода. Рассмотрим подробнее, как работают виртуальные таблицы в 1С:
Если мы используем таблицу Остатки на определенную дату, 1С суммирует все движения «Приход» и вычитает «Расход» от начала времен до указанной точки. В контексте имущественных вычетов это недопустимо без фильтрации по налоговому периоду, так как вычеты за 2018 и 2024 годы — это разные сущности с точки зрения налогового кодекса.
Посмотрим на пример неправильного запроса, который собирает все «хвосты»:
ВЫБРАТЬ
РегистрОстатки.Сотрудник,
РегистрОстатки.СуммаОстаток
ИЗ
РегистрНакопления.ВычетыПоНДФЛ.Остатки(&ДатаРасчета, ) КАК РегистрОстатки
В данном случае система вернет всё, что не было закрыто с 2018 года. Чтобы решить проблему в коде, проанализируем ситуацию и добавим условие по периоду или введем дополнительное измерение.
Если мы выяснили, что 2018 год «не закрыт» из-за ошибок в старых документах или неверной логики переноса данных, самым быстрым способом исправления будет техническая чистка регистра. Мы не будем перепроводить документы пятилетней давности, так как это может «развалить» прошлую отчетность.
Разберем алгоритм действий:
КорректировкаЗаписейРегистров.После проведения этого документа остаток на 01.01.2019 станет нулевым, и проблема в 2024 году исчезнет сама собой.
Если архитектура самописной базы не позволяет оперативно чистить регистры, мы можем изменить логику получения данных в модуле расчета. Рассмотрим вариант, при котором мы игнорируем всё, что было до начала текущего года.
Проанализируем правильный подход к построению запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СУММА(ВычетыОбороты.СуммаПриход) КАК СуммаРазрешенногоВычета,
| СУММА(ВычетыОбороты.СуммаРасход) КАК СуммаИспользованногоВычета
|ИЗ
| РегистрНакопления.ВычетыПоНДФЛ.Обороты(&НачалоГода, &КонецПериода, , ) КАК ВычетыОбороты
|ГДЕ
| ВычетыОбороты.Сотрудник = &Сотрудник";
Запрос.УстановитьПараметр("НачалоГода", НачалоГода(Объект.Дата));
Запрос.УстановитьПараметр("КонецПериода", КонецДня(Объект.Дата));
Запрос.УстановитьПараметр("Сотрудник", ТекущийСотрудник);
Использование виртуальной таблицы Обороты вместо Остатки позволяет нам жестко ограничить выборку текущим годом. Таким образом, сумма 2660,98 из 2018 года просто не попадет в выборку.
Выясним причину, почему данные вообще смешиваются. В типовых решениях, таких как 1С:ЗУП, регистры по НДФЛ всегда имеют измерение НалоговыйПериод или РегистрацияВНалоговомОргане. Если в вашей самописной базе в регистре только измерение Сотрудник, то система «сваливает в одну кучу» вычеты за все годы.
Рассмотрим вариант доработки структуры:
НалоговыйПериод (тип Дата или Число для года).ГДЕ НалоговыйПериод = &ТекущийГод.Это наиболее правильный, «взрослый» метод решения проблемы, который исключит подобные ошибки в будущем.
При работе с имущественными вычетами важно помнить о логике минимальной суммы. Программа должна сравнивать остаток разрешенного вычета и сумму начисленного дохода. Код должен выглядеть примерно так:
// Вычисляем максимально возможный вычет в этом месяце
СуммаВычетаКПрименению = Мин(ДоходСотрудникаЗаМесяц, ОстатокРазрешенногоВычетаНаТекущийГод);
Если же программа, как указано в проблеме, прибавляет остаток 2018 года к доходу или вычету некорректно, это приводит к занижению налоговой базы. Всегда проверяйте актуальность итогов регистра. Рекомендуем зайти в Обслуживание — Управление итогами и убедиться, что итоги рассчитаны по текущую дату. В ряде случаев помогает полное пересчет итогов через Тестирование и исправление в Конфигураторе (флажок «Пересчет итогов»).
Подводя итог, скажем: проблема «незакрытого» 2018 года решается либо административным путем (корректировка остатков), либо программным (фильтрация по периоду в запросах). Для долгосрочной стабильности системы лучше всего внедрить измерение налогового периода в сам регистр.