Фоновое Задание "Удаление помеченных объектов" (не монопольно)

02.08.13

База данных - Чистка данных

Подробное описание немонопольного удаления помеченных объектов, реализованное как Фоновое Задание.

Вот я, наконец, добрался до давно мучившей меня проблемы - как реализовать Удаление помеченных объектов следующим образом:

а) не монопольно - многие пользователи и Склад работают допоздна, так что выгнать их нет никакой возможности;

б) автоматически, чтобы запустилось Фоновое Задание и удалило весь накопившийся "мусор".

Перелопатив большое количество материала, который нашел на Инфостарте и в сети, пришел к неутешительным выводам - эти варианты мне не подходят, придется обходиться своими силами....

Да и радости не прибавлял тот факт, что в 18-ой платформе была всё таки исправлена древняя ошибка № 20013012, теперь установить Монопольный режим при запуске Удаления помеченных объектов стало практически невозможно.....

Возник вопрос - что удалить, а что оставить? Решили, если есть ссылки на Справочники или Документы - оставляем, а Регистрами Сведений решили пожертвовать (даже если будет урон, то незначительный).

Вот что в результате получилось:

Процедура УдалениеПомеченныхОбъектов() Экспорт

   
УстановитьПривилегированныйРежим(Истина);

    Попытка

       
ПомеченныеОбъекты = НайтиПомеченныеНаУдаление();
       
ТабСсылок = НайтиПоСсылкам(ПомеченныеОбъекты);

       
МассивКУдалению = Новый Массив;
       
ТабНеУдаляемых = ТабСсылок.СкопироватьКолонки();

        Для Каждого
Элемент из ПомеченныеОбъекты Цикл
           
СтрокиСсылки = ТабСсылок.НайтиСтроки(Новый Структура("Ссылка", Элемент));
            Если
СтрокиСсылки.Количество() > 0 Тогда
                Если
СтрокиСсылки.Количество() = 1 Тогда

                    Если Лев(СтрокиСсылки[0].Метаданные.ПолноеИмя(),15) = "РегистрСведений" Тогда
                       
МассивКУдалению.Добавить(Элемент); // Если ссылка на РегистрСведений, то удалять
                       
Продолжить;
                    КонецЕсли;
                    Если
СтрокиСсылки[0].Данные <> Элемент Тогда

                        НоваяСтрока = ТабНеУдаляемых.Добавить();
                       
НоваяСтрока.Ссылка = СтрокиСсылки[0].Ссылка;
                       
НоваяСтрока.Данные = СтрокиСсылки[0].Данные;
                       
НоваяСтрока.Метаданные = СтрокиСсылки[0].Метаданные;
                        Продолжить;
                    Иначе
                       
МассивКУдалению.Добавить(Элемент);
                        Продолжить;
                    КонецЕсли;
                КонецЕсли;
                Если
СтрокиСсылки.Количество() > 1 Тогда // Надо проверить!!!
                    // Может там ссылка на справочник, или документ, или регистр сведений???
                   
НеУдалять = Ложь;
                    Для
й = 0 По СтрокиСсылки.Количество()-1 Цикл
                       
// Проверим метаданные, если ссылка на РегистрСведений, тогда удалять
                       
Если Лев(СтрокиСсылки[й].Метаданные.ПолноеИмя(),15) = "РегистрСведений" Тогда
                            Продолжить;
                        КонецЕсли;
                        Если
СтрокиСсылки[й].Данные <> Элемент Тогда
                           
НеУдалять = Истина; Прервать;
                        КонецЕсли;
                    КонецЦикла;
                   
й = ?(й = Неопределено, 0, й);
                    Если
НеУдалять Тогда
                       
НоваяСтрока = ТабНеУдаляемых.Добавить();
                       
НоваяСтрока.Ссылка = СтрокиСсылки[й].Ссылка;
                       
НоваяСтрока.Данные = СтрокиСсылки[й].Данные;
                       
НоваяСтрока.Метаданные = СтрокиСсылки[й].Метаданные;
                    Иначе
                       
МассивКУдалению.Добавить(Элемент);
                    КонецЕсли;
                КонецЕсли;
            Иначе
               
МассивКУдалению.Добавить(Элемент); // Ссылка вообще не найдена....
           
КонецЕсли;
        КонецЦикла;

        Для Каждого
Элемент из МассивКУдалению Цикл
           
Ссылка = Элемент.Ссылка;
           
Объект = Ссылка.ПолучитьОбъект();
            Попытка
                Если Не
Объект = Неопределено Тогда
                   
Объект.Удалить();
                КонецЕсли;
            Исключение
               
ЗаписьЖурналаРегистрации("Удаление помеченных объектов.",
               
УровеньЖурналаРегистрации.Информация, , ,
               
"Не могу удалить объект " + Объект);
            КонецПопытки;
        КонецЦикла;

       
// Информацию о неудаляемых ссылках сбросим в текстовый файл
       
ТекстДок = Новый ТекстовыйДокумент;
        Для каждого
Ссылка из ТабНеУдаляемых Цикл
           
СтрСообщения = "Объект не удален: " + СокрЛП(Ссылка[0]);
           
СтрСсылка = ", используется в " + СокрЛП(Ссылка[1]);
           
ТекстДок.ДобавитьСтроку(СтрСообщения + СтрСсылка);
        КонецЦикла;
       
ТекстДок.Записать(КаталогВременныхФайлов() + "Undelete.txt");

    Исключение
       
ЗаписьЖурналаРегистрации("Удаление помеченных объектов.",
           
УровеньЖурналаРегистрации.Информация, , , "Не могу удалить выбранные объекты: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;

КонецПроцедуры

Не забывайте важные нюансы:

а) ничего не должно мешать выполнению Фонового Задания, проверяйте Модули объекта справочников и документов на предмет неинициализированных значений переменных (они могут быть определены в Толстом клиенте);

б) запускаться Фоновое задание должно под Полными правами (ну можно ещё сделать Роль "Программист" и наделить её всеми возможными галками);

в) желательно не ограничивать Фоновое Задание временем выполнения, если большая база, то поиск ссылок на удаляемый объект займет большое количество времени.

Пробуйте, ищите и у вас обязательно всё получится.....


Вступайте в нашу телеграмм-группу Инфостарт

См. также

Инструментарий разработчика Чистка данных Свертка базы Инструменты администратора БД Системный администратор Программист Руководитель проекта 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP, УНФ, КА и т.д.). Поддерживаются серверные и файловые базы, управляемые и обычные формы. Может выполнять свертку одновременно в несколько потоков. А так же автоматически, без непосредственного участия пользователя. Решение в Реестре отечественного ПО

14400 руб.

20.08.2024    43726    237    123    

220

Чистка данных Системный администратор Программист 1С v8.3 Управляемые формы 1C:Бухгалтерия 1С:Бухгалтерия 1.6 1С:Бухгалтерия 3.0 1С:ERP Управление предприятием 2 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 1.6 1С:Управление нашей фирмой 3.0 1С:Управление торговлей 10 1С:Управление торговлей 11 1С:Розница 2 1С:Розница 3.0 Платные (руб)

Данные обработки помогут Вам легко и, главное быстро, выполнить удаление любых данных в Ваших базах 1С на платформах 8.1-8.3. Обработки помогут легко просмотреть связи ссылок в виде дерева, выбрать что удалять, а что нет, используя любые отборы. Это позволит уменьшить объем лишней и не нужной информации в справочниках и документах, планах видов характеристик и др. объектах и облегчит работу с данными пользователям и Вам. Понятное расположение команд и настроек, в сочетании с описанием и справкой, еще упростят процесс. (Обновление от 30.09.2025, версия 4.5)

