В практике разработчика на платформе 1С:Предприятие 7.7 (особенно при использовании SQL-версии) иногда встречается труднообъяснимая ситуация: документ не проведен, флаг проведения в журнале отсутствует, но движения по регистрам (которые пользователи часто называют «проводками») существуют и влияют на итоги. Ситуация усложняется, когда в измерения регистра попадают ссылки на типы документов, которые там физически не должны находиться. Рассмотрим подробнее причины этого явления и разберем по шагам методы борьбы с «фантомными» записями.
Проанализируем архитектуру хранения данных 1С 7.7 на MS SQL Server. Сведения о движениях по регистрам хранятся в таблицах RA* (где вместо звездочки указан ID регистра), а статус документа (проведен или нет) записывается в общую таблицу журнала _1SJOURN в колонку CLOSED.
Выясним причину сбоя: в момент записи документа система выполняет транзакцию. Если происходит аварийное завершение работы 1С, обрыв связи с сервером или нехватка места в логе транзакций SQL, может возникнуть ситуация, когда данные в таблицу RA уже «улетели», а флаг CLOSED = 1 в таблице _1SJOURN еще не успел обновиться. Платформа 7.7 не всегда корректно откатывает такие изменения на уровне SQL-сервера, оставляя «мусорные» записи. В результате мы видим движения в регистре, хотя документ считается не проведенным.
Посмотрим на пример кода, который часто становится источником проблем. Автор темы описывает схему проведения связанных объектов внутри явной транзакции в форме документа:
Процедура ПровестиСохранить()
НачатьТранзакцию();
флПроведения = 1;
Если Провести() = 1 Тогда
// Далее проведение связанных объектов
// Если что-то не так, флПроведения = 0
Иначе
флПроведения = 0;
КонецЕсли;
Если флПроведения = 0 Тогда
ОтменитьТранзакцию();
Иначе
ЗафиксироватьТранзакцию();
КонецЕсли;
КонецПроцедуры
Разберем ситуацию: в 1С 7.7 транзакции являются «плоскими». Вызов метода Провести() внутри другой транзакции (НачатьТранзакцию()) крайне опасен. Если внутри штатного механизма проведения 1С произойдет какая-то ошибка, которую платформа попытается обработать самостоятельно, ваша внешняя транзакция может войти в клинч с системной. Это приводит к тому, что блокировки таблиц не снимаются вовремя, а SQL Server может принудительно разорвать соединение, оставляя в базе записи, прошедшие в обход логики контроля ссылочной целостности 1С.
Важно: Проведение связанных объектов лучше выносить в модуль документа в процедуру ОбработкаПроведения, чтобы всё выполнялось в рамках одной системной транзакции без явных вызовов команд управления транзакциями в форме.
Самый тревожный симптом — когда в измерении регистра, имеющем тип «Документ определенного вида», оказывается ссылка на документ другого вида. В SQL-версии 7.7 под типизированное измерение выделяется поле фиксированной длины. Если туда попадает «чужой» IDDOC, это означает, что запись произошла на уровне SQL-движка мимо объектной модели платформы.
Проанализируем, почему это происходит:
1C++ или FormEx при неправильном обращении с прямыми запросами или типизацией в памяти может спровоцировать подмену указателей объектов.Если вы столкнулись с подобным «глюком», выполним следующие шаги для очистки базы и предотвращения повторений:
Шаг 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).Подводя итог, можно сказать, что появление движений у непроведенного документа в 1С 7.7 — это всегда следствие прерванной транзакции или низкоуровневого сбоя СУБД. Сочетание правильной логики кода и актуального состояния SQL-сервера позволяет полностью исключить возникновение подобных багов.