Почему в оборотно-сальдовой ведомости двоится сальдо по дебету и кредиту на счетах затрат и как это исправить?

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

При формировании общей оборотно-сальдовой ведомости (ОСВ) с включенной настройкой развернутого сальдо пользователи иногда сталкиваются с неожиданным поведением: по чисто активным счетам затрат (например, 20 «Основное производство», 25 «Общепроизводственные расходы», 44 «Расходы на продажу») на начало или конец периода появляются одинаковые суммы одновременно по дебету и по кредиту. При этом, если открыть отчет «ОСВ по счету», никаких раздвоений не видно — сальдо свернуто либо вовсе равно нулю. Разберем детально механизм возникновения этой коллизии на уровне платформы «1С:Предприятие» и пошагово рассмотрим способы ее устранения.

Механизм возникновения проблемы на уровне платформы

Для понимания природы ошибки проанализируем, как регистр бухгалтерии Хозрасчетный хранит данные аналитических измерений и признаков учета. В платформе 1С действует жесткое системное правило типизации полей:

  1. Если у счета на уровне плана счетов отключен определенный признак учета (например, валютный учет или учет по подразделениям), то в таблице движений регистра значения полей ВалютаДт, ВалютаКт, ВалютнаяСуммаДт и ВалютнаяСуммаКт обязаны принимать физическое значение NULL, а не пустую ссылку или число 0.
  2. Если в базе применялись универсальные обработки группового изменения или поиска и замены значений (особенно старые или некорректно написанные внешние обработки), они могут перезаписать набор записей документа. При такой перезаписи поля, в которых должен находиться NULL, нередко заполняются пустыми ссылками соответствующего типа (например, пустая ссылка справочника Валюты) или числовым нулем.
  3. В виртуальной таблице ОстаткиИОбороты регистра бухгалтерии при расчете развернутого сальдо происходит группировка по всем аналитическим измерениям. С точки зрения СУБД и платформы значение NULL и пустая ссылка — это два принципиально разных значения. В итоге проводки по дебету и кредиту попадают в разные строки группировки и не взаимозачитываются. Сальдо расщепляется: одна строка формирует остаток по дебету, а другая — зеркальный остаток по кредиту.

Выясним, почему же в отчете «ОСВ по счету» этой проблемы не видно. В типовых конфигурациях в специализированном отчете по конкретному счету алгоритм компоновки данных жестко ориентирован на признак активности счета. Для активного счета платформа принудительно рассчитывает только дебетовый итог, игнорируя возникший фиктивный кредитовый остаток. В общей же ОСВ разворот строится по всей совокупности измерений, из-за чего скрытый конфликт значений выходит наружу.

Решение 1. Групповое перепроведение документов

Самый простой и безопасный способ вернуть записям регистра правильную структуру — выполнить типовое проведение документов. При проведении документа через стандартные механизмы конфигурации набор записей регистра формируется с нуля, а модули объекта гарантируют корректную расстановку NULL для всех неиспользуемых признаков учета.

  1. Перейдем в раздел Операции — Групповое перепроведение документов.
  2. Укажем период, в котором наблюдаются расхождения в оборотно-сальдовой ведомости.
  3. Запустим процесс перепроведения и дождемся его окончания.
  4. После выполнения процедуры повторно выполним регламентные операции закрытия месяца, чтобы обновить движения по списанию затрат.

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

Бывают ситуации, когда перепроведение документов невозможно: период закрыт от изменений, в базе хранятся ручные корректировки проводок либо перепроведение может сместить партионный учет и расчет себестоимости. В таком случае исправим наборы записей программно, заменив ошибочные пустые ссылки и нули обратно на NULL.

Посмотрим на пример кода внешней обработки, выполняющей обход регистра бухгалтерии и нормализующей записи по регистратору:


ВыборкаРегистраторов = Документы.ОперацияБух.Выбрать(НачалоПериода, КонецПериода);

Пока ВыборкаРегистраторов.Следующий() Цикл
    НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Регистратор.Установить(ВыборкаРегистраторов.Ссылка);
    НаборЗаписей.Прочитать();
    
    Модифицирован = Ложь;
    
    Для Каждого Проводка Из НаборЗаписей Цикл
        // Проверяем счет дебета
        Если ЗначениеЗаполнено(Проводка.СчетДт) Тогда
            Если Не Проводка.СчетДт.Валютный Тогда
                Если Проводка.ВалютаДт <> Неопределено И Проводка.ВалютаДт <> NULL Тогда
                    Проводка.ВалютаДт = Неопределено;
                    Проводка.ВалютнаяСуммаДт = Неопределено;
                    Модифицирован = Истина;
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
        
        // Проверяем счет кредита
        Если ЗначениеЗаполнено(Проводка.СчетКт) Тогда
            Если Не Проводка.СчетКт.Валютный Тогда
                Если Проводка.ВалютаКт <> Неопределено И Проводка.ВалютаКт <> NULL Тогда
                    Проводка.ВалютаКт = Неопределено;
                    Проводка.ВалютнаяСуммаКт = Неопределено;
                    Модифицирован = Истина;
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    Если Модифицирован Тогда
        НаборЗаписей.Записать(Истина);
    КонецЕсли;
КонецЦикла;

// После корректировки наборов необходимо обновить таблицы итогов
РегистрыБухгалтерии.Хозрасчетный.ПересчитатьИтоги();

Разберем важный нюанс: при записи набора через встроенный язык присвоение значения Неопределено реквизиту, не поддерживающему данный тип по метаданным счета, заставляет платформу сохранить в базу данных истинный NULL. Завершающий вызов метода ПересчитатьИтоги() обязателен, так как он синхронизирует агрегированные остатки регистра с исправленными проводками.

Решение 3. Тестирование и исправление базы данных

Если раздвоение сальдо вызвано сбоем в таблицах предварительно рассчитанных итогов (например, при внезапном перезапуске сервера СУБД или сбое транзакции), воспользуемся встроенной сервисной процедурой Конфигуратора:

  1. Создадим резервную копию информационной базы (выгрузка в .dt или средствами СУБД).
  2. Запустим базу в режиме Конфигуратор с административными правами.
  3. Откроем меню Администрирование — Тестирование и исправление...
  4. Установим флаг напротив пункта Пересчет итогов.
  5. При наличии поврежденных ссылок также включим пункты Проверка логической целостности и Проверка ссылочной целостности в режиме «Очищать ссылки».
  6. Нажмем кнопку Выполнить.

Обратите внимание: пересчет итогов устраняет расхождения только тогда, когда сами проводки корректны. Если же в проводках физически хранятся пустые ссылки вместо NULL, тестирование и исправление не поможет — потребуется перепроведение документов или программная нормализация наборов записей.

Рекомендации по предотвращению проблемы

Проанализируем меры предосторожности, которые позволят избежать повторения инцидента в будущем:

  1. Используйте типовые средства замены данных: откажитесь от универсальных внешних обработок прямой замены ссылок в пользу встроенной обработки «Поиск и удаление дублей» (раздел Администрирование — Обслуживание — Корректировка данных). Она учитывает структуру метаданных и правила платформы по заполнению признаков учета.
  2. Корректно настраивайте отчеты: в отчете «Оборотно-сальдовая ведомость» на вкладке «Развернутое сальдо» включайте только активно-пассивные счета расчетов (60, 62, 76). Счета учета производственных и коммерческих затрат (20, 25, 26, 44) не требуют детализации по развернутому сальдо в общей ведомости.
  3. Контролируйте время закрывающих документов: регламентные операции закрытия месяца должны иметь время 23:59:59 и находиться в самом конце хронологической цепочки документов отчетного периода.
← На главную