12000 руб.

22.02.2013    142725    281    147    

450

Чистка данных Программист Пользователь 1С v8.3 Управляемые формы 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Зарплата и кадры государственного учреждения 3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Платные (руб)

Обработка позволяет удобно и выборочно удалить данные из базы 1С на управляемых формах например БП 3.0, УТ 11, КА 2, ERP, УНФ, ЗУП 3, Розница и др. Это могут быть неактуальные организации или другие перечни объектов. При этом есть возможность провести анализ пересечений документов с другими организациями и таким образом уберечься от того, что при удалении обороты по другой организации изменятся. Объекты нужно выбирать вручную и после этого запускать команду удаления. Будут удалены все ссылки на них.

5000 руб.

28.11.2019    28578    77    20    

92

Чистка данных Программист 1С v8.3 Управляемые формы 1C:Бухгалтерия 1С:Управление торговлей 10 1С:Управление нашей фирмой 1.6 1С:Управление торговлей 11 Платные (руб)

Данные обработки помогут Вам быстро и просто выполнить перезапись любых ссылочных объектов, а также провести/снять с проведения документы с возможностью выбора регистров и произвольными отборами, в Ваших базах 1С на платформах 8.1-8.3. Обработка позволят найти документы с движениями или без них. Все это дает Вам мощный инструмент для работы. Понятное расположение команд и настроек, в сочетании с описанием и справкой, еще упростят процесс. А также обновления Вы получаете бесплатно в течение года с момента приобретения данных обработок! Данные обработки входят в ТОП-100 продаж, что является залогом популярности, надежности в работе, и признанием других покупателей.

9600 руб.

17.09.2013    806529    58    51    

94

Чистка данных Программист 1С v8.3 1C:Бухгалтерия Платные (руб)

Если в вашей информационной базе крутится очень много данных, или база должна быть доступна 24/7 (как в моем случае), или же вы боитесь запускать тестирование и исправление, НО существует потребность удалить битые ссылки, тогда эта обработка сможет Вам помочь. Обработка выявляет битые ссылки как в самих объектах метаданных, так и в их табличных частях(!), а так же может их удалить.

5136 руб.

23.08.2021    11163    23    3    

29

Оптовая торговля Логистика, склад и ТМЦ Чистка данных Программист Бухгалтер Пользователь 1С v8.3 Оперативный учет 1С:Управление торговлей 11 Россия Управленческий учет Платные (руб)

Если вы начали работать в программном продукте Управление Торговлей, редакция 11 или Комплексная Автоматизация редакция 2 и включили механизм учёта серий, то перейти обратно в учёт без серий будет не так-то просто. Сложность заключается в том, что нужно очистить серии в табличной части документа, например, Реализация Товаров и услуг. Предлагаем алгоритм перехода на учет без серий для программного продукта УТ11. (Очистка серий.)

2400 руб.

09.04.2019    30418    47    15    

50

Чистка данных Системный администратор Программист 1С v8.3 Управляемые формы 1С:Бухгалтерия 3.0 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Управление холдингом 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Управление торговлей 11 1С:Розница 2 Абонемент ($m)

Универсальный инструмент для очистки базы. Работает как на конфигурациях на основе БСП, так и самописных. Позволяет выбрать данные, отобразить форму списка, увидеть структуру метаданных, очистить базу применяя при необходимости условия. Удаление производится по выбранным элементам в таблице значений. Наложение условий позволяет удалить документы по выбранной организации.

1 стартмани

25.12.2023    11244    246    WeterSoft    7    

16

Чистка данных Инструментарий разработчика Системный администратор Программист 1С v8.3 Абонемент ($m)

Очередная вариативная очистка кэша 1С с помощью Исполнителя 3.0.2.2.

1 стартмани

25.10.2023    6700    6    SerVer1C    27    

25
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. V.Nikonov 123 07.08.13 12:25 Сейчас в теме
Однако, не нравится запуск Контроля/Удаления сразу всех Помеченных объектов...
Может реализовать отбор пакетов по N (например 100 объектов)?
2. popro 19.08.13 11:24 Сейчас в теме
я сделал по очереди, мне кажется так удобнее
3. Finder_S 44 17.09.13 16:51 Сейчас в теме
А если ссылка тоже помечена на удаление?
По правильному конечно нужно рекурсией до самого верха добраться и проверить все ссылки и ссылки ссылок на пометку на удаление. Если все помечены, то можно всю ветку удалять.
Но по времени исполнения будет не быстро.
4. buzzzard 51 26.03.14 18:27 Сейчас в теме
(3) Finder_S, мне кажется, если эта зачистка работает по расписанию, то в конце концов любая ветка помеченных объектов удалится. Просто это будет выполнено в несколько проходов. Но по любому это лучше, чем вообще не чистить ;)
5. pyrkin_vanya 501 31.07.14 16:28 Сейчас в теме
Времени нет самому писать. Чувак, выручил. От души )))))))
6. klel 27.01.15 09:34 Сейчас в теме
Большое спасибо за статью, воспользуюсь только наверно переделаю, по отдельному объекту, будет работать в фоне и по ночам
7. Minakov00078 38 31.01.16 21:58 Сейчас в теме
Посмотрел код, вроде грамотно. Универсальность обработки удаления помеченных на удаление не работает пока не удалишь ссылки на регистры сведений. Попробую у себя сделать.
8. ekaterinaeon 19 14.09.16 08:55 Сейчас в теме
:) Спасибо, очень пригодилось!!!
9. WinnerBoy 25.11.16 11:47 Сейчас в теме
Век живи - век учись. Спасибо за статью.
10. user1718973 13.04.22 10:42 Сейчас в теме
11. KamranV21 345 25.12.23 14:47 Сейчас в теме
Большое спасибо, очень пригодилось в УПП.

С вашего позволения, немного переработал процедуру, чтобы также можно было удалить взаимосвязанные объекты: например, когда есть помеченные номенклатура и ее же единица измерения. Также удаление поместил в транзакцию. Возможно, кому-то пригодится:


УстановитьПривилегированныйРежим(Истина);
	
	ПомеченныеОбъекты = НайтиПомеченныеНаУдаление();
	ТаблицыСсылок = НайтиПоСсылкам(ПомеченныеОбъекты);
	
	МассивКУдалению = Новый Массив;
	МассивНеудаляемых = Новый Массив;
	
	ЛюбаяСсылка = Новый ОписаниеТипов;
	ЛюбаяСсылка = Новый ОписаниеТипов(ЛюбаяСсылка, Справочники.ТипВсеСсылки().Типы());
	ЛюбаяСсылка = Новый ОписаниеТипов(ЛюбаяСсылка, Документы.ТипВсеСсылки().Типы());
	ЛюбаяСсылка = Новый ОписаниеТипов(ЛюбаяСсылка, Перечисления.ТипВсеСсылки().Типы());
	ЛюбаяСсылка = Новый ОписаниеТипов(ЛюбаяСсылка, ПланыСчетов.ТипВсеСсылки().Типы());
	ЛюбаяСсылка = Новый ОписаниеТипов(ЛюбаяСсылка, ПланыВидовХарактеристик.ТипВсеСсылки().Типы());
	ЛюбаяСсылка = Новый ОписаниеТипов(ЛюбаяСсылка, Задачи.ТипВсеСсылки().Типы());
	ЛюбаяСсылка = Новый ОписаниеТипов(ЛюбаяСсылка, ПланыВидовРасчета.ТипВсеСсылки().Типы());
	ЛюбаяСсылка = Новый ОписаниеТипов(ЛюбаяСсылка, ПланыОбмена.ТипВсеСсылки().Типы());
	
	СвязанныеОбъекты = Новый ТаблицаЗначений;
	СвязанныеОбъекты.Колонки.Добавить("Объект", ЛюбаяСсылка);
	СвязанныеОбъекты.Колонки.Добавить("СвязанныйОбъект", ЛюбаяСсылка);
	
	Для Каждого Элемент из ПомеченныеОбъекты Цикл
		СтрокиСсылки = ТаблицыСсылок.НайтиСтроки(Новый Структура("Ссылка", Элемент));
		Если СтрокиСсылки.Количество() > 0 Тогда
			Если СтрокиСсылки.Количество() = 1 Тогда
				
				Если Лев(СтрокиСсылки[0].Метаданные.ПолноеИмя(), 15) = "РегистрСведений" Тогда
					МассивКУдалению.Добавить(Элемент);
					Продолжить;
				КонецЕсли;
				Если СтрокиСсылки[0].Данные <> Элемент Тогда
					
					Если ПомеченныеОбъекты.Найти(СтрокиСсылки[0].Данные) = Неопределено Тогда
						МассивНеудаляемых.Добавить(Элемент);
						Продолжить;
					Иначе
						СтрокаСвязи = СвязанныеОбъекты.Добавить();
						СтрокаСвязи.Объект = СтрокиСсылки[0].Данные;
						СтрокаСвязи.СвязанныйОбъект = Элемент;
						МассивКУдалению.Добавить(Элемент);
						Продолжить;	
					КонецЕсли;
				Иначе
					МассивКУдалению.Добавить(Элемент);
					Продолжить;
				КонецЕсли;
			КонецЕсли;
			Если СтрокиСсылки.Количество() > 1 Тогда
				НеУдалять = Ложь;
				Для Сч = 0 По СтрокиСсылки.Количество()-1 Цикл
					Если Лев(СтрокиСсылки[Сч].Метаданные.ПолноеИмя(), 15) = "РегистрСведений" Тогда
						Продолжить;
					КонецЕсли;
					Если СтрокиСсылки[Сч].Данные <> Элемент Тогда
						Если ПомеченныеОбъекты.Найти(СтрокиСсылки[Сч].Данные) = Неопределено Тогда
							НеУдалять = Истина;
						Иначе
							СтрокаСвязи = СвязанныеОбъекты.Добавить();
							СтрокаСвязи.Объект = СтрокиСсылки[Сч].Данные;
							СтрокаСвязи.СвязанныйОбъект = Элемент;
						КонецЕсли;
					КонецЕсли;
				КонецЦикла;
				Если НеУдалять Тогда
					МассивНеудаляемых.Добавить(Элемент);
				Иначе
					МассивКУдалению.Добавить(Элемент);
				КонецЕсли;
			КонецЕсли;
		Иначе
			МассивКУдалению.Добавить(Элемент);
		КонецЕсли;
	КонецЦикла;
	
	Для Каждого Ссылка Из МассивНеудаляемых Цикл
		НайденныеСтроки = СвязанныеОбъекты.НайтиСтроки(Новый Структура("Объект", Ссылка));
		Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
			Индекс = МассивКУдалению.Найти(НайденнаяСтрока.СвязанныйОбъект);
			Если Индекс <> Неопределено Тогда
				МассивКУдалению.Удалить(Индекс);
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
	НачатьТранзакцию();
	
	Попытка
		Для Каждого Элемент Из МассивКУдалению Цикл
			Ссылка = Элемент.Ссылка;
			Объект = Ссылка.ПолучитьОбъект();
			Если Не Объект = Неопределено Тогда
				Объект.Удалить();
			КонецЕсли;
		КонецЦикла;
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ЗаписьЖурналаРегистрации("Удаление помеченных объектов.",
		УровеньЖурналаРегистрации.Информация, , , "Не могу удалить выбранные объекты: " + ОписаниеОшибки());
	КонецПопытки;

Показать
Для отправки сообщения требуется регистрация/авторизация