Многие знают, что любому объекту ссылочного типа в 1С ссылка присваивается при записи в базу данных. То есть, если объект новый, то реквизит Ссылка у него пустой. Кстати, это один из способов узнать, работает пользователь с новым, только что созданным объектом, или же открыл уже существующий.
//Это новый контрагент
Иначе
//Это ранее записанный контрагент
КонецЕсли;
При записи объекта устанавливается случайная ссылка, так что предугадать ее у вас вряд ли получится. Тем не менее, существуют ситуации, когда полезно и даже необходимо знать ссылку на объект еще до записи этого объекта в базу. Приведем несколько примеров:
- При обмене данными необходимо программно создать некоторые записи в регистрах, включающие ссылку на объект обмена. При этом в базе-источнике таких регистров нет. Пример такой задачи мы подробно рассмотрим ниже.
- При оптимизации работы программного кода. Например, нужно программно создать контрагента, его договор и установить этот договор как Основной. Если идти классическим путем, то нужно сначала создать и записать элемент справочника Контрагенты, пройдя при этом все процедуры записи (а это может занять значительное время). Далее, нужно создать элемент справочника ДоговорыКонтрагентов, установив в качестве Владельца ссылку на контрагента. И наконец, получив заново объект элемента справочника Контрагенты, заполнить там реквизит ОсновнойДоговор и записать его, пройдя заново все процедуры записи.
Эту процедуру можно ускорить, зная заранее ссылку на еще не созданный ДоговорКонтрагента. В этом случае уже не требуется два раза получать и записывать Контрагента.
Как узнать ссылку на объект до его записи
Последовательность действий:
- Сгенерировать уникальный идентификатор объекта.
- Зарезервировать ссылку по уникальному идентификатору
- Установить зарезервированную ссылку для нового объекта.
УИД = новый УникальныйИдентификатор;
//Создаем ссылку по этому идентификатору. Для этого нужно знать тип объекта
НоваяСсылка = Справочники.Контрагенты.ПолучитьСсылку(УИД);
//Устанавливаем ссылку для нового объекта
СправочникОбъект.УстановитьСсылкуНового(НоваяСсылка);
После этого объект можно записать. Будет установлена заранее известная ссылка.
Особенности получения ссылок на новые объекты при обмене данными
Рассмотрим, как получить ссылку на незаписанный объект на примере следующей задачи:
При обмене данными между двумя базами передается документ приобретения товаров. В базе источнике есть реквизит с типом Булево, показывающий получение оригиналов документов от поставщика. В базе-приемнике отметка о получении оригиналов реализована через регистр сведений с измерением — ссылкой на документ и ресурсом — ссылкой на перечисление.
Для решения этой задачи будет использоваться обработчик ПослеЗагрузки в правилах конвертации документа приобретения. Реквизит ОригиналыПолучены будет передаваться в виде параметра.
Код будет выглядеть так:
Если ОригиналыПолучены Тогда
//Если записывается новый объект, создадим его ссылку
//В противном случае используем найденную
Если НЕ ОбъектНайден Тогда
СсылкаДокумента = Документы.ПоступлениеТоваровУслуг.ПолучитьСсылку(новый УникальныйИдентификатор);
Объект.УстановитьСсылкуНового(СсылкаДокумента);
Иначе
СсылкаДокумента = Ссылка;
КонецЕсли;
МЗ=РегистрыСведений.СтатусыДокументов.СоздатьМенеджерЗаписи();
МЗ.Организация = Объект.Организация;
//Устанавливаем в записи регистра сведений ссылку, полученную для еще не записанного объекта
МЗ.Документ = СсылкаДокумента;
МЗ.Статус = Перечисления.СтатусыДокументовПоступления.ОригиналПолучен;
МЗ.Записать();
КонецЕсли;
ВАЖНО!!! Если в обмене участвуют другие объекты, имеющие ссылки на наш документ приобретения товаров (например, счета-фактуры), то в них вы скорее всего получите <Объект не найден>, т.к. мы заменили ссылку на документ. Для того чтобы этого избежать, нужно в правилах конвертации документа на вкладке Настройки установить флаг Не запоминать выгруженные объекты. При использовании этого флага система не будет сохранять документы в специальной таблице кеширования, а каждый раз будет подбирать ссылку этого объекта заново, уже с учетом внесенных нами изменений.
а как быть если нужно создать с тем же УИД, как и в исходной базе, как этот самый УИД получить?
УИД объекта можно получить с помощью функции УникальныйИдентификатор()
Чтобы задать объекту конкретный УИД нужно сделать так:
Новый_UID = Новый УникальныйИдентификатор(«1014270d-d794-11df-825c-001517542b78»);
НоваяСсылка = Справочники.Номенклатура.ПолучитьСсылку(Новый _UID);
НашаНоменклатура = Справочники.Номенклатура.СоздатьЭлемент();
НашаНоменклатура.УстановитьСсылкуНового(НоваяСсылка);
Если нужно заменить УИД уже существующего объекта, то все равно создают новый объект — копию существующего, а потом выполняют поиск и замену ссылок по всей базе. Есть такая обработка даже. Если этого не сделать, получите везде вместо ссылки на объект с новым УИД <Объект не найден>.
Только при обмене не обязательно делать одинаковые УИД в базах. Сопоставление объектов происходит через регистр сведений Соответствия объектов информационных баз.