Разработка и Конфигурация · 14 мин
ПолучитьСсылку в 1С: что возвращает метод и как с ним работать
Разбираем метод ПолучитьСсылку в 1С: что возвращает, чем отличается от НайтиПоСсылке, типичные ошибки, примеры кода и проверка результата на битые ссылки.
Метод ПолучитьСсылку() встроенного языка 1С — один из самых часто используемых при программной работе со справочниками, документами, планами счетов и другими ссылочными объектами. При этом у начинающих разработчиков он регулярно вызывает путаницу: одни ожидают, что метод «найдёт» элемент в базе, другие считают, что он создаёт объект. На деле поведение метода иное, и понимание того, что именно он возвращает, избавляет от множества ошибок — от «битых ссылок» до лишних обращений к базе данных.
Коротко: ПолучитьСсылку() формирует значение ссылки программно, без обращения к данным информационной базы. Он не проверяет, существует ли объект с такой ссылкой, и не читает его реквизиты. Результат — это просто идентификатор, который можно сравнивать, присваивать и использовать в запросах. Что происходит дальше с этой ссылкой — уже ответственность разработчика.
Ниже разберём сигнатуру метода, что именно он возвращает в разных сценариях, чем отличается от похожих методов, когда его применение оправдано, а когда приводит к битым ссылкам, и как проверить результат.
Сигнатура метода и что он возвращает
Метод вызывается у менеджера ссылочного объекта: Справочники.Номенклатура.ПолучитьСсылку(), Документы.РеализацияТоваровУслуг.ПолучитьСсылку() и аналогично для планов видов характеристик, планов счетов, планов обмена, бизнес-процессов и задач.
Вариантов вызова два:
ПолучитьСсылку()— без параметров. Возвращает новую ссылку с автоматически сгенерированным уникальным идентификатором. Объекта в базе при этом нет — существует только значение ссылки.ПолучитьСсылку(УникальныйИдентификатор)— с параметром типаУникальныйИдентификатор. Возвращает ссылку, «собранную» из переданного УИД. Если объект с таким идентификатором есть в базе — ссылка указывает на него. Если нет — ссылка будет «битой» при попытке чтения данных.
Ключевой момент: тип возвращаемого значения — это ссылка соответствующего вида (например, СправочникСсылка.Номенклатура), а не объект и не строка. Проверить тип можно через ТипЗнч().
НоваяСсылка = Справочники.Номенклатура.ПолучитьСсылку();
Сообщить(ТипЗнч(НоваяСсылка)); // СправочникСсылка.Номенклатура
Сообщить(НоваяСсылка.УникальныйИдентификатор()); // сгенерированный УИД
Что возвращает вызов без параметра
Вызов без параметра чаще всего используют, когда нужно заранее получить ссылку для будущего объекта. Классический сценарий — создание объекта с заранее известной ссылкой через УстановитьСсылкуНового():
НоваяСсылка = Справочники.Контрагенты.ПолучитьСсылку();
НовыйОбъект = Справочники.Контрагенты.СоздатьЭлемент();
НовыйОбъект.УстановитьСсылкуНового(НоваяСсылка);
НовыйОбъект.Наименование = "ООО Ромашка";
НовыйОбъект.Записать();
Зачем это нужно: пока объект не записан, у него нет ссылки, но ссылка может понадобиться заранее — например, чтобы в той же транзакции записать другой объект, ссылающийся на этот, или сформировать движения. Без УстановитьСсылкуНового() платформа при записи сгенерирует ссылку сама, и заранее узнать её нельзя.
Важно понимать: до вызова Записать() ссылка существует только как значение в памяти. Если выведете её в сообщение, увидите представление вида «<Объект не найден>» с УИД — это нормально, объект ещё не создан.
Что возвращает вызов с уникальным идентификатором
Второй вариант — восстановление ссылки по известному УИД. Типичный случай: идентификатор пришёл из внешней системы, из строки в файле обмена или был сохранён ранее как строка:
УИД = Новый УникальныйИдентификатор("a1b2c3d4-e5f6-7890-abcd-ef1234567890");
СсылкаНаТовар = Справочники.Номенклатура.ПолучитьСсылку(УИД);
Метод просто «упаковывает» УИД в ссылку нужного типа. Он не выполняет запрос к базе и не проверяет существование объекта. Поэтому:
- если объект с таким УИД есть — ссылка рабочая, через
ПолучитьОбъект()можно прочитать данные; - если объекта нет — ссылка станет «битой»: попытка обратиться к реквизитам вызовет ошибку, а запрос по такой ссылке вернёт
NULLв полях соединения.
Проверка существования объекта делается отдельно — запросом или через ПолучитьОбъект() с проверкой на Неопределено:
Объект = СсылкаНаТовар.ПолучитьОбъект();
Если Объект = Неопределено Тогда
// объекта с таким УИД в базе нет
КонецЕсли;
Чем ПолучитьСсылку отличается от похожих методов
Путаница чаще всего возникает между четырьмя способами получить ссылку. Они решают разные задачи, и подмена одного другим — источник ошибок.
| Способ | Что делает | Обращение к базе | Когда применять |
|---|---|---|---|
ПолучитьСсылку() | Формирует новую ссылку с новым УИД | Нет | Перед созданием объекта с заданной ссылкой |
ПолучитьСсылку(УИД) | Строит ссылку из переданного УИД | Нет | Восстановление ссылки по известному идентификатору |
НайтиПоКоду(), НайтиПоНаименованию(), НайтиПоРеквизиту() | Ищут объект в базе, возвращают ссылку или пустую ссылку | Да | Поиск существующего элемента по данным |
ПустаяСсылка() | Возвращает пустую ссылку данного типа | Нет | Проверки на незаполненность, значения по умолчанию |
Отдельно стоит НайтиПоСсылке() — метод, который по ссылке возвращает объект для чтения и изменения (по сути аналог Ссылка.ПолучитьОбъект()). Пара этих методов работает в противоположных направлениях: ПолучитьСсылку — от идентификатора к ссылке, ПолучитьОбъект — от ссылки к данным.
Сравнение вариантов
Быстро, без запроса к базе. Подходит, когда УИД гарантированно достоверен. Не проверяет существование объекта.
Позволяет сразу проверить существование и получить нужные поля. Требует обращения к базе, но безопаснее для непроверенных идентификаторов.
Ищет по данным, а не по идентификатору. Возвращает пустую ссылку, если не найдено — это явный признак отсутствия элемента.
Типовые сценарии применения
Создание объекта с заранее заданной ссылкой
Нужно при загрузке данных сохранить исходный идентификатор из внешней системы, чтобы при повторной загрузке узнавать те же объекты. Тогда ссылку строят из УИД внешней системы:
УИДИзФайла = Новый УникальныйИдентификатор(СтрокаУИД);
Ссылка = Справочники.Номенклатура.ПолучитьСсылку(УИДИзФайла);
Если Ссылка.ПолучитьОбъект() = Неопределено Тогда
НовыйОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НовыйОбъект.УстановитьСсылкуНового(Ссылка);
// заполнение реквизитов
НовыйОбъект.Записать();
КонецЕсли;
Это стандартный приём синхронизации: идентификатор внешней системы становится идентификатором ссылки в 1С, и сопоставление объектов не требует отдельных таблиц соответствий.
Ссылка для движений и связанных записей
Когда в одной операции создаются несколько связанных объектов (например, контрагент и договор), ссылку на «главный» объект получают заранее и подставляют в реквизиты зависимых. Это избавляет от необходимости записывать объекты строго последовательно с перечитыванием ссылок.
Сравнение и проверка заполненности
Для проверки «ссылка не пустая» используют ПустаяСсылка() или метод значения Пустая(), но не ПолучитьСсылку() — это разные вещи. Новая ссылка из ПолучитьСсылку() не считается пустой: у неё есть УИД, хотя объекта в базе нет.
- 1Сформируйте или получите уникальный идентификатор (из файла, внешней системы или оставьте генерацию платформе)
- 2Вызовите МенеджерОбъекта.ПолучитьСсылку(УИД) и сохраните результат в переменную
- 3Проверьте Ссылка.ПолучитьОбъект() — если не Неопределено, объект уже существует, создавать не нужно
- 4Создайте объект через СоздатьЭлемент() или СоздатьДокумент() и вызовите УстановитьСсылкуНового(Ссылка)
- 5Заполните реквизиты и вызовите Записать()
- 6Проверьте результат: Объект.Ссылка должна быть равна ранее полученной ссылке
Типичные ошибки и как их избежать
Первая и самая частая ошибка — ожидание, что ПолучитьСсылку(УИД) вернёт Неопределено или пустую ссылку, если объекта нет. Этого не происходит: метод всегда возвращает «полноценную» ссылку. Проверку существования нужно делать явно.
Вторая ошибка — использование метода для поиска по коду или наименованию. Для этого существуют НайтиПоКоду(), НайтиПоНаименованию(), НайтиПоРеквизиту(). ПолучитьСсылку работает только с идентификатором.
Третья ошибка — потеря ссылки между созданием и записью. Если вызвать ПолучитьСсылку() дважды и передать в УстановитьСсылкуНового() не ту переменную, объект запишется с неожиданным идентификатором, а заранее подготовленные связанные записи укажут «в никуда».
Как проверить результат и отличить норму от проблемы
После работы с методом полезно убедиться, что ссылка ведёт себя как ожидается. Основные контрольные точки:
Как проверить результат
ТипЗнч() показывает ссылку нужного вида, например СправочникСсылка.Номенклатура
Возвращено Неопределено или значение другого типа — ошибка в вызове менеджера
Ссылка.ПолучитьОбъект() возвращает объект, реквизиты читаются
ПолучитьОбъект() вернул Неопределено — объект с таким УИД в базе отсутствует
После записи объекта отображается наименование или номер
Отображается <Объект не найден> (УИД) — битая ссылка
Ссылка, полученная по УИД, равна ссылке существующего объекта с тем же УИД
Ссылки не равны — вероятно, перепутаны УИД или типы объектов
Для массовой проверки битых ссылок удобен запрос с левым соединением: если поле соединённой таблицы равно NULL, ссылка указывает на несуществующий объект. Также в типовых конфигурациях есть штатные средства поиска и удаления помеченных объектов, которые выявляют такие ситуации.
В обменах данными храните УИД источника в виде строки в отдельном реквизите или регистре соответствий, даже если используете его как идентификатор ссылки. Это упрощает диагностику: по строке всегда можно восстановить ссылку через ПолучитьСсылку и проверить, что загрузилось, а что нет.
Ограничения и границы применения
Метод доступен только у менеджеров ссылочных типов: справочников, документов, планов видов характеристик, планов счетов, планов видов расчёта, планов обмена, бизнес-процессов и задач. У регистров, перечислений и констант его нет — там само понятие ссылки отсутствует или устроено иначе.
При работе в распределённых базах и обменах помните: один и тот же УИД в разных узлах может указывать на разные объекты, если синхронизация настроена не через идентификаторы. Автоматическая «сборка» ссылки по УИД из чужой базы без гарантий соответствия — прямой путь к рассинхронизации.
Наконец, ПолучитьСсылку() не заменяет механизмы планов обмена и типовые правила конвертации. В сложных интеграциях надёжнее использовать штатные средства сопоставления объектов, а ручную работу со ссылками оставить для простых и контролируемых сценариев.
Как выбрать действие
Что важно запомнить
ПолучитьСсылку() формирует ссылку программно и не обращается к базе: без параметра — новая ссылка с новым УИД, с параметром — ссылка из переданного УИД. Существование объекта метод не проверяет, поэтому перед использованием ссылки в данных проверяйте её через ПолучитьОбъект() или запрос.
Частые вопросы
Почему ПолучитьСсылку(УИД) вернул ссылку, но объекта в базе нет?
Метод не выполняет запрос к базе — он только формирует значение ссылки из идентификатора. Существование объекта проверяйте отдельно: Ссылка.ПолучитьОбъект() вернёт Неопределено, если объекта нет, либо используйте запрос по ссылке.
Чем новая ссылка из ПолучитьСсылку() отличается от пустой ссылки?
У новой ссылки есть уникальный идентификатор, и метод Пустая() для неё вернёт Ложь. Пустая ссылка — это специальное значение-заглушка данного типа без идентификатора объекта; она используется для обозначения незаполненного реквизита.
Можно ли передать в ПолучитьСсылку строку с УИД?
Напрямую нет — параметр должен иметь тип УникальныйИдентификатор. Строку сначала преобразуйте: Новый УникальныйИдентификатор("a1b2c3d4-..."). Если строка имеет неверный формат, конструктор вызовет исключение, которое стоит обработать через Попытка/Исключение.
Что произойдёт, если записать два объекта с одной ссылкой через УстановитьСсылкуНового?
При записи второго объекта возникнет ошибка нарушения уникальности идентификатора — платформа не позволит создать два объекта одного типа с одинаковым УИД. Перед записью убедитесь, что объект с такой ссылкой ещё не существует.
Нагружает ли ПолучитьСсылку() базу данных при массовом вызове?
Нет, сам метод работает в памяти и не обращается к СУБД, поэтому в цикле он практически бесплатен. Нагрузку создают последующие действия: ПолучитьОбъект(), запись объектов и запросы. Для массовых проверок существования эффективнее один запрос с условием «Ссылка В (&СписокСсылок)», чем вызов ПолучитьОбъект() для каждой ссылки.
Как найти в базе все битые ссылки после некорректного обмена?
Используйте запрос с левым соединением таблицы, где хранится ссылка, к таблице соответствующего объекта: записи, где поля соединённой таблицы равны NULL, содержат битые ссылки. В типовых конфигурациях также есть обработки поиска и удаления помеченных объектов, которые показывают места использования удалённых элементов.