Почему запрос к виртуальной таблице возвращает не свернутые остатки

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

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

Проанализируем суть проблемы

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

  1. Счет 52, Субконто1: «Основной», Сумма: 500
  2. Счет 52, Субконто1: «Основной», Сумма: -490

Хотя визуально строки кажутся идентичными по ключевым полям, платформа с точки зрения СУБД видит их разными. Разберем по шагам, где может скрываться различие.

Выясним причину: NULL против Пустой ссылки

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

NULL в измерении означает, что для данного счета этот вид учета выключен (например, в плане счетов для счета не установлена галочка «Учет по подразделениям»).

Пустая ссылка (например, Справочник.ПодразделенияОрганизаций.ПустаяСсылка()) означает, что учет по этому измерению включен, но само значение в проводке просто не заполнено.

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


ВЫБРАТЬ
    ХозрасчетныйОстатки.Счет,
    ХозрасчетныйОстатки.Подразделение,
    ТИПЗНАЧЕНИЯ(ХозрасчетныйОстатки.Подразделение) КАК ТипПодразделения,
    ХозрасчетныйОстатки.СуммаОстаток
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Остатки(&Граница, Счет = &НужныйСчет) КАК ХозрасчетныйОстатки

Если в результате вы увидите, что в одной строке тип значения — NULL, а в другой — Подразделение (пустая ссылка), то для SQL-сервера это будут абсолютно разные записи, и он не сможет их сгруппировать в одну строку.

Почему данные в регистре «портятся»

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

Когда пользователь «сливает» два подразделения в одно, обработка ищет все ссылки на удаляемое подразделение и заменяет их на новое. Если в регистре были записи с NULL (где подразделение не должно быть заполнено по логике плана счетов), обработка может по ошибке записать туда пустую ссылку или ссылку на новое подразделение. В итоге нарушается логическая целостность: на счете, где учета по подразделениям быть не должно, появляется ссылка на конкретное подразделение.

Способ решения №1: Тестирование и исправление

Самый правильный и безопасный метод — воспользоваться штатным механизмом платформы. Разберем действия по шагам:

  1. Создадим резервную копию базы данных.
  2. Зайдем в Конфигуратор.
  3. Выберем меню Администрирование — Тестирование и исправление.
  4. Установим флаг «Проверка логической целостности».
  5. В настройках при нахождении ошибок выберем «Исправлять».

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

Способ решения №2: Программная корректировка

Если Тестирование и исправление по каким-то причинам недоступно или нужно исправить данные точечно, можно написать небольшую обработку. Проанализируем пример кода для исправления ситуации с измерением Подразделение:


НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент);
НаборЗаписей.Прочитать();

Для Каждого Запись Из НаборЗаписей Цикл
    // Проверяем, нужен ли подразделение на этом счету
    Если Не Запись.Счет.УчетПоПодразделениям Тогда
        Если Запись.Подразделение <> NULL Тогда
            Запись.Подразделение = NULL;
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

НаборЗаписей.Записать();

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

Особенности физических таблиц итогов

Рассмотрим подробнее, почему пересчет итогов не всегда помогает. Регистр бухгалтерии хранит данные в физических таблицах (например, _AccRgAT0, _AccRgAT1 и т.д. — таблицы итогов). Виртуальная таблица Остатки обращается именно к ним. Если в этих таблицах уже «застряли» разные значения (NULL и ссылка), то простой пересчет лишь подтвердит их наличие. Поможет либо полное «Пересчитать итоги» с очисткой таблиц, либо исправление самих движений (регистраторов), после чего итоги обновятся автоматически.

Важный совет: При написании собственных запросов к виртуальным таблицам всегда учитывайте возможность появления NULL в полях соединений. Если вы соединяете таблицу остатков с другой таблицей по измерению, используйте конструкцию ЕСТЬNULL(Таблица.Измерение, ЗначениеПустойСсылки), чтобы избежать потери данных или некорректной группировки в самом запросе.

Резюме

Мы выяснили причину возникновения несвернутых остатков: это конфликт типов данных в измерениях регистра. Всегда проверяйте записи на наличие «лишних» ссылок там, где План счетов предполагает NULL. Регулярное проведение Тестирования и исправления и аккуратная работа с обработками замены ссылок позволят избежать подобных проблем в будущем.

← На главную