Почему при перепроведении документа «Реализация» в 1С:Бухгалтерии сторнируются проводки?

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

При работе в сильно измененных, нетиповых конфигурациях «1С:Бухгалтерия предприятия 3.0» пользователи часто сталкиваются с аномальным поведением системы во время перепроведения документов. Одной из наиболее запутанных проблем является автоматическое сторнирование (минусование) проводок по регистру бухгалтерии при повторном проведении документа. На ОСВ по счету (например, по счету 08.34 или 90) данные обороты затираются, так как система делает сначала обычную проводку, а следом — точно такую же сторнирующую запись «красным».

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

Выясняем первопричину: почему двоятся проводки со знаком минус?

В типовой конфигурации «1С:Бухгалтерия» при перепроведении документа старые проводки просто удаляются из базы данных, а вместо них записываются новые актуальные движения. Появление компенсирующих отрицательных проводок (сторно) в том же самом периоде указывает на работу кастомного (доработанного) алгоритма.

Рассмотрим детально основные технические причины, которые приводят к такому поведению системы:

  1. Логическая ошибка в кастомном коде «аудиторского следа» или механизма «мягкого» проведения. Очень часто разработчики пытаются реализовать алгоритм, который фиксирует изменения в закрытых или текущих периодах. Для этого в коде пишется запрос, считывающий старые движения документа до его проведения. Если этот запрос выполняется внутри транзакции проведения, когда старые проводки еще не очищены платформой, код считывает их, создает сторнирующие записи на ту же сумму, а затем стандартный механизм добавляет новые «плюсовые» записи. В итоге проводки взаимно уничтожаются.
  2. Некорректная настройка свойства «Удаление движений» у документа. Если для документа в Конфигураторе установлено свойство «Не удалять автоматически» или «Удалять при необходимости», старые записи регистра бухгалтерии не очищаются перед началом выполнения процедуры ОбработкаПроведения. Если при этом разработчик не предусмотрел принудительную программную очистку набора записей, система накладывает новые движения на старые, запуская некорректно написанные контроли остатков или корректирующие алгоритмы.
  3. Ошибки в подписках на события (Event Subscriptions). Поскольку конфигурация нетиповая, логика проведения может быть вынесена из модуля самого документа в общие модули, вызываемые через подписки. Особое внимание следует обратить на подписки для событий ОбработкаПроведения документа РеализацияТоваровУслуг или на событие ПриЗаписи регистра бухгалтерии Хозрасчетный.
  4. Применение механизмов расширений конфигурации. Если доработки внедрены через расширения с использованием аннотаций &После или &Вместо для процедуры ОбработкаПроведения, обработчик в расширении может повторно считывать движения документа и накладывать ошибочное сторно.
  5. Использование ручной корректировки движений. Когда на документе установлен флаг «Ручная корректировка» (истина для реквизита РучнаяКорректировка), система должна защищать движения от перезаписи. Если сторонний доработанный регламентный процесс или групповое перепроведение пытается обойти этот запрет программно, это может приводить к генерации корректирующих (сторнирующих) проводок.

Пошаговый план исправления проблемы в Конфигураторе

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

Шаг 1: Проверка флага «Ручная корректировка»

Прежде чем открывать Конфигуратор, провем экспресс-диагностику в режиме «1С:Предприятие»:

  1. Откроем проблемный документ «Реализация (акт, накладная)».
  2. Перейдем в окно просмотра движений документа (нажав кнопку Дт/Кт на панели инструментов).
  3. Проверим, установлен ли флажок «Ручная корректировка (разрешает редактирование движений документа)».
  4. Если флаг установлен, попробуем временно снять его и повторно провести документ. Если проводки пришли в норму — проблема кроется в алгоритмах, которые пытаются программно обрабатывать документы с ручной корректировкой.

Шаг 2: Проверка свойств удаления движений документа

