УстановитьСсылкуНового() или «как узнать ссылку на объект до записи»

Многие знают, что любому объекту ссылочного типа в 1С ссылка присваивается при записи в базу данных. То есть, если объект новый, то реквизит Ссылка у него пустой. Кстати, это один из способов узнать, работает пользователь с новым, только что созданным объектом, или же открыл уже существующий.

Если Ссылка = Справочники.Контрагенты.ПустаяСсылка() Тогда
//Это новый контрагент
Иначе
//Это ранее записанный контрагент
КонецЕсли;

При записи объекта устанавливается случайная ссылка, так что предугадать ее у вас вряд ли получится. Тем не менее, существуют ситуации, когда полезно и даже необходимо знать ссылку на объект еще до записи этого объекта в базу. Приведем несколько примеров:

  1. При обмене данными необходимо программно создать некоторые записи в регистрах, включающие ссылку на объект обмена. При этом в базе-источнике таких регистров нет. Пример такой задачи мы подробно рассмотрим ниже.
  2. При оптимизации работы программного кода. Например, нужно программно создать контрагента, его договор и установить этот договор как Основной. Если идти классическим путем, то нужно сначала создать и записать элемент справочника Контрагенты, пройдя при этом все процедуры записи (а это может занять значительное время). Далее, нужно создать элемент справочника ДоговорыКонтрагентов, установив в качестве Владельца ссылку на контрагента. И наконец, получив заново объект элемента справочника Контрагенты, заполнить там реквизит ОсновнойДоговор и записать его, пройдя заново все процедуры записи.
    Эту процедуру можно ускорить, зная заранее ссылку на еще не созданный ДоговорКонтрагента. В этом случае уже не требуется два раза получать и записывать Контрагента.

Как узнать ссылку на объект до его записи

Последовательность действий:

  1. Сгенерировать уникальный идентификатор объекта.
  2. Зарезервировать ссылку по уникальному идентификатору
  3. Установить зарезервированную ссылку для нового объекта.
//Создаем уникальный идентификатор
УИД = новый УникальныйИдентификатор;

//Создаем ссылку по этому идентификатору. Для этого нужно знать тип объекта
НоваяСсылка = Справочники.Контрагенты.ПолучитьСсылку(УИД);

//Устанавливаем ссылку для нового объекта
СправочникОбъект.УстановитьСсылкуНового(НоваяСсылка);

После этого объект можно записать. Будет установлена заранее известная ссылка.

Особенности получения ссылок на новые объекты при обмене данными

Рассмотрим, как получить ссылку на незаписанный объект на примере следующей задачи:

При обмене данными между двумя базами передается документ приобретения товаров. В базе источнике есть реквизит с типом Булево, показывающий получение оригиналов документов от поставщика. В базе-приемнике отметка о получении оригиналов реализована через регистр сведений с измерением — ссылкой на документ и ресурсом — ссылкой на перечисление.

Для решения этой задачи будет использоваться обработчик ПослеЗагрузки в правилах конвертации документа приобретения. Реквизит ОригиналыПолучены будет передаваться в виде параметра.

Код будет выглядеть так:

ОригиналыПолучены = ПараметрыОбъекта["ОригиналыПолучены"];

Если ОригиналыПолучены Тогда

//Если записывается новый объект, создадим его ссылку
//В противном случае используем найденную
Если НЕ ОбъектНайден Тогда
СсылкаДокумента = Документы.ПоступлениеТоваровУслуг.ПолучитьСсылку(новый УникальныйИдентификатор);
Объект.УстановитьСсылкуНового(СсылкаДокумента);
Иначе
СсылкаДокумента = Ссылка;
КонецЕсли;

МЗ=РегистрыСведений.СтатусыДокументов.СоздатьМенеджерЗаписи();
МЗ.Организация = Объект.Организация;

//Устанавливаем в записи регистра сведений ссылку, полученную для еще не записанного объекта
МЗ.Документ = СсылкаДокумента;

МЗ.Статус = Перечисления.СтатусыДокументовПоступления.ОригиналПолучен;
МЗ.Записать();
КонецЕсли;

ВАЖНО!!! Если в обмене участвуют другие объекты, имеющие ссылки на наш документ приобретения товаров (например, счета-фактуры), то в них вы скорее всего получите <Объект не найден>, т.к. мы заменили ссылку на документ. Для того чтобы этого избежать, нужно в правилах конвертации документа на вкладке Настройки установить флаг Не запоминать выгруженные объекты. При использовании этого флага система не будет сохранять документы в специальной таблице кеширования, а каждый раз будет подбирать ссылку этого объекта заново, уже с учетом внесенных нами изменений.Не запоминать выгруженные объекты при установке ссылки нового

УстановитьСсылкуНового() или «как узнать ссылку на объект до записи»: 2 комментария

  1. Макс

    а как быть если нужно создать с тем же УИД, как и в исходной базе, как этот самый УИД получить?

    1. Автоматизация малого бизнеса Автор записи

      УИД объекта можно получить с помощью функции УникальныйИдентификатор()
      Чтобы задать объекту конкретный УИД нужно сделать так:

      Новый_UID = Новый УникальныйИдентификатор(«1014270d-d794-11df-825c-001517542b78»);
      НоваяСсылка = Справочники.Номенклатура.ПолучитьСсылку(Новый _UID);
      НашаНоменклатура = Справочники.Номенклатура.СоздатьЭлемент();
      НашаНоменклатура.УстановитьСсылкуНового(НоваяСсылка);

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

      Только при обмене не обязательно делать одинаковые УИД в базах. Сопоставление объектов происходит через регистр сведений Соответствия объектов информационных баз.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *