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

Программист 1С v8.3 (Обычные формы) Бухгалтерский учет Промышленность, строительство и АПК
← На главную

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

Анализируем причину возникновения проблемы

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

  1. Неопределено (Undefined): Это полное отсутствие значения и типа. Такое часто происходит, когда документ (например, ПлатежноеПоручениеИсходящее) формирует проводки по универсальному алгоритму и просто «не знает» о новом субконто. В базу записывается пустое значение без привязки к конкретному справочнику.
  2. Пустая ссылка (Empty Reference): Это значение, которое имеет конкретный тип (например, СправочникСсылка.ПодразделенияОрганизаций), но указывает на несуществующий элемент. Так пишут проводки специализированные документы (например, ОтражениеЗарплатыВРегламентированномУчете), которые жестко типизируют свои движения.

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

Разбираемся в типах данных: NULL, Неопределено и Пустая ссылка

Для эффективного решения задачи нам необходимо четко различать эти понятия, так как методы работы с ними в коде 1С существенно различаются:

NULL — используется исключительно в языке запросов для обозначения отсутствующих данных (например, при левом соединении, когда во второй таблице нет соответствующей записи). В регистрах бухгалтерии NULL в качестве значения субконто обычно не встречается.

Неопределено — системный тип, обозначающий, что значение еще не инициализировано или тип не определен. В субконто оно попадает, если при записи набора записей в соответствующее поле не было передано ничего.

Пустая ссылка — это инициализированный объект определенного типа. У каждого справочника есть своя пустая ссылка. Она равна Справочники.ПодразделенияОрганизаций.ПустаяСсылка(). Она не равна Неопределено.

Метод 1: Программная корректировка записей регистра

Если документов много и они относятся к прошлым периодам, перепроводить их — не самый лучший вариант. Гораздо быстрее и безопаснее воспользоваться прямой модификацией записей регистра бухгалтерии без перепроведения документов. Проанализируем пример кода, который поможет «схлопнуть» аналитику, установив во всех записях единую пустую ссылку.


// Пример обработки для исправления пустых субконто
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |   ХозрасчетныйДвиженияССубконто.Регистратор КАК Регистратор
    |ИЗ
    |   РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто КАК ХозрасчетныйДвиженияССубконто
    |ГДЕ
    |   ХозрасчетныйДвиженияССубконто.СчетКт = &Счет
    |   И ХозрасчетныйДвиженияССубконто.СубконтоКт2 = НЕОПРЕДЕЛЕНО"; // Укажите нужный номер субконто

Запрос.УстановитьПараметр("Счет", ПланыСчетов.Хозрасчетный.НДФЛ); // Например, 68.01
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    Набор = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
    Набор.Отбор.Регистратор.Установить(Выборка.Регистратор);
    Набор.Прочитать();
    
    Изменено = Ложь;
    Для Каждого Запись Из Набор Цикл
        // Проверяем Кредит счета
        Если Запись.СчетКт = ПланыСчетов.Хозрасчетный.НДФЛ Тогда
            // Если в субконто Неопределено - заменяем на пустую ссылку
            Если Запись.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Подразделения] = Неопределено Тогда
                Запись.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Подразделения] = Справочники.ПодразделенияОрганизаций.ПустаяСсылка();
                Изменено = Истина;
            КонецЕсли;
        КонецЕсли;
        
        // Аналогично можно проверить Дебет (СчетДт и СубконтоДт)
    КонецЦикла;
    
    Если Изменено Тогда
        Набор.Записать(); // Записываем изменения без перепроведения документа
        Сообщить("Исправлен документ: " + Выборка.Регистратор);
    КонецЕсли;
КонецЦикла;

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

Метод 2: Универсальное решение через «составной тип»

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

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

Метод 3: Предотвращение проблемы в будущих периодах

Чтобы проблема не повторялась при создании новых документов, рекомендуется реализовать подписку на событие. Рассмотрим этот механизм подробнее.

  1. Создадим новую Подписку на событие в дереве метаданных.
  2. В качестве источника выберем РегистрБухгалтерииНаборЗаписей.Хозрасчетный.
  3. Событие — ПередЗаписью.
  4. В обработчике события напишем код, который будет проверять тип субконто перед сохранением в базу.

Процедура ПередЗаписьюДвиженийХозрасчетный(Источник, Отказ, Замещение) Экспорт
    Для Каждого Запись Из Источник Цикл
        // Проверяем наличие счета 68.01 в проводке
        Если Запись.СчетКт = ПланыСчетов.Хозрасчетный.НДФЛ Тогда
             // Проверяем тип конкретного субконто
             Если Запись.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Подразделения] = Неопределено Тогда
                 Запись.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Подразделения] = Справочники.ПодразделенияОрганизаций.ПустаяСсылка();
             КонецЕсли;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

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

Важное замечание по счету 68.01 (НДФЛ)

Проанализируем ситуацию со стороны методологии учета. В типовой конфигурации УПП счет 68.01 тесно связан с регистрами накопления по НДФЛ. Добавление субконто Подразделение на этот счет только в бухгалтерском плане счетов может привести к тому, что бухгалтерские данные в разрезе подразделений перестанут сходиться с налоговой отчетностью (6-НДФЛ, 2-НДФЛ), так как налоговый учет ведется по регистрам накопления, где своя логика определения подразделений (часто по регистрации в ИФНС).

Совет: Перед тем как внедрять подобную аналитику, убедитесь, что бухгалтерия понимает, как она будет сверять эти данные в дальнейшем.

Резюме

Для исправления «раздвоения» пустых строк в ОСВ мы выполнили следующие шаги:

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

← На главную