Несоответствие остатков стандартным запросом и sql запросом в 1С 7.7: как исправить расхождения без монопольного режима

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

В рамках этой статьи мы подробно разберем, почему возникает этот технический конфликт, как устроена архитектура таблиц регистров 1С 7.7 на MS SQL Server, и как исправить расхождение остатков без необходимости монопольного выгона пользователей из информационной базы.

Выясняем причину: архитектура хранения регистров в 1С 7.7

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

  1. Таблица движений (имеет префикс RAxxxx) — в этой таблице содержатся детальные записи о каждом факте прихода или расхода, совершенном документами-регистраторами. Каждая запись жестко привязана к определенному документу через его уникальный идентификатор.
  2. Таблица итогов/остатков (имеет префикс RGxxxx) — здесь хранятся предварительно рассчитанные остатки ресурсов в разрезе измерений (аналитики) регистра. Данные остатки рассчитываются на конец каждого месяца (периода) и на текущую Точку Актуальности (ТА).

Рассмотрим подробнее механизм работы платформы при формировании отчетов. Когда мы строим отчет по движениям (например, ведомость движения товаров), платформа 1С обращается к таблице RAxxxx. Если вы удалили записи о движениях документа напрямую из SQL, то в этой таблице записей не окажется, и отчет покажет полное отсутствие движений.

Однако, когда отчет или запрос запрашивает текущие остатки, платформа в целях оптимизации быстродействия не пересчитывает все движения с начала времен. Вместо этого она берет уже готовые, предрассчитанные данные напрямую из таблицы итогов RGxxxx. Поскольку при ручном удалении движений из RAxxxx таблица RGxxxx осталась нетронутой, в ней зависли некорректные остатки. Таким образом, мы получаем опасное расхождение: движений нет, а остатки в отчетах есть.

Почему происходит исходный сбой с пометкой удаления

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

  1. Сбои транзакций и блокировки на уровне СУБД. Если в момент отмены проведения или установки пометки удаления произошел сетевой сбой, аварийное отключение клиента или взаимоблокировка (deadlock) на MS SQL Server, транзакция могла выполниться частично. Платформа успела обновить статус документа в журнале 1SJOURN на «помечен на удаление», но транзакция по очистке таблиц регистров RAxxxx и RGxxxx была прервана или откатилась.
  2. Повреждение индексов SQL-таблиц. Из-за устаревших или поврежденных индексов платформа 1С при выполнении стандартного метода очистки движений могла «не увидеть» часть записей в таблицах регистров, пропустив их и оставив в базе данных несогласованность.

Способ 1. Выборочный пересчет регистров с помощью обработки УстановкаТА.ert

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

Посмотрим на пример использования популярной обработки УстановкаТА.ert. Данная обработка позволяет управлять Точкой Актуальности (ТА) и выполнять выборочный пересчет итогов по конкретным регистрам без монопольного захвата базы. Алгоритм ее работы выглядит следующим образом:

  1. Запускаем обработку в режиме предприятия (пользователи могут продолжать работу в системе).
  2. Выбираем из списка тот регистр, по которому возникло расхождение остатков.
  3. Временно сдвигаем Точку Актуальности назад (например, на один документ или на начало дня), а затем возвращаем ее обратно вперед.
  4. В процессе сдвига ТА платформа 1С автоматически инициирует последовательный перерасчет таблицы остатков RGxxxx на основе актуальных и физически существующих движений из таблицы RAxxxx. Все зависшие фантомные остатки будут корректно списаны и приведены в соответствие с реальностью.

Способ 2. Программное исправление через объектную модель 1С (безопасный путь)

Чтобы избежать нарушения ссылочной целостности базы данных, настоятельно рекомендуется не прибегать к прямым SQL-запросам DELETE или TRUNCATE к таблицам RAxxxx без крайней необходимости. Безопаснее написать простую обработку на встроенном языке 1С, которая заставит саму платформу корректно очистить данные во всех связанных таблицах.

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


// Создаем объект для работы с документом
Док = СоздатьОбъект("Документ");
ВыбранныйДок = "Реализация"; // Укажите вид вашего документа

Если Док.НайтиДокумент(СсылкаНаПроблемныйДокумент) = 1 Тогда
    // Шаг 1: Временно снимаем пометку удаления
    Док.СнятьПометкуУдаления();
    
    // Шаг 2: Принудительно делаем документ непроведенным
    Док.СделатьНепроведенным();
    
    // Шаг 3: Вызываем штатный метод очистки всех движений по регистрам
    Док.ОчиститьДвижения();
    
    // Шаг 4: Снова помечаем документ на удаление
    Док.УстановитьПометкуУдаления();
    
    Предупреждение("Документ успешно обработан. Движения корректно удалены из RA и RG!");КонецЕсли;

При таком подходе платформа выполнит все транзакции на уровне СУБД согласованно, гарантируя чистоту как в таблицах движений RAxxxx, так и в таблицах остатков RGxxxx.

Способ 3. Прямой пересчет итогов через SQL-скрипты (для опытных администраторов)

Если объем регистра колоссален, а монопольный доступ получить невозможно, опытные администраторы баз данных прибегают к прямому пересчету итогов через T-SQL. Для этого пишется скрипт, выполняющий следующие действия:

  1. Полностью очищается таблица итогов RGxxxx для проблемного регистра с помощью команды TRUNCATE TABLE.
  2. На основе записей из таблицы движений RAxxxx заново рассчитываются остатки на конец каждого месяца исторического периода и записываются в RGxxxx.

Важно: Этот метод требует глубокого понимания структуры метаданных конкретной конфигурации и файла словаря данных 1cv7.dd, так как имена таблиц и полей в SQL зашифрованы внутренними идентификаторами платформы (например, SP123, IDDOC и т.д.).

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

Чтобы минимизировать вероятность возникновения подобных «глюков» с регистрами в будущем, рекомендуется придерживаться нескольких простых правил обслуживания базы данных:

← На главную