1с запрос как найти объект не найден

 0 

   

Распечатать

Как в запросе выполнить отбор по Объект не найден

Для этого используется логический оператор ЕСТЬ NULL функций языка запросов.
Например, допустим, в регистре накопления «ПартииТоваровНаСкладах» мы хотим найти записи, в которых измерение «ДокументОприходования» оказалось такой вот битой ссылкой на «объект не найден». Запрос будет выглядеть примерно так:

Код 1C v 8.х

 ВЫБРАТЬ
ПартииТоваровНаСкладах.Регистратор,
ПартииТоваровНаСкладах.Номенклатура,
ПартииТоваровНаСкладах.СерияНоменклатуры,
ПартииТоваровНаСкладах.ДокументОприходования,
ПартииТоваровНаСкладах.Качество,
ПартииТоваровНаСкладах.Склад,
ПартииТоваровНаСкладах.ХарактеристикаНоменклатуры,
ПартииТоваровНаСкладах.СтатусПартии,
ПартииТоваровНаСкладах.Заказ
ИЗ
РегистрНакопления.ПартииТоваровНаСкладах КАК ПартииТоваровНаСкладах
ГДЕ
ПартииТоваровНаСкладах.ДокументОприходования.Ссылка ЕСТЬ NULL

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

Содержание:

  1. Выборка объектов с помощью запроса
  2. Использование объектной модели
  3. Поиск подстроки 1С «Объект не найден» в представлении ссылки

Трудно найти человека, который при работе с информационными базами данных на платформе 1С более или менее продолжительное время, ни разу не столкнулся с “битыми” ссылками в 1С, которые содержат поля таблиц баз данных (пресловутый текст в 1С «Объект не найден» c уникальным идентификатором отсутствующего объекта в поле со ссылкой на отсутствующий объект информационной базы). Причинами возникновения таких ситуаций могут быть выполнение удаления объектов информационных баз без контроля ссылочной целостности, аварийные завершения работы информационных баз, ошибки при обменах данными и т.д.

Сразу хочется отметить, что следует отличать ситуации с “битыми” ссылками в 1С от ситуаций, когда у пользователя из-за некорректных настроек прав доступа просто нет возможности “видеть” даже представление объекта информационной базы, запрещенного ему для открытия и просмотра, в таких случаях в видимом для пользователя поле со ссылкой на такой объект тоже содержится строка, включающая текст «Объект не найден».

Существуют несколько способов выявления “битых” ссылок в 1С в таблицах информационной базы.  

1.    Выборка объектов с помощью запроса

Первый способ: выборка объектов информационной базы с “битыми” ссылками в 1С с помощью запроса.

ТекстЗапроса =

    “ВЫБРАТЬ

    |       ПеремещениеТоваров.Ссылка КАК Ссылка

    |ИЗ

    |       Документ.ПеремещениеТоваров КАК ПеремещениеТоваров

    |ГДЕ

    |       НЕ ПеремещениеТоваров.СкладОтравитель ЕСТЬ NULL

    |       И ПеремещениеТоваров.СкладОтравитель.Ссылка ЕСТЬ NULL”.

В данном случае мы с помощью запроса производим поиск документов «Перемещение товаров», у которых “битая” ссылка на склад-отправитель. Для этого в условии отбора убеждаемся, что ссылка на склад-отправитель в принципе не пустая(часть условия “ГДЕ”: “НЕ ПеремещениеТоваров.СкладОтравитель ЕСТЬ NULL”) и, если это так, то проверяем ссылку на “битость”(часть условия “ГДЕ”: “ПеремещениеТоваров.СкладОтравитель.Ссылка ЕСТЬ NULL”).

Во второй части условия “ГДЕ” (“ПеремещениеТоваров.СкладОтравитель.Ссылка ЕСТЬ NULL”) вместо “Ссылка” можно использовать другие реквизиты склада-отправителя, например, “Код” (“ПеремещениеТоваров.СкладОтравитель.Код ЕСТЬ NULL”) – в таком случае мы также сможем отобрать перемещения с “битыми” ссылками на склад-отправитель.

Следует оговорить ситуацию, когда нужно произвести выборку объектов с битыми ссылками в 1С, но при этом поле объекта, в котором возможна “битая” ссылка, имеет составной тип, а нам требуется найти “битые” ссылки только определенного типа. Например, если в нашем случае склад-отправитель имеет составной тип “Склады” + “Подразделения организаций”, а нам нужно отобрать только перемещения с “битыми” складами-отправителями типа “Подразделения организаций”, в текст нашего запроса в условие “ГДЕ” добавится часть “ПеремещениеТоваров.СкладОтравитель ССЫЛКА Справочник.ПодрадзделенияОрганизаций”. Запрос примет следующий вид:

