К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как получить ссылку на объект в 1С

Как получить ссылку на объект в 1С: методы ПолучитьСсылку, НайтиПоКоду, НайтиПоНаименованию, работа с уникальным идентификатором и типичные ошибки разработчиков.

Ссылка — основной способ обращения к данным в 1С. Справочники, документы, планы видов характеристик и другие объектные типы хранятся в базе как записи, а работа с ними в коде идёт через ссылки. Понимание того, как получить ссылку разными способами, нужно при обменах, загрузках данных, программном создании документов и поиске дублей.

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

Способ получения ссылки зависит от того, что известно об объекте: уникальный идентификатор, код, наименование или набор реквизитов. Ниже разобраны все рабочие варианты с примерами кода и типичными ошибками.

Что такое ссылка и чем она отличается от объекта

В 1С существует два разных программных представления одной записи базы: ссылка (например, СправочникСсылка.Номенклатура) и объект (СправочникОбъект.Номенклатура). Ссылка — это лёгкий идентификатор, который содержит только указатель на запись. Объект — полная копия данных в памяти, которую можно изменять и записывать.

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

Метод ПолучитьОбъект() вызывают только когда данные нужно изменить и записать. Если требуется просто прочитать наименование, код или реквизит — достаточно ссылки.

Получение ссылки по уникальному идентификатору

Универсальный способ — метод ПолучитьСсылку(), который принимает уникальный идентификатор (GUID). Он работает для справочников, документов, планов счетов и других объектных типов.

УИД = Новый УникальныйИдентификатор("a1b2c3d4-e5f6-7890-abcd-ef1234567890");

СсылкаНаЭлемент = Справочники.Номенклатура.ПолучитьСсылку(УИД);

Обратное действие — получить идентификатор из существующей ссылки — выполняется методом УникальныйИдентификатор():

УИД = СсылкаНаЭлемент.УникальныйИдентификатор();

Важная особенность: ПолучитьСсылку() вернёт ссылку даже если объекта с таким идентификатором в базе нет. При обращении к реквизитам такой «битой» ссылки возникнет ошибка. Проверить существование можно попыткой чтения реквизита или запросом.

Поиск ссылки по коду и наименованию

Когда идентификатор неизвестен, но есть код или наименование, используются методы поиска менеджера справочника. Для документов аналогично работает НайтиПоНомеру() с указанием даты.

СсылкаПоКоду = Справочники.Номенклатура.НайтиПоКоду("000000123");

СсылкаПоИмени = Справочники.Номенклатура.НайтиПоНаименованию("Кабель ВВГ 3х2,5", Истина);

СсылкаДокумента = Документы.РеализацияТоваровУслуг.НайтиПоНомеру("0000-000456", ТекущаяДатаСеанса());

Второй параметр НайтиПоНаименованию определяет точность совпадения: Истина — полное совпадение строки, Ложь — поиск по началу наименования. Учитывайте, что наименования не уникальны: метод вернёт первый найденный элемент, а при нескольких одинаковых наименованиях результат может быть не тем, который ожидался.

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

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

Проверка результата: пустая ссылка и существование объекта

Корректная работа со ссылками требует двух разных проверок, которые часто путают. Первая — проверка на пустую ссылку: найден ли элемент вообще. Вторая — проверка существования объекта в базе, актуальная для ссылок, полученных по УИД.

Если СсылкаПоКоду.Пустая() Тогда

// Элемент не найден

КонецЕсли;

// Альтернатива через сравнение

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

// Элемент не найден

КонецЕсли;

Для проверки существования объекта по ссылке надёжнее всего использовать запрос, который не вызывает исключения даже для битых ссылок:

Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ Ссылка = &Ссылка");

Запрос.УстановитьПараметр("Ссылка", СсылкаНаЭлемент);

Если Запрос.Выполнить().Пустой() Тогда

// Объекта нет в базе

КонецЕсли;

Контрольные точки

Как проверить полученную ссылку

Ссылка получена поиском по коду или наименованию
Норма

Ссылка.Пустая() = Ложь, реквизиты читаются без ошибок

Тревожный признак

Пустая() = Истина — элемент не найден, поиск дал пустой результат

Ссылка получена через ПолучитьСсылку(УИД)
Норма

Запрос по ссылке возвращает строку, реквизиты доступны

Тревожный признак

Ошибка «Объект не найден» при чтении реквизита — битая ссылка

Получение ссылки из реквизита, строки и в запросах

На практике ссылка часто уже хранится в реквизите другого объекта — тогда её не нужно искать, достаточно прочитать поле. Например, ссылка на контрагента из документа доступна как ДокументСсылка.Контрагент без дополнительного поиска.

Если ссылка хранится в виде строки (например, при обмене через файлы), её восстанавливают из строкового представления УИД через конструктор Новый УникальныйИдентификатор(СтрокаУИД) с последующим ПолучитьСсылку(). Для типов, известных только в момент выполнения, используют конструкцию вида:

