Поиск битых ссылок

11.02.25

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

Обработка для поиска всех битых ссылок (Объект не найден).

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Поиск битых ссылок с проверкой типов полей
.epf 11,09Kb
6
6 Скачать (1 SM) Купить за 1 850 руб.

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

Вводные данные такие: база около 1 Тб, битых ссылок по оценке десятки тысяч.

Поискав по просторам интернета, ничего идеально подходящего не нашлось, чтоб не уходило в бесконечность.

Однако очень близка к идеалу была статья, она и была взята за основу, только чуть подпилена.

Прошу не судить строго, требовалось сделать быстро, из подручных материалов… Возможно кому-то сэкономит время.

Список доработок:

  1. Вместо выбора конкретных таблиц, сделана возможность выбора на форме классов таблиц (Документы, Справочники и т.д.):

 

 

  1. Добавлена возможность добавления таблиц исключений (например, на некоторые таблицы нет доступа даже у полных прав)

 

 

  1. Добавлено логирование, с заполнением текущей даты и последнего завершенного объекта (например, справочника). Возникла необходимость, так как порой уходит очень надолго, и выбран быстрый вариант доработки.
  2. Основной алгоритм в целом похож на исходную статью, из значимого:
  • добавил сразу проверку на то, что поле имеет один тип и это число.
  • вместо добавлением всего и вся «.Ссылка» сделал левое соединение только к тем таблицам, типы которых действительно встречаются в базе данных. Способа использовал два. Первый – если в поле может быть больше 5 типов, то использовал запрос:
Запрос.Текст = "Выбрать Различные ТипЗначения(" + Поле.Имя + ") Как Тип Из " + ПолноеИмяТаблицы;

Если в поле меньше 5 типов, то делал запросы перебором для каждого типа:

Запрос.Текст = "Выбрать Первые 1 Истина Из " + ПолноеИмяТаблицы + " Где ТипЗначения(" + Поле.Имя + ") = &Тип";

И если запрос не пустой, то делал соединение к этой таблице.

Несмотря на то, что здесь запрос в цикле, это в значительной степени окупается при большом объеме данных. Добавление «.Ссылка» в запрос уводило его в бесконечность. Явное соединение только с используемыми таблицами сократило до минимума.

  1. И еще некоторые дополнения.

Программный код основного алгоритма следующий.

Процедура НайтиСсылкиНаСервере собирает текст запроса и заполняет таблицу на форме с битыми ссылками.