“ВЫБРАТЬ

    |       ПеремещениеТоваров.Ссылка КАК Ссылка

    |ИЗ

    |       Документ.ПеремещениеТоваров КАК ПеремещениеТоваров

    |ГДЕ

    |       ПеремещениеТоваров.СкладОтравитель ССЫЛКА Справочник.ПодрадзделенияОрганизаций

    |       И НЕ ПеремещениеТоваров.СкладОтравитель ЕСТЬ NULL

    |       И ПеремещениеТоваров.СкладОтравитель.Ссылка ЕСТЬ NULL”.  

2.    Использование объектной модели

Второй способ: определение “битой” ссылки с использованием объектной модели данных 1С.

При данном способе для поиска “битых” ссылок используется метод ПолучитьОбъект() платформы 1С по ссылке на объект информационной базы, который возвращает «Неопределено» в случаях с “битыми” ссылками:

Если ЗначениеЗаполнено(ДокументПеремещения.СкладОтправитель) И (ДокументПеремещения.СкладОтправитель.ПолучитьОбъект() = Неопределено) Тогда

// Здесь выполняется требуемый код обработки найденного объекта с “битой” ссылкой.

КонецЕсли;

Если поле с “битой” ссылкой имеет составной тип, и нам необходимо выявлять только битые ссылки определенного типа, тогда, как и при первом случае, мы соответствующим способом модифицируем условие:

Если (ТипЗнч(Объект.СкладОтравитель) = Тип(“СправочникСсылка.ПодрадзделенияОрганизаций”)) И ЗначениеЗаполнено(ДокументПеремещения.СкладОтправитель) И (ДокументПеремещения.СкладОтправитель.ПолучитьОбъект() = Неопределено) Тогда

        // Здесь выполняется требуемый код обработки найденного объекта с “битой” ссылкой.

    КонецЕсли.  

3.    Поиск подстроки «Объект не найден» в представлении ссылки

Третий способ: поиск подстроки «Объект не найден» в представлении ссылки.

    Если СтрНайти(ДокументПеремещения.СкладОтправитель, “Объект не найден”) > 0 Тогда

        // Здесь выполняется требуемый код обработки найденного объекта с “битой” ссылкой.

    КонецЕсли;

По поводу последнего способа хотелось бы отметить следующее: хотя на первый взгляд он выглядит не очень “красивым”, по сравнению со вторым способом, он является более предпочтительным с точки зрения производительности, так как метод ПолучитьОбъект(), используемый во втором способе, немного больше “нагружает” систему в случаях, когда при проверке условия ссылка оказывается не “битой”, и платформа выделяет дополнительные ресурсы вычислительной машины для создания в ее памяти копии объекта информационной базы по проверяемой ссылке.

При это нужно быть аккуратным – используя в коде поиск “битых” ссылок по подстроке «Объект не найден», нужно учитывать, что подстрока “Объект не найден” в представлении “битой” ссылки может изменяться в зависимости от языка, используемого в “региональных установках информационной базы”.

Специалист компании «Кодерлайн»

Аскер Жансуев

Иногда в ИБ можно встретить ссылки на объекты <Объект не найден> (75:a353ac9e17b7bc7111e60238e0dc59c6), это ссылки на удаленные объекты. Получаются такие ссылки в ходе сбоев ИБ, РИБ(Распределенных Информационных Баз) или других механизмов создающих ссылки не записанных объектов(разбирал здесь).

Поиск "Объект не найден" в регистре и удаление

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

В рамках задачи необходимо удалить записи регистра с битыми ссылками, в статье не будет разбираться тестирование и исправление ИБ, или другое восстановление ссылок.

Поиск ссылок <Объект не найден>

Сама ссылка считается валидной, а вот если обратиться к ее реквизиту в запросе, то получим NULL. Из этого пишем запрос получающий наименование из ссылки в измерении «номенклатура» регистра сведений «Данные для обработки» и отбираем записи у которых значение запрашиваемого реквизита равно NULL. Если измерений по которым необходимо производить поиск больше одного, то объединяем условия через ИЛИ.

А для удаления таких записей просто создадим наборы записей указав отборы и запишем.

&НаСервере
Процедура УдалитьПлохиеЗаписиДанныхДляОбработки()

	// Найдем записи с <Объект не найден>
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	ДанныеДляОбработки.Номенклатура КАК Номенклатура
	|ИЗ
	|	РегистрСведений.ДанныеДляОбработки КАК ДанныеДляОбработки
	|ГДЕ
	|	ДанныеДляОбработки.Номенклатура.Наименование ЕСТЬ NULL";
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	// Удаление записей с <Объект не найден>
	Пока Выборка.Следующий() Цикл 
		
		НаборЗаписей = РегистрыСведений.ДанныеДляОбработки.СоздатьНаборЗаписей();
		
		НаборЗаписей.Отбор.Номенклатура.Установить(Выборка.Номенклатура);
		
		НаборЗаписей.Записывать = Истина;
		НаборЗаписей.Записать(Истина);	
				
	КонецЦикла;
	
КонецПроцедуры

После выполнения данного кода из регистра сведений будут удалены все записи со ссылками <Объект не найден>.

Как в запросе исключить <Объект не найден>

Я
   Max1986

11.05.12 – 17:17

Прошу совета в таком вопросе.

Есть распределенная база. Есть регистр сведений и там есть параметры из другой базы вида <Объект не найден>.

ак нам в запросе исключить эти элементы?

Типа использовать подобие или еще что?

Я пока нашел только один выход – ВНУТРЕННЕЕ СОЕДИНЕНИЕ с со значениями этого реквизита Регистра.

Соответственно объекты  <Объект не найден> не попадут.

Есть ли другой вариант?

   Deniskind

1 – 11.05.12 – 17:25

Попробуйте в ГДЕ указать ПолеРегистраСведений ЕСТЬ NULL

или ПолеРегистраСведений.Представление ЕСТЬ NULL

   Deniskind

2 – 11.05.12 – 17:25

Точнее наоборот 🙂

НЕ ЕСТЬ NULL

   Max1986

3 – 11.05.12 – 17:26

(1)он не NULL а <Объект не найден>

   Max1986

4 – 11.05.12 – 17:26

(2)не пройдет

   Кокос

5 – 11.05.12 – 17:27

РАЗРЕШЕННЫЕ

правда помоему только в корневых объектах выборки помоему. на реквизитах не сработает 🙂

   mikecool

6 – 11.05.12 – 17:27

(0) исправить ситуацию не предлагать?

   Кокос

7 – 11.05.12 – 17:29

(6) согласен. такой ситуации в корне быть не должно. значит у него и в журналах и в списках все это торчит.

   sapphire

8 – 11.05.12 – 17:29

(0) Ну и правильно. В чем вопрос-то?

   Deniskind

9 – 11.05.12 – 17:30

(3) Рискну предположить, что представление <Объект не найден> будет, все таки, NULL

   mikecool

10 – 11.05.12 – 17:31

(9) нет, неправильно

   mikecool

11 – 11.05.12 – 17:31

+10 есть ссылка, но нет объекта, значение – строка(36)

   Fragster

12 – 11.05.12 – 17:32

Где Реквизит.Ссылка Есть не NULL

   Fragster

13 – 11.05.12 – 17:32

Где Таблица.Реквизит.Ссылка Есть не NULL

   ДемонМаксвелла

14 – 11.05.12 – 17:33

все реквизиты у <Объект не найден> будут NULL

   ДемонМаксвелла

15 – 11.05.12 – 17:34

(12) +1

   Max1986

16 – 11.05.12 – 17:37

Короче, быстрее и правильнее оказалось вариант сделанный мной – со ВНУТРЕННИМ СОЕДИНЕНИЕМ

   Deniskind

17 – 11.05.12 – 17:39

Проверил:

ВЫБРАТЬ

   РегистрСведений1.Справочник1,

   РегистрСведений1.Ресурс1

ИЗ

   РегистрСведений.РегистрСведений1 КАК РегистрСведений1

   ГДЕ НЕ (Справочник1.Представление ЕСТЬ NULL)

Вот эта штука выбирает все строки регистра, у которых в измерении нет <Объект не найден>

   sapphire

18 – 11.05.12 – 17:40

(16) И?

Это же очевидно. Если ссылка на реквизит битая, т.е. поле заполнено неким значением и не есть NULL, но отсутствует в целевой таблице.

   sapphire

19 – 11.05.12 – 17:40

(17) Неявное внутреннее соединение.

   Deniskind

20 – 11.05.12 – 17:41

(19) Согласен

   ИС-2

21 – 11.05.12 – 17:41

я делаю по наименованию или коду.

Пр

Не оБъек.Код = “”

   ДемонМаксвелла

22 – 11.05.12 – 17:52

(21) иногда лучше молчать

   sapphire

23 – 11.05.12 – 17:54

(21) Тоже самое что и в (17) см (19).

   sapphire

24 – 11.05.12 – 17:55

(22) Да ладно, пусть высказывается. Только зачем? Ради флуда?

В (0) ТС всё правильно делает. ТОлько сама тема неясно за каким организована.

   Wern

25 – 11.05.12 – 17:59

Неявное соединение лучше явного, улучшается читаемость кода.

   sapphire

26 – 11.05.12 – 18:08

(25) Автор, убей себя об стену.

   Reset

27 – 11.05.12 – 18:14

(26) Сам убейся, он прав [в данном конкретном случае].

(23) то же самое, да да, кроме того что (21) грубо нерабочее.

   Necessitudo

28 – 11.05.12 – 18:33

(26) +1

Я не пойму – у автора именно битые ссылки или просто рлс работает?

   sapphire

29 – 11.05.12 – 18:35

(28) Да из обмена к нему хлам приехал.

   sapphire

30 – 11.05.12 – 18:37

(27) Никоим образом он не прав. Неявные соединения это … чаще всего дикая беда.

Например, есть регистр накопления с кучей регистраторов.

Как думаешь к чему приведет код Регистратор.{чего-то там}?

   Immortal

31 – 11.05.12 – 21:11

вопрос больше в постановке задачи, чем в решении.

правила формирования и миграции записей известны, фильтры в РИБ тоже.

таким образом, определение записей с пустым регистратором особого труда не составляет.

   sapphire

32 – 11.05.12 – 23:31

(31) Ничего нового. Ответ очевиден

   Immortal

33 – 12.05.12 – 00:00

(32)не понимаю, к чему это относится, объясни

   qwerty09

34 – 12.05.12 – 00:24

(17) как вариант, но в выборку будут попадать незаполненные значения полей составного типа…самым правильным вариантом будет:

ГДЕ Объект.РеквизитОбъекта ЕСТЬ NULL И Объект <> &ПустаяСсылкаНаОбъект

или

ГДЕ Объект.РеквизитОбъекта ЕСТЬ NULL И Объект <> Неопределено

   sapphire

35 – 12.05.12 – 00:40

(34) В обмене  и запросах поля составного типа = зло, ИМХо.

   Wern

36 – 12.05.12 – 02:29

(35) Конечно зло, если не умеешь их готовить. По-мне лучше научится один раз и потом пользоваться, чем избегать постоянно.

   sapphire

37 – 12.05.12 – 02:32

(36) А тут далеко вообще не все умеют что-либо готовить.

   МимохожийОднако

38 – 12.05.12 – 07:34

(0)Код показывай

  

Reset

39 – 12.05.12 – 09:48

(30) Говорить любишь, думать нет.

Если поле не составное – нафиг не нужно явное соединение, достаточно обращения через точку [для данного конкретного, обозначенного в сабже случая].

Если поле составное и содержит пустую ссылку (неизвестного типа) – куда ты будешь соединять явно? Куда-нибудь? Таки придется делать все соединения вручную. Опять же нафиг не нужный лишний текст.

Повторюсь, (25) в значительной степени прав В ДАННОМ КОНКРЕТНОМ СЛУЧАЕ (капс для неумеющих читать с первого раза).

“.Ссылка” в разы читабельней чем куча неужных соединений. В данной, блин, конректной, задаче.

Skip to content

1С – поиск и исправление битых ссылок <Объект не найден>, пример процедуры и запроса

Поиск и исправление битых ссылок <Объект не найден>

Если в элементе справочника или документа присутствует фраза <Объект не найден>, значит ссылки на этот объект не существует — это так называемая битая ссылка. Если не исправить ситуацию, то возникнут сложности при обмене данными. Пример исправления ситуации ниже.

Задача:

  1. найти в справочнике «Договоры» все договоры, с битыми ссылками на владельца (контрагента);
  2. заменить битые ссылки на действующего контрагента;

Пример процедуры:

&НаСервере
Процедура ЗаменитьБитыеСсылкиНаСервере()
	
	Запрос = Новый Запрос(
	"ВЫБРАТЬ
	|	ДоговорыКонтрагентов.Ссылка КАК ДоговорСсылка,
	|	ДоговорыКонтрагентов.Владелец КАК КонтрагентСсылка
	|ИЗ
	|	Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов");
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
			
		Если Выборка.КонтрагентСсылка.ПолучитьОбъект() = Неопределено Тогда
		
			//если контрагент не определен, значит - это битая ссылка
			ДоговорОбъект = Выборка.ДоговорСсылка.ПолучитьОбъект();
			ДоговорОбъект.Владелец = Справочники.Контрагенты.НайтиПоКоду("ФР-001289", Истина);
			ДоговорОбъект.Записать();
			
			Сообщить("Исправлен договор: " + ДоговорОбъект.Код);
			
		КонецЕсли;
	
	КонецЦикла; 
	
КонецПроцедуры

Связанные статьи

Добавить комментарий