Почему не отображаются остатки и обороты в разрезе субконто и как это исправить?

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

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

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

Физические причины сбоя: что происходит в СУБД

Чтобы понять суть проблемы, нам необходимо заглянуть под «капот» платформы 1С и СУБД. В регистрах бухгалтерии данные о движениях и итогах хранятся в нескольких физических таблицах СУБД. Основными из них являются:

  1. Таблица движений (основная таблица): содержит общие данные проводок (период, регистратор, счет дебета, счет кредита, суммы).
  2. Таблица значений субконто (_AccRgED): хранит конкретные значения аналитики для каждой проводки. Именно здесь записываются ссылки на физические лица, контрагентов, номенклатуру и т.д.
  3. Таблицы итогов (_AccRgAT, _AccRgCT): оптимизированные таблицы, в которых платформа хранит рассчитанные остатки и обороты в разрезе периодов, счетов и субконто для быстрого построения отчетов.

Когда мы обращаемся к виртуальной таблице РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты, платформа выполняет сложный SQL-запрос со множественными левыми соединениями (LEFT JOIN) между таблицей итогов, таблицей настроек субконто счета и справочниками метаданных.

Если субконто на счете было создано некорректно (например, при программном переносе данных с отключенным контролем, динамическом обновлении конфигурации или сбое реструктуризации СУБД), в таблице значений субконто _AccRgED вместо пустой ссылки правильного типа (например, СправочникСсылка.ФизическиеЛица) может записаться системное значение Неопределено или NULL.

В итоге получается следующая картина:

Рассмотрим детально способы решения этой проблемы.

Способ 1. Создание нового аналогичного счета и замена ссылок (Обходной путь)

Если база данных работает в файловом режиме или у вас нет прямого доступа к СУБД SQL, самым быстрым и безопасным решением будет пересоздание счета. Рассмотрим этот процесс по шагам:

  1. Перейдем в план счетов конфигурации или в режиме «1С:Предприятие» (если счет не предопределенный).
  2. Создадим новый аналогичный счет (например, с кодом 76.аналог), у которого вручную и безпешибочно зададим те же самые виды субконто (например, первое субконто — «Физические лица»).
  3. Воспользуемся стандартной обработкой «Поиск и замена значений» (или аналогичной из состава БСП / Инфостарт).
  4. В качестве заменяемого значения выберем наш «проблемный» счет, а в качестве заменяющего — вновь созданный правильный счет.
  5. Запустим процесс замены. Обработка найдет все упоминания старого счета в документах, проводках, операциях и заменит их на новый счет.
  6. После завершения замены проверим формирование «Оборотно-сальдовой ведомости» по новому счету. Так как структура субконто на новом счете изначально была создана корректно, виртуальные таблицы сформируются правильно, и аналитика отобразится в отчете.
  7. Удалим старый проблемный счет из системы. При необходимости переименуем новый счет, вернув ему прежнее наименование и код.

Способ 2. Очистка таблиц итогов через SQL и полный пересчет

Если база данных развернута на сервере под управлением MS SQL Server или PostgreSQL, мы можем решить проблему на уровне базы данных, не прибегая к долгому процессу замены ссылок в документах (что особенно критично для крупных баз данных объемом в сотни гигабайт). Нам понадобится временно очистить таблицы итогов регистра бухгалтерии и инициировать их пересчет платформой с нуля.

Критически важно: Перед выполнением любых операций в SQL-консоли обязательно сделайте резервную копию (бэкап) базы данных!

Выполним следующие действия:

  1. Определим имена таблиц итогов нашего регистра бухгалтерии. Для этого можно воспользоваться обработками получения структуры хранения базы данных или выполнить запрос к СУБД. Обычно эти таблицы имеют префиксы _AccRgAT (итоги по счетам с субконто) и _AccRgCT (итоги между счетами).
  2. Откроем SQL Server Management Studio (SSMS) и выполним следующий скрипт для полной очистки таблиц итогов регистра (на примере условных имен таблиц):

-- Очищаем таблицы итогов по счетам
TRUNCATE TABLE _AccRgAT024070; -- Итоги по счетам без субконто
TRUNCATE TABLE _AccRgAT124080; -- Итоги по счетам с Субконто 1
TRUNCATE TABLE _AccRgAT224081; -- Итоги по счетам с Субконто 2

-- Очищаем таблицы оборотов между счетами
TRUNCATE TABLE _AccRgCT24083;

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

  1. Запустим базу в режиме «Конфигуратор».
  2. Перейдем в меню Администрирование -> Тестирование и исправление...
  3. Установим флажок только напротив пункта «Пересчет итогов» и нажмем кнопку «Выполнить».

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

Способ 3. Программная коррекция и приведение типов

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

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


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

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

← На главную