Если ручная корректировка не при чем, переходим в Конфигуратор и анализируем структуру метаданных:

  1. Найдем в дереве метаданных документ РеализацияТоваровУслуг (или соответствующий доработанный документ реализации).
  2. Откроем его палитру свойств и перейдем на вкладку «Движения».
  3. Обратим внимание на свойство «Удаление движений». Для типовых документов рекомендуется устанавливать значение Удалять автоматически. Если там установлено Не удалять автоматически, проанализируем, очищаются ли движения программно в самом начале процедуры проведения.

Шаг 3: Поиск сторнирующих алгоритмов в модуле объекта

Откроем модуль объекта исследуемого документа и перейдем к обработчику проведения. Нам нужно локализовать код, который может умножать суммы на «-1» или добавлять записи со знаком минус.

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


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    
    // ПРИМЕР ОШИБОЧНОГО КОДА:
    // Попытка получить старые проводки текущего документа прямо в транзакции проведения
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Хозрасчетный.СчетДт,
        |	Хозрасчетный.СчетКт,
        |	Хозрасчетный.Сумма
        |ИЗ
        |	РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
        |ГДЕ
        |	Хозрасчетный.Регистратор = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    РезультатЗапроса = Запрос.Выполнить();
    
    Если Не РезультатЗапроса.Пустой() Тогда
        Выборка = РезультатЗапроса.Выбрать();
        Пока Выборка.Следующий() Цикл
            // Формируем сторно-запись на основе старых данных
            ПроводкаСторно = Движения.Хозрасчетный.Добавить();
            ЗаполнитьЗначенияСвойств(ПроводкаСторно, Выборка);
            ПроводкаСторно.Сумма = -Выборка.Сумма; // Здесь происходит зануление!
            ПроводкаСторно.Период = Дата;
        КонецЦикла;
    КонецЕсли;

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

Для исправления такой логики необходимо переписать алгоритм так, чтобы получение старых движений происходило до начала транзакции записи новых проводок, либо использовать временные таблицы или анализировать движения, сохраненные в свойствах объекта при чтении (например, в событии ПередЗаписью).

Шаг 4: Анализ подписок на события

Если в модуле объекта документа подозрительный код отсутствует, велика вероятность, что проводки искажаются «снаружи» через подписки на события. Выполним поиск активных подписок:

  1. В дереве конфигурации развернем ветку «Общие» -> «Подписки на события».
  2. Отберем подписки, у которых в качестве источника (поле Источник) указан документ РеализацияТоваровУслуг (или тип ДокументОбъект), а событием является ОбработкаПроведения или ПриЗаписи.
  3. Также проверим подписки на события регистра бухгалтерии Хозрасчетный (события ПередЗаписью или ПриЗаписи для набора записей).
  4. Перейдем в обработчики этих подписок в общих модулях и установим точки останова на строках добавления записей в движения.

Шаг 5: Использование отладчика для быстрого поиска виновника

Самый надежный и быстрый способ найти виновника автоматического сторно — запустить отладку:

  1. Запустим систему в режиме отладки.
  2. В Конфигураторе откроем модуль регистра бухгалтерии Хозрасчетный (или общий модуль, где формируются движения) и найдем процедуру записи движений.
  3. Установим точку останова с условием. Условием укажем появление отрицательной суммы в наборе записей, например: Проводка.Сумма < 0.
  4. Запустим перепроведение проблемного документа «Реализация».
  5. При срабатывании точки останова откроем панель «Стек вызова» (Call Stack). Стек вызова покажет точную цепочку процедур и функций, приведших к добавлению минусовой проводки. Вы сразу увидите, какая именно доработка (какой общий модуль, расширение или подписка) инициировала сторнирование.

Используя данный системный подход, мы сможем быстро локализовать участок кода, вызывающий появление лишних сторнирующих записей, исправить логическую ошибку разработчиков и вернуть учет по ОСВ в корректное русло.

← На главную