При активном использовании механизмов синхронизации (например, при выгрузке данных из 1С:Управление торговлей 10.3 в 1С:Бухгалтерия предприятия 3.0) пользователи часто сталкиваются с крайне коварным поведением системы. В Оборотно-сальдовой ведомости (ОСВ) по счету 41 внезапно возникает непонятное сальдо на определенную дату. Однако при попытке детализировать этот остаток — открыть «Карточку счета» или «Отчет по проводкам» — мы не обнаруживаем абсолютно никаких документов-регистраторов за этот период. Карточка счета оказывается пустой, а сумма в ОСВ продолжает отображаться.
Давайте подробно разберем, почему возникает эта проблема, как устроена архитектура хранения данных в 1С на физическом уровне и какими методами можно полностью ликвидировать подобные «фантомные» остатки.
Для того чтобы понять природу этой ошибки, нам необходимо заглянуть во внутреннюю структуру СУБД (например, MS SQL Server или PostgreSQL), где развернута база 1С. Платформа 1С:Предприятие для хранения бухгалтерских проводок использует две основные группы таблиц в базе данных:
_AccRg. В ней хранятся физические записи проводок, каждая из которых жестко привязана к своему документу-источнику (свойство Регистратор). Именно на основании этой таблицы строятся детальные отчеты: «Карточка счета», «Анализ субконто» и «Отчет по проводкам»._AccRgT. Для ускорения работы система не рассчитывает остатки с самого начала ведения учета при каждом формировании ОСВ. Вместо этого платформа хранит уже рассчитанные остатки и обороты в разрезе месяцев и субконто в специальных суммовых таблицах. Оборотно-сальдовая ведомость берет готовые цифры именно отсюда.В процессе обмена данными, аварийного завершения транзакции или некорректного программного изменения документов сторонними обработками происходит **рассинхронизация** этих таблиц. В таблице итогов зависает «фантомная» запись с суммой, в то время как в таблице движений реальная проводка отсутствует или была удалена. В результате ОСВ за конкретный день показывает остаток, а детальные отчёты не выводят ничего, так как им физически не за что зацепиться.
Многие специалисты сразу запускают процедуру «Тестирование и исправление» (ТиИ) с флагом «Пересчет итогов». Однако на SQL-базах этот шаг часто завершается безрезультатно. Платформа оптимизирует запросы и может проигнорировать пересчет тех периодов, которые она считает «чистыми». Более того, если в регистре бухгалтерии Хозрасчетный задействован механизм разделения итогов, сбойная запись может находиться в одной из параллельных точек хранения (так называемых сплитах), блокируя стандартные алгоритмы пересчета.
Ниже мы рассмотрим пошаговые сценарии и методы исправления этой ситуации — от простых интерактивных действий до низкоуровневой работы с базой данных.
Самый простой и безопасный способ заставить систему принудительно пересчитать все итоги с нуля — это их полное временное отключение. При отключении итогов платформа физически очищает таблицы _AccRgT в SQL-базе. При последующем включении таблицы заполняются заново на основе реальных проводок из таблицы движений.
Выполним следующие шаги:
После выполнения этих действий сформируем ОСВ по счету 41 за проблемный период и проверим результат.
Если предыдущий шаг не принес результата, велика вероятность, что фантомный остаток удерживается механизмом разделения итогов. Для исправления ситуации выполним пересчет в монопольном режиме без разделения:
Довольно часто «фантомы» возникают из-за человеческого фактора или ошибок алгоритмов сериализации XML при обмене. Например, документ от 02.10.2018 из-за опечатки записывается в регистр с датой 02.10.0218 или 02.10.2118. ОСВ за стандартные периоды эту запись не видит, но при определенных манипуляциях с границами дат в отчете сумма начинает «вылезать».
Для поиска таких аномалий воспользуемся «Консолью запросов». Напишем и выполним следующий запрос:
ВЫБРАТЬ
Хозрасчетный.Период КАК Период,
Хозрасчетный.Регистратор КАК Регистратор,
Хозрасчетный.Субконто1 КАК Номенклатура,
Хозрасчетный.Сумма КАК Сумма
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
Хозрасчетный.Счет = &Счет41
И (Хозрасчетный.Период < ДАТАВРЕМЯ(2000, 1, 1)
ИЛИ Хозрасчетный.Период > ДАТАВРЕМЯ(2050, 1, 1))
Если запрос вернул строки, мы обнаружим документы, которые улетели в глубокое прошлое или далекое будущее. Нам останется лишь открыть эти документы и исправить в них дату на корректную.
Еще одна классическая техническая проблема — наличие «осиротевших» движений в регистре бухгалтерии. Это происходит, когда документ-регистратор удаляется непосредственно из базы данных (например, обработкой удаления без контроля ссылочной целостности или при сбое транзакции обмена), а записи в регистре проводок остаются жить своей жизнью. При построении карточки счета платформа делает внутреннее соединение с таблицей документов и, не найдя ссылку, отбрасывает эту строку. ОСВ же работает напрямую с итогами и продолжает выводить сумму.
Давайте напишем запрос в консоли для выявления записей с отсутствующим или битым регистратором:
ВЫБРАТЬ
Хозрасчетный.Период КАК Период,
Хозрасчетный.Регистратор КАК Регистратор,
Хозрасчетный.Сумма КАК Сумма
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
Хозрасчетный.Счет = &Счет41
И (Хозрасчетный.Регистратор.Ссылка ЕСТЬ NULL
И НЕ Хозрасчетный.Регистратор = НЕОПРЕДЕЛЕНО)
Если запрос выявил подобные строки (в поле Регистратор будет значение вида <Объект не найден...>), нам необходимо программно очистить эти движения. Для этого мы можем написать простую обработку. В качестве примера приведем программный код для удаления движений по конкретной битой ссылке:
// Предположим, мы получили битую ссылку из запроса
БитаяСсылка = НайтиБитуюСсылкуОпределеннымОбразом();
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(БитаяСсылка);
// Записываем пустой набор записей, тем самым удаляя битые движения из базы данных
НаборЗаписей.Записать();
После программной очистки «осиротевших» проводок обязательно выполните пересчет итогов, описанный в первом способе.
Если вы являетесь системным администратором и база данных работает под управлением MS SQL Server, при этом стандартные средства 1С зависают или работают некорректно, можно прибегнуть к прямому удалению итогов на уровне СУБД.
Важно: Перед выполнением любых операций на уровне SQL обязательно сделайте резервную копию (бэкап) базы данных!
_AccRgT и её вариации (например, таблицы остатков и оборотов)._AccRg трогать нельзя!):
TRUNCATE TABLE _AccRgT12345; -- Имя таблицы в вашей базе может отличаться
В редких случаях фантомные остатки могут быть вызваны кэшированием результатов запросов к виртуальным таблицам на стороне сервера приложений 1С:Предприятия. Если вы провели все операции по очистке и пересчету, а локальные отчеты у некоторых пользователей продолжают показывать неверные данные, выполните очистку серверного кэша:
1C:Enterprise 8.3 Server Agent).C:\Program Files\1cv8\srvinfo\ на Windows-сервере).snccntry, reg_1541 и т.д.).Применяя данные методы последовательно, вы гарантированно избавитесь от любых расхождений между Оборотно-сальдовой ведомостью и детальными отчетами по счету 41, обеспечив абсолютную чистоту и корректность бухгалтерского учета.