В практике разработки на платформе 1С нередко возникают задачи технической очистки информационных баз — например, при подготовки рабочей копии для аудита, подготовке базы к сжатию или подготовке демонстрационного стенда. В отличие от стандартного пометки на удаление с последующим контролем ссылочной целостности, непосредственное удаление стирает элементы из базы данных напрямую.
Рассмотрим подробно способы реализации программного непосредственного удаления объектов, проанализируем различия ключевых методов платформы и разберем правила безопасной очистки движений регистров.
Прежде чем переходить к написанию кода, важно осознавать последствия физического удаления записей из таблиц базы данных:
<Объект не найден...>.Обязательное условие: все операции непосредственного удаления необходимо выполнять строго на резервной копии информационной базы.
Разберем классический подход с использованием встроенного языка. Метод Удалить() вызывается у объекта информационной базы и полностью удаляет запись из базы данных. При этом вызове отрабатывают стандартные события модуля объекта (ПередУдалением, ПриУдалении) и подписки на события.
Посмотрим на пример обхода метаданных для удаления документов и справочников:
Запрос = Новый Запрос;
Менеджеры = Новый СписокЗначений;
Менеджеры.Добавить("Документы", "Документ");
Менеджеры.Добавить("Справочники", "Справочник");
Для Каждого Элемент Из Менеджеры Цикл
ВЗапрос = Элемент.Представление;
ТипОбъекта = Метаданные[Элемент.Значение];
Для Каждого Вид Из ТипОбъекта Цикл
ИмяОбъекта = Вид.Имя;
Запрос.Текст = "ВЫБРАТЬ Нечто.Ссылка КАК Ссылка ИЗ " + ВЗапрос + "." + ИмяОбъекта + " КАК Нечто";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ОбъектДляУдаления = Выборка.Ссылка.ПолучитьОбъект();
Если ОбъектДляУдаления <> Неопределено Тогда
ОбъектДляУдаления.Удалить();
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЦикла;
Платформа 1С предоставляет глобальную процедуру УдалитьОбъекты(). В отличие от метода Удалить() у конкретного объекта, функция УдалитьОбъекты(МассивСсылок, Ложь) удаляет массив элементов напрямую из таблиц СУБД, минуя обработчики модуля объекта. Это существенно ускоряет процесс обработка больших объемов данных.
Проанализируем пример массового удаления документов с фильтрацией по организации:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| АвансовыйОтчет.Ссылка КАК Ссылка
|ИЗ
| Документ.АвансовыйОтчет КАК АвансовыйОтчет
|ГДЕ
| АвансовыйОтчет.Организация = &Организация";
Запрос.УстановитьПараметр("Организация", ВыбраннаяОрганизация);
Результат = Запрос.Выполнить().Выгрузить();
МассивУдаления = Результат.ВыгрузитьКолонку("Ссылка");
// Второй параметр Ложь означает отключение проверки ссылочной целостности
УдалитьОбъекты(МассивУдаления, Ложь);
Если удаляется проведенный документ, его записи в регистрах накопления, бухгалтерии или сведений могут остаться в базе данных. Чтобы этого не произошло, необходимо предварительно очистить движения документа.
Рассмотрим два варианта очистки движений:
Вариант A. Очистка через коллекции движений объекта
Для Каждого Движение Из ДокументОбъект.Движения Цикл
Движение.Прочитать();
Движение.Очистить();
КонецЦикла;
ДокументОбъект.Записать();
ДокументОбъект.Удалить();
Вариант B. Быстрая очистка через набор записей регистра (оптимально для больших объемов)
Для предотвращения избыточной нагрузки на оперативную память при вызове Прочитать() эффективнее записывать пустой набор записей с отбором по регистратору:
Набор = РегистрыНакопления.Продажи.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(СсылкаНаДокумент);
Набор.Записать(); // Запись пустого набора удаляет записи регистратора
Для корректного и быстрого завершения процедуры удаления рекомендуем соблюдать следующие правила:
РегистрыНакопления[ИмяРегистра].УстановитьИспользованиеИтогов(Ложь) и включите его после завершения обработки.НачатьТранзакцию() и ЗафиксироватьТранзакцию(), чтобы избежать переполнения журнала транзакций СУБД.Тестирование и исправление информационной базы. Отметьте пункт «Проверка логической целостности» и выберите вариант «Очищать ссылки» при обнаружении несуществующих объектов..1CD) выполните процедуру «Сжатие таблиц информационной базы» или запустите chdbfl.exe. В клиент-серверном режиме запустите регламентную процедуру сжатия базы (Shrink) на стороне MS SQL Server или команду VACUUM FULL в PostgreSQL.