Часто в процессе оптимизации базы данных 1С:Предприятие возникает задача очистки регистров сведений от устаревших данных. Мы удаляем записи, но забываем, что информация об этих изменениях сохраняется в таблицах регистрации для обмена данными. Если не произвести очистку этих таблиц, база может продолжать разрастаться, а обмены — работать некорректно. Рассмотрим, как программно удалить такие регистрации.
Когда вы удаляете записи из РегистрСведений, платформа не всегда автоматически очищает таблицу изменений для узлов обмена, особенно если это происходит не в транзакции записи самого набора. Основная сложность заключается в том, что метод ПланыОбмена.УдалитьРегистрациюИзменений требует передачи объекта, который однозначно идентифицирует удаляемую запись. В случае с периодическим регистром, простого указания одного измерения недостаточно — платформа ожидает полного соответствия структуры отбора, включая Период.
Для начала нам необходимо определить, какие именно записи числятся в очереди на отправку. Для этого воспользуемся запросом к виртуальной таблице Изменения интересующего нас регистра. Это позволит нам получить точные данные, которые необходимо «погасить».
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СтатусыДоставкиТоваровИзменения.Узел,
| СтатусыДоставкиТоваровИзменения.Период,
| СтатусыДоставкиТоваровИзменения.ЗаказНаПеремещение
|ИЗ
| РегистрСведений.СтатусыДоставкиТоваров.Изменения КАК СтатусыДоставкиТоваровИзменения
|ГДЕ
| СтатусыДоставкиТоваровИзменения.Период < &ДатаОтсечки";
Запрос.УстановитьПараметр("ДатаОтсечки", ТекущаяДата() - 86400 * 365); // Например, за прошлый год
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Теперь, когда у нас есть выборка, важно правильно подготовить объект НаборЗаписей. Ошибка «Недопустимое значение параметра» в 90% случаев связана с тем, что в отбор не были добавлены все ключевые поля. В периодическом регистре Период является частью ключевого набора.
Рассмотрим процесс удаления по шагам:
ПланыОбмена.УдалитьРегистрациюИзменений.
Пока Выборка.Следующий() Цикл
НаборЗаписей = РегистрыСведений.СтатусыДоставкиТоваров.СоздатьНаборЗаписей();
// Обязательно устанавливаем все измерения и Период
НаборЗаписей.Отбор.ЗаказНаПеремещение.Установить(Выборка.ЗаказНаПеремещение);
НаборЗаписей.Отбор.Период.Установить(Выборка.Период);
// Метод Прочитать() поможет инициализировать структуру, если это необходимо
НаборЗаписей.Прочитать();
// Удаляем регистрацию для конкретного узла
ПланыОбмена.УдалитьРегистрациюИзменений(Выборка.Узел, НаборЗаписей);
КонецЦикла;
Полнота отбора: Никогда не забывайте про Период. Если ваш регистр является периодическим (в пределах секунды, дня и т.д.), отсутствие этого поля в Отбор приведет к ошибке выполнения метода. Если вы не уверены, какие именно поля входят в основной отбор, загляните в Конфигуратор в свойства регистра — все поля, помеченные как основные, должны быть заполнены в наборе.
Метод Прочитать(): Использование НаборЗаписей.Прочитать() перед вызовом удаления является хорошим тоном. Хотя сами данные из базы уже могли быть удалены, вызов Прочитать() корректно подготавливает внутреннюю структуру объекта для передачи в платформенный метод удаления регистрации.
Альтернативный путь: Если записей критически много, ручной перебор в цикле может быть долгим. В таких случаях мы рекомендуем использовать встроенную обработку «Регистрация изменений», которая доступна в режиме «1С:Предприятие» через панель функций технического специалиста. Она позволяет выбрать узел и регистр, после чего массово отменить регистрацию без написания кода.
Прямая работа с SQL: Крайне не рекомендуем удалять записи напрямую из таблиц _ChangeR... в SQL-базе данных. Это нарушает целостность внутренней структуры метаданных и может привести к непредсказуемым ошибкам в механизмах обмена данными в будущем. Если программное решение не помогает, лучше выполнить «Тестирование и исправление» информационной базы.
Используя этот подход, вы сможете эффективно очистить систему от «мусорных» записей в таблицах обмена и вернуть вашей базе данных стабильную и быструю работу.