Почему появляются движения в не проведенном документе 1С 7.7 на SQL и как это исправить

Программист 1С v7.7 Управленческий учет
← На главную

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

Причина 1: Рассогласование таблиц RA и _1SJOURN

Проанализируем архитектуру хранения данных 1С 7.7 на MS SQL Server. Сведения о движениях по регистрам хранятся в таблицах RA* (где вместо звездочки указан ID регистра), а статус документа (проведен или нет) записывается в общую таблицу журнала _1SJOURN в колонку CLOSED.

Выясним причину сбоя: в момент записи документа система выполняет транзакцию. Если происходит аварийное завершение работы 1С, обрыв связи с сервером или нехватка места в логе транзакций SQL, может возникнуть ситуация, когда данные в таблицу RA уже «улетели», а флаг CLOSED = 1 в таблице _1SJOURN еще не успел обновиться. Платформа 7.7 не всегда корректно откатывает такие изменения на уровне SQL-сервера, оставляя «мусорные» записи. В результате мы видим движения в регистре, хотя документ считается не проведенным.

Причина 2: Неправильное использование транзакций

Посмотрим на пример кода, который часто становится источником проблем. Автор темы описывает схему проведения связанных объектов внутри явной транзакции в форме документа:


Процедура ПровестиСохранить()
    НачатьТранзакцию();
    флПроведения = 1;
    Если Провести() = 1 Тогда
        // Далее проведение связанных объектов
        // Если что-то не так, флПроведения = 0
    Иначе
        флПроведения = 0;
    КонецЕсли;
    
    Если флПроведения = 0 Тогда
        ОтменитьТранзакцию();
    Иначе
        ЗафиксироватьТранзакцию();
    КонецЕсли;
КонецПроцедуры

Разберем ситуацию: в 1С 7.7 транзакции являются «плоскими». Вызов метода Провести() внутри другой транзакции (НачатьТранзакцию()) крайне опасен. Если внутри штатного механизма проведения 1С произойдет какая-то ошибка, которую платформа попытается обработать самостоятельно, ваша внешняя транзакция может войти в клинч с системной. Это приводит к тому, что блокировки таблиц не снимаются вовремя, а SQL Server может принудительно разорвать соединение, оставляя в базе записи, прошедшие в обход логики контроля ссылочной целостности 1С.

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

Причина 3: Нарушение типизации измерений

Самый тревожный симптом — когда в измерении регистра, имеющем тип «Документ определенного вида», оказывается ссылка на документ другого вида. В SQL-версии 7.7 под типизированное измерение выделяется поле фиксированной длины. Если туда попадает «чужой» IDDOC, это означает, что запись произошла на уровне SQL-движка мимо объектной модели платформы.

Проанализируем, почему это происходит:

  1. Разрушение индексов: Если индексы в таблицах SQL повреждены, 1С может ошибочно адресовать запись не в ту ячейку памяти или таблицы.
  2. Использование внешних компонент: Применение 1C++ или FormEx при неправильном обращении с прямыми запросами или типизацией в памяти может спровоцировать подмену указателей объектов.
  3. Отсутствие Service Pack: Для SQL Server 2000 критически важно наличие Service Pack 4. Старые версии имели ошибки в менеджере блокировок, что приводило к записи «грязных» данных.

Алгоритм решения проблемы

Если вы столкнулись с подобным «глюком», выполним следующие шаги для очистки базы и предотвращения повторений:

Шаг 1: Тестирование и исправление с пересчетом итогов. Это стандартная процедура, но при работе с SQL она не всегда удаляет записи-сироты из таблиц RA. Однако она позволяет синхронизировать таблицу журнала и итогов.

Шаг 2: Манипуляции с Точкой Актуальности (ТА). Как заметил автор, перенос ТА на самый первый документ и обратно на текущую дату заставляет 1С пересчитать все итоги. Это помогает «скрыть» фантомные движения из отчетов, но физически записи в SQL могут остаться.

Шаг 3: Прямая очистка через SQL (для опытных пользователей). Если штатные средства не помогают, необходимо найти записи в таблицах регистра, для которых нет соответствующих проведенных документов в журнале. Пример логики запроса (не используйте без бэкапа!):


-- Пример логики поиска "сирот"
SELECT * FROM RA_Repair_Table -- имя таблицы вашего регистра
WHERE IDDOC NOT IN (SELECT IDDOC FROM _1SJOURN WHERE CLOSED = 1)

Шаг 4: Настройка региональных стандартов. Проверим настройки операционной системы на сервере SQL. В параметрах «Язык и региональные стандарты» должен быть выбран «Русский». Это критично для корректной сортировки строк IDDOC, которые 1С 7.7 использует в качестве первичных ключей.

Как предотвратить проблему в будущем

Проанализируем программный код и настройки среды:

  1. Откажитесь от явных транзакций в формах при вызове метода Провести(). Позвольте платформе самой управлять транзакцией проведения.
  2. Удалите остатки настроек УРБД. Если в базе когда-то использовалась распределенка, но сейчас она не нужна, убедитесь, что таблицы регистрации изменений пусты и не создают лишнюю нагрузку на транзакции.
  3. Обновите SQL Server. Убедитесь, что установлены последние патчи (SP4 для SQL 2000).
  4. Проверьте логику связанных документов. Если документ А при проведении должен проводить документ Б, делайте это через модуль проведения документа А, предварительно проверяя блокировки объектов Б.Блокировка(1).

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

← На главную