В процессе разработки и сопровождения конфигураций на платформе «1С:Предприятие 8» программисты регулярно сталкиваются с необходимостью изменить логику проведения документов. Иногда требуется полностью отказаться от формирования движений конкретного документа по определенному регистру (например, по РегистрБухгалтерии1 или регистру накопления).
В такой ситуации возникает закономерный вопрос: что произойдет с уже существующими в базе данных движениями? Удалятся ли они автоматически? Останутся ли «висеть» в СУБД в виде битых ссылок со значением «Объект не найден...»? И как эти процессы отражаются на уровне таблиц базы данных под управлением MS SQL Server или PostgreSQL?
Для того чтобы детально разобраться в этой теме, мы должны четко разделить задачу на два принципиально разных сценария, так как поведение платформы 1С и СУБД в них кардинально отличается.
---
Рассмотрим ситуацию, когда разработчик открывает Конфигуратор, находит нужный регистр (например, регистр бухгалтерии или регистр накопления), переходит на вкладку «Регистраторы» и снимает галочку у определенного документа (например, у Документ1). После этого выполняется обновление конфигурации базы данных (клавиша F7).
Проанализируем, что происходит в этот момент на уровне СУБД и в самой платформе:
DELETE FROM _AccRegXXX WHERE _RecorderTRef = ...), либо через создание временной таблицы. Во втором случае создается новая таблица регистра с обновленной структурой, в нее копируются только валидные данные (записи по оставшимся регистраторам), после чего старая таблица удаляется, а новая переименовывается.<Объект не найден...>? Нет, не будет. Поскольку платформа полностью и безвозвратно удаляет строки из таблицы физического регистра на уровне СУБД, никаких «ошметков» или записей с битыми ссылками в этом регистре не останется.---
Теперь разберем второй, более частый сценарий. Разработчик оставляет документ в списке регистраторов в Конфигураторе, но заходит в модуль этого документа и комментирует или удаляет код формирования движений внутри процедуры ОбработкаПроведения (или в обработчиках подписок на события).
Выясним, к чему приведет простое обновление конфигурации в этом случае:
Существующие записи в СУБД не изменятся автоматически. Само по себе изменение программного кода в модуле объекта при обновлении базы данных никак не влияет на уже записанные в СУБД строки в таблицах регистров. Все старые проводки и движения существующих документов останутся лежать в базе в первозданном виде.
Что произойдет с движениями при дальнейших действиях пользователей с конкретным документом?
Удаление движений в Конфигураторе:
ОбработкаПроведения платформа сначала очистит все старые движения документа в СУБД. Затем запустится ваш новый пустой код проведения. Поскольку новый код ничего не записывает, документ останется проведенным, но его движения в регистре полностью исчезнут.Записать() пустого набора), то старые движения так и останутся в СУБД нетронутыми, несмотря на то, что документ был перепроведен.---
Иногда при формировании отчетов или просмотре движений в регистрах программисты видят в поле Регистратор битую ссылку вида <Объект не найден...> (83:af8700155d05070111e3b2e9bc83a152).
Рассмотрим причины возникновения этой проблемы. Строка <Объект не найден...> появляется только тогда, когда сам документ-источник был физически удален из базы данных, но записи по нему в таблице регистра остались.
Платформа 1С устроена так, что при стандартном интерактивном или программном удалении объектов проверяется ссылочная целостность, а движения удаляются автоматически. Однако сбой может произойти в следующих случаях:
Удалить() вместо штатной пометки удаления и последующего удаления помеченных объектов. Либо удаление производилось прямыми SQL-запросами в обход объектной модели платформы 1С.Как исправить битые ссылки в регистрах?
Для устранения этой проблемы рекомендуется выполнить процедуру «Тестирование и исправление» (ТиИ) через Конфигуратор:
Также вы можете решить эту проблему программно. Разберем пример кода, который находит записи с битыми ссылками в регистре накопления и очищает их:
Выборка = РегистрыНакопления.РегистрНакопления1.Выбрать();
Пока Выборка.Следующий() Цикл
// Проверяем, что регистратор не существует в базе
Если Выборка.Регистратор.ПолучитьОбъект() = Неопределено Тогда
// Создаем пустой набор записей с отбором по битой ссылке
Набор = РегистрыНакопления.РегистрНакопления1.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(Выборка.Регистратор);
// Записываем пустой набор, удаляя тем самым движения из СУБД
Набор.Записать();
КонецЕсли;
КонецЦикла;
---
Подведем итоги нашего анализа. Выбор метода «отмены» движений зависит от ваших конечных целей:
ОбработкаПроведения). Старые движения при этом не пострадают, пока пользователи не решат перепровести старые документы.