Книга знаний

Рекламное место пустует
1С:Предприятие / Объекты конфигурации

Статья захвачена: Звездочёт
с 18.09.15 12:56 по 21.09.15 12:56

Пустые ссылки

Неопределено <> NULL <> "" <> 0 <> пустая ссылка <> Битая ссылка
<br><br>Как определить, что ссылка пустая, а не битая, как грамотно применять пустые ссылки
Автор статьи: Волшебник | Редакторы: mrist, Immortal, badday, Михей, НЕА123
Последняя редакция №22 от 24.01.11 | История
URL: http://kb.mista.ru/article.php?id=21

Ключевые слова: пустая, ссылка, заполнен, незаполнен, битая, неопределено, ПустаяСсылка, несуществующая


В 8.0 ссылки бывают пустыми. Тогда у нее идентификатор равен
00000000-0000-0000-0000-000000000000

У обычной ссылки уникальный идентификатор можно получить так:
уник = Ссылка.УникальныйИдентификатор();

например "7c9706eb-eaba-11d8-bca8-000c6efdd521"

Получить пустую ссылку можно методом:
Справочники.Номенклатура.ПустаяСсылка()


Получить пустую ссылку по значению неизвестного типа можно следующей конструкцией:
МассивТипов = Новый Массив();
МассивТипов.Добавить(ТипЗнч(ЗначениеНеизвТипа));
ОписаниеТипов= Новый ОписаниеТипов(МассивТипов,,,); 
ЗначениеПустаяСсылка = ОписаниеТипов.ПривестиЗначение(Неопределено);



Проверить на пустую ссылку можно так:
Если Ссылка.Пустая() Тогда


Или так:
Если Ссылка = Справочники.Номенклатура.ПустаяСсылка() Тогда


В запросах для версии 8.0 так:
...
|ГДЕ Поле = &ПустаяСсылка";
...
Запрос.УстановитьПараметр("ПустаяСсылка",Справочники.Номенклатура.ПустаяСсылка());

В запросах для версии 8.1 так:
...
|ГДЕ Поле = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)";
...


Пустые ссылки возвращаются методами НайтиПоНаименованию, НайтиПоКоду, НайтиПоНомеру в случае, когда объект не найден. Пустые ссылки являются значениями по умолчанию для реквизитов ссылочных типов. Если реквизит имеет составной тип данных,то значением по умолчанию для него является Неопределено.

Неопределено <> NULL <> "" <> 0 <> пустая ссылка <> Битая ссылка

У пустой ссылки есть все поля (реквизиты, табличные часть) и к ним можно обращаться. Они будут незаполнены (для чисел - 0, для ссылок - пустые ссылки, для строк переменной длины - "", для строк фиксированной длины - опр. количество пробелов). Табличные части будут иметь 0 строк.

Пустые ссылки можно "разыменовать" (обращаться через точку с свойствам). Следующий фрагмент кода вполне работоспособен:

ПустойПользователь = Справочники.Пользователи.ПустаяСсылка(); 
ЦФО = ПустойПользователь.Сотрудник.Подразделение.ЦФО; 


Т.е. не нужно лишних проверок в программных модулях. Может кому пригодится.

Есть еще такое понятие, как "битая ссылка" (условное название). Когда объект был удален непосредственно, то все ссылки на него в справочниках, в документах, в регистрах стали битыми и отображаются следующим образом:

<Объект не найден> (16:bca8000c6efdd52111d8eaba7c9706eb)


Битая ссылка не является пустой. Т.е. метод Пустая() возвращает Ложь. Определить, что ссылка битая можно так:

Если Ссылка.ПолучитьОбъект() = Неопределено Тогда 
//битая ссылка 
КонецЕсли; 


или так (ненадежно):

Если Лев(СокрЛП(Ссылка),18) = "<Объект не найден>" Тогда


Еще вариант (действует для обьектов, которые имеют ссылку)
Попытка
  обьект=Ссылка.Ссылка;
Исключение
  сообщить("битая");
КонецПопытки;


И последний вариант для проверки в запросах:
ГДЕ Объект.РеквизитОбъекта ЕСТЬ NULL И Не Объект=&ПустаяСсылкаОбъекта


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

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

Процедура КнопкаВыполнитьНажатие(Кнопка)

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

    Для Каждого пРегистр из Метаданные.РегистрыНакопления Цикл
        УдалениеБитыхСсылок(пРегистр.Имя,РегистрыНакопления,"РегистрНакопления")
    КонецЦикла;
    
КонецПроцедуры
Закладка

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2011 | Mista.ru

Яндекс.Метрика