Менеджер = Справочники[ИмяСправочника]; // или Документы[ИмяДокумента]

СсылкаНаЭлемент = Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаУИД));

В запросах ссылка получается полем Ссылка любой объектной таблицы. Это предпочтительный способ поиска по произвольным реквизитам, для которых нет штатных методов НайтиПо... — например, поиск номенклатуры по артикулу:

Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка ИЗ Справочник.Номенклатура ГДЕ Артикул = &Артикул");

Запрос.УстановитьПараметр("Артикул", "КБЛ-325");

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

СсылкаНаЭлемент = Выборка.Ссылка;

КонецЕсли;

Маршрут решения

Как выбрать способ получения ссылки

Известен уникальный идентификатор (обмен, внешняя система)Используйте ПолучитьСсылку(УИД) с последующей проверкой существования объекта
Известен код справочника или номер документаИспользуйте НайтиПоКоду() или НайтиПоНомеру() с проверкой на пустую ссылку
Известны только произвольные реквизиты (артикул, ИНН, штрихкод)Выполните запрос с отбором по реквизиту и возьмите поле Ссылка
Ссылка уже есть в реквизите другого объектаПросто прочитайте реквизит — поиск не нужен

Типичные ошибки при работе со ссылками

Большинство проблем со ссылками связано с пропущенными проверками и непониманием разницы между ссылкой и объектом. Разбор частых сценариев помогает избежать ошибок в продуктивной базе.

Отдельного внимания заслуживает сравнение ссылок. Оператор сравнения ссылок разных типов (например, ссылки справочника и документа) вернёт Ложь без ошибки, но сравнение ссылки с Неопределено или строкой в некоторых контекстах приведёт к неожиданным результатам. Для проверки типа используйте ТипЗнч() и Тип().

Типичные ошибки
01
Сравнение результата НайтиПоКоду с Неопределено вместо ПустаяСсылка() — проверка никогда не сработает, и код пойдёт дальше с пустой ссылкой
02
Вызов ПолучитьОбъект() в цикле для чтения одного реквизита — резкое падение производительности на больших объёмах
03
Использование НайтиПоНаименованию без учёта дублей — при одинаковых наименованиях берётся не тот элемент
04
Чтение реквизитов ссылки, полученной по УИД, без проверки существования — ошибка «Объект не найден» в продуктиве
05
Хранение ссылки как строки наименования вместо УИД при обмене — после переименования элемента связь теряется

Производительность и безопасная работа в продуктивной базе

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

Любые эксперименты с программным созданием и изменением объектов выполняйте сначала на копии базы. Запись объекта с неправильно полученной ссылкой может создать дубли или перезаписать данные, а откат в файловой базе без резервной копии невозможен.

Итог

Что важно запомнить

Ссылку получают через менеджер типа: ПолучитьСсылку(УИД) — по идентификатору, НайтиПоКоду / НайтиПоНаименованию / НайтиПоНомеру — по данным, запрос — по произвольным реквизитам. Результат поиска всегда проверяйте на пустую ссылку, а ссылку по УИД — на существование объекта. Для чтения данных используйте ссылку, ПолучитьОбъект() — только для изменения.

Частые вопросы

Чем ссылка отличается от уникального идентификатора?

Ссылка — типизированное значение платформы, которое «знает», к какому виду объекта относится (справочник, документ). Уникальный идентификатор — просто GUID, строка из 36 символов без привязки к типу. Из ссылки всегда можно получить УИД, а из УИД — ссылку только если известен тип объекта.

Почему НайтиПоКоду не находит элемент, который точно есть?

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

Можно ли получить ссылку на ещё не записанный объект?

Да. У нового объекта, созданного через СоздатьЭлемент() или СоздатьДокумент(), можно заранее установить ссылку методом УстановитьСсылкуНового() — это используется в обменах, чтобы сохранить связи до записи. Если ссылку не установить, она будет назначена автоматически при записи.

Как получить ссылку, если тип объекта заранее неизвестен?

Используйте метаданные: переберите менеджеры через Метаданные.Справочники / Метаданные.Документы или обратитесь к менеджеру по имени — Справочники[ИмяТипа]. Для восстановления ссылки из строкового представления вида «Справочник.Номенклатура» есть метод ЗначениеИзСтрокиВнутр(), но он предназначен для служебных механизмов и требует осторожности.

Что быстрее: НайтиПоКоду или запрос?

Для одиночного поиска по коду разница незначительна — оба варианта используют индекс. При массовой обработке выгоднее один запрос с соединением или условием «В», чем тысячи отдельных вызовов НайтиПоКоду, каждый из которых — отдельное обращение к базе.

Как проверить, что две ссылки указывают на один объект?

Достаточно обычного сравнения: Если Ссылка1 = Ссылка2 Тогда. Ссылки одного типа равны, когда совпадают их уникальные идентификаторы. Сравнивать строковые представления или УИД отдельно не требуется.