&НаСервере
Процедура НайтиСсылкиНаСервере(МД, ПолноеИмяТаблицы, КэшИсключений)
	
	Если КэшИсключений[ПолноеИмяТаблицы] <> Неопределено Тогда
		Возврат;
	КонецЕсли;
		
	Запрос = Новый Запрос("Выбрать Первые 1 Истина Из " + ПолноеИмяТаблицы);
	Рез = Запрос.Выполнить();
	Если Рез.Пустой() Тогда
		Возврат;
	КонецЕсли;
	
    //массив будет содержать структуры с четырмя элементами:
    //1) Поле - имя и псевдоним в запросе ссылочного поля таблицы
    //2) ПолеЭтоБитаяСсылка - псевдоним в запросе поля булевого типа, которое
    //   в результате запроса будет Истина, если Поле содержит битую ссылку
    //3) МассивИменТаблиц - массив, состоящий из полных имен метаданных,
    //   на которые возможны ссылки из поля
    //4) МожетБытьНеопределено - может ли поле быть равно Неопределено
    МассивОписанийПолей = Новый Массив;
    ДобавитьОписаниеПолей(МассивОписанийПолей, "Измерения", МД, ПолноеИмяТаблицы);
    ДобавитьОписаниеПолей(МассивОписанийПолей, "Ресурсы", МД, ПолноеИмяТаблицы);
    ДобавитьОписаниеПолей(МассивОписанийПолей, "Реквизиты", МД, ПолноеИмяТаблицы);
    ДобавитьОписаниеПолей(МассивОписанийПолей, "РеквизитыАдресации", МД, ПолноеИмяТаблицы);

    Если МассивОписанийПолей.Количество() = 0 Тогда
        Возврат; //ссылочных полей нет
    КонецЕсли;

    //Теперь у нас есть ссылочные поля таблицы и имена таблиц, ссылки на которые
    //они могут содержать можно переходить к конструированию запроса
    ПС = Символы.ПС;
    ТАБ = Символы.Таб;
    ТАБ3 = ТАБ+ТАБ+ТАБ;

    МаксИндексМассиваОписаний = МассивОписанийПолей.Количество() - 1;
	ТекстЗапросаИтоговый = "";
    Для Г = 0 По МаксИндексМассиваОписаний Цикл
	    БлокСсылочныхПолей = "";
	    БлокБулевыхПолей = "";
	    БлокУсловия = "";
		ТекстСоединения = "";
		НаимТаб = "т_" + СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
	    Для К = 0 По МаксИндексМассиваОписаний Цикл

	        ОписаниеПоля = МассивОписанийПолей[К];
			ТекстУсловияНул = "";
			Если Г <> К Тогда
				БулевоВыражение = "ЛОЖЬ";
			Иначе
		        БулевоВыражение = "ВЫБОР КОГДА " + ПС+ТАБ3+
		                ?(ОписаниеПоля.МожетБытьНеопределено, НаимТаб + "." + ОписаниеПоля.Поле + " <> НЕОПРЕДЕЛЕНО И ", "");

		        Для Каждого ИмяТаблицы Из ОписаниеПоля.МассивИменТаблиц Цикл
		            БулевоВыражение = БулевоВыражение + НаимТаб + "." + ОписаниеПоля.Поле
		                                + " <> ЗНАЧЕНИЕ("+ИмяТаблицы+".ПустаяСсылка) И ";
					ИмяСоедТаб = СтрЗаменить(ИмяТаблицы, ".", "_");
					ТекстСоединения = ТекстСоединения + ПС + "ЛЕВОЕ СОЕДИНЕНИЕ " + ИмяТаблицы + " КАК " + ИмяСоедТаб + ПС + "ПО " 
						+ НаимТаб + "." + ОписаниеПоля.Поле + " = " + ИмяСоедТаб + ".Ссылка";
					ТекстУсловияНул = ТекстУсловияНул + " И " + ИмяСоедТаб + ".Ссылка ЕСТЬ NULL"; 

				КонецЦикла;
				ТекстУсловияНул = Сред(ТекстУсловияНул, 4);
				
		        БулевоВыражение = БулевоВыражение+ТекстУсловияНул
		                            +ПС+ТАБ3+"ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ";
			КонецЕсли;							
								
	        БлокСсылочныхПолей = БлокСсылочныхПолей + ТАБ + НаимТаб + "." + ОписаниеПоля.Поле;
	        БлокБулевыхПолей = БлокБулевыхПолей + ТАБ + БулевоВыражение + " КАК "+ОписаниеПоля.ПолеЭтоБитаяСсылка;
	        БлокУсловия = БлокУсловия + ТАБ + БулевоВыражение;

	        Если К <> МаксИндексМассиваОписаний Тогда //дальше будут еще поля
	            БлокСсылочныхПолей = БлокСсылочныхПолей + ","+ПС;
	            БлокБулевыхПолей = БлокБулевыхПолей + "," + ПС;
	            БлокУсловия = БлокУсловия + " ИЛИ " + ПС;
			КонецЕсли;
			

		КонецЦикла;
	    //СОБИРАЕМ ТЕКСТ, ДОБАВЛЯЕМ ТАБЫ И ПЕРЕНОСЫ ЧТОБЫ БЫЛО КРАСИВО
	    ТекстЗапроса =  "ВЫБРАТЬ" +ПС+ПС+ БлокСсылочныхПолей + ","+ПС+БлокБулевыхПолей+
						//ПС+ПС+"ИЗ " + ПолноеИмяТаблицы+
	                    ПС+ПС+"ИЗ " + ПолноеИмяТаблицы+ " КАК "+НаимТаб+ТекстСоединения+
	                    ПС+ПС+"ГДЕ"+ПС+ПС+ БлокУсловия;
		ТекстЗапросаИтоговый = ТекстЗапросаИтоговый + ТекстЗапроса;
		Если Г <> МаксИндексМассиваОписаний Тогда //дальше будут еще поля
			ТекстЗапросаИтоговый = ТекстЗапросаИтоговый + ПС + ПС + "ОБЪЕДИНИТЬ ВСЕ" + ПС + ПС;
	    КонецЕсли;
			
	КонецЦикла;

   Запрос = Новый Запрос(ТекстЗапросаИтоговый);

	Попытка
    	Выборка = Запрос.Выполнить().Выбрать();
	Исключение
		Сообщить("Ошибка при обработке таблицы: " + ПолноеИмяТаблицы);
		ОписаниеОшибки = ОписаниеОшибки();
		Сообщить(ОписаниеОшибки);
	
	КонецПопытки;

    //Обходим записи с битыми ссылками и по булевым полям смотрим, какие именно поля содержат битые ссылки
	КэшСсылок = Новый Соответствие;
    Пока Выборка.Следующий() Цикл
        Для Каждого ОписаниеПоля Из МассивОписанийПолей Цикл
            Если Выборка[ОписаниеПоля.ПолеЭтоБитаяСсылка] Тогда //ИСТИНА, значит ссылка битая

                БитаяСсылка = Выборка[ОписаниеПоля.Поле];
				БитаяСсылкаСтрока = КэшСсылок[БитаяСсылка];
				Если БитаяСсылкаСтрока = Неопределено Тогда
					БитаяСсылкаСтрока = Строка(БитаяСсылка); 
					КэшСсылок.Вставить(БитаяСсылка, БитаяСсылкаСтрока);				
					Если СтрНачинаетсяС(БитаяСсылкаСтрока, "<Объект не найден>") Тогда	//Есть ошибка алгоритма, что если в составном поле есть строка и ссылка, то строка тоже идентифицируется как битая ссылка
						НовСтр = Табл.Добавить();
						НовСтр.БитаяСсылка = БитаяСсылкаСтрока;
					КонецЕсли;
				КонецЕсли;

			КонецЕсли;
        КонецЦикла;
    КонецЦикла;

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

Вспомогательная процедура ДобавитьОписаниеПолей определяет поля каких типов присутствуют в таблице и соответственно к каким таблицам требуется делать соединение.

&НаСервере
Процедура ДобавитьОписаниеПолей(МассивОписанийПолей, ТипПолей, МД, ПолноеИмяТаблицы)
	
    Попытка      
        Поля = МД[ТипПолей];
	Исключение  
		Возврат;
	КонецПопытки;

    Для Каждого Поле Из Поля Цикл
        ТипыПоля = Поле.Тип.Типы();
        МассивПолныхИменМетаданных = Новый Массив;
		Если ТипыПоля.Количество() = 1 И ТипыПоля[0] = Тип("Число") Тогда
			Продолжить;
		ИначеЕсли ТипыПоля.Количество() > 5 Тогда
	 		Запрос = Новый Запрос;
			Запрос.Текст = "Выбрать Различные ТипЗначения(" + Поле.Имя + ") Как Тип Из " + ПолноеИмяТаблицы;
			Рез = Запрос.Выполнить();
			ТипыПоля = Рез.Выгрузить().ВыгрузитьКолонку("Тип");
		Иначе
			ТипыПоляНовые = Новый Массив;
			Для Каждого Тип Из ТипыПоля Цикл
				Запрос = Новый Запрос;
				Запрос.Текст = "Выбрать Первые 1 Истина Из " + ПолноеИмяТаблицы + " Где ТипЗначения(" + Поле.Имя + ") = &Тип";
				Запрос.УстановитьПараметр("Тип", Тип);
				Рез = Запрос.Выполнить();
				Если Рез.Пустой() Тогда
					Продолжить;
				КонецЕсли;
				ТипыПоляНовые.Добавить(Тип);
			КонецЦикла;
			ТипыПоля = ТипыПоляНовые;
		КонецЕсли;

	    Для Каждого Тип Из ТипыПоля Цикл
			
	    	МетаданныеТипа = Метаданные.НайтиПоТипу(Тип);
	    	Если МетаданныеТипа <> Неопределено Тогда
	    	    МассивПолныхИменМетаданных.Добавить(МетаданныеТипа.ПолноеИмя());
	    	КонецЕсли;
	   КонецЦикла;

        Если МассивПолныхИменМетаданных.Количество() > 0 Тогда
            МассивОписанийПолей.Добавить(Новый Структура(
                "Поле, ПолеЭтоБитаяСсылка, МассивИменТаблиц, МожетБытьНеопределено",
                Поле.Имя, Поле.Имя + "ЭтоБитаяСсылка", МассивПолныхИменМетаданных, ТипыПоля.Количество()>1));
        КонецЕсли;
	КонецЦикла; 
	
КонецПроцедуры

Результат действия программы:

 

Проверено на следующих конфигурациях и релизах:

  • Бухгалтерия предприятия, редакция 3.0, релизы 3.0.161.22

поиск битых ссылок объект не найден обработка

См. также

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

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

8400 руб.

20.08.2024    16596    113    52    

115

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

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

9600 руб.

22.02.2013    139353    265    144    

436

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

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

3582 руб.

16.03.2015    198614    218    82    

252

Чистка данных Программист Пользователь Платформа 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, Розница и др. Это могут быть как неиспользуемые элементы справочников, так и неактуальные организации. При этом есть возможность провести анализ пересечений документов с другими организациями и таким образом уберечься от того, что при удалении обороты по другой организации изменятся.

3350 руб.

28.11.2019    26542    64    17    

79

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

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

2400 руб.

09.04.2019    29434    44    15    

46

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

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

1 стартмани

25.10.2023    5678    5    SerVer1C    26    

24

Чистка данных Программист Платформа 1С v8.3 Управляемые формы Платформа 1C v8.2 1C:Бухгалтерия 1С:ERP Управление предприятием 2 Бесплатно (free)

ВАЖНО!!! Очистку регистров накопления и регистров сведений рекомендуется делать пользователям со знанием дела и с осознанием последствий! Обработка поможет быстро очистить выбранный регистр. Делаю данную обработку в первую очередь для себя, т.к. были случаи, когда нужно было очищать регистры, а делать красиво и удобно времени не было.

06.02.2023    22353    1537    Neiron_1C    22    

17

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

В архив помещаются неактуальные элементы справочников. Тем самым появляется возможность выводить в справочнике для просмотра и выбора только актуальные в данный момент данные. Работает для всех справочников.

4 стартмани

07.11.2022    10518    62    sapervodichka    73    

94
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ivnik 612 18.02.25 10:44 Сейчас в теме
То. что обработка находит битые ссылки - это понятно. А потом она с ними что-нибудь делает или только показывает?
Оставьте свое сообщение