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

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

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

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

Ссылка — основной способ обращения к данным в 1С: любой элемент справочника, документ, элемент плана счетов или иной объект ссылочного типа существует в базе как уникальная запись, и работать с ней из кода можно только через ссылку. При этом у начинающих разработчиков часто возникает путаница между ссылкой и объектом: ссылка — это «указатель» на запись в базе, а объект — полная копия данных, полученная через метод ПолучитьОбъект(). Для большинства задач достаточно ссылки, и грузить объект целиком не нужно.

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

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

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

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

Получение ссылки по коду или номеру

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

bsl
СсылкаТовара = Справочники.Номенклатура.НайтиПоКоду("000000123");
Если СсылкаТовара.Пустая() Тогда
    Сообщить("Элемент не найден");
КонецЕсли;

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

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

Поиск ссылки по наименованию и реквизиту

Метод НайтиПоНаименованию() ищет элемент справочника по точному совпадению наименования. Третий параметр отвечает за точное соответствие: значение Истина исключает частичные совпадения. Учтите, что наименования могут дублироваться — метод вернёт первый найденный элемент, что не всегда ожидаемо.

bsl
СсылкаКонтрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка", Истина);

// Поиск по произвольному реквизиту
СсылкаПоИНН = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7701234567");

Метод НайтиПоРеквизиту() работает только с реквизитами, для которых в конфигураторе включено индексирование, — иначе поиск будет выполняться полным перебором и на больших справочниках заметно замедлит работу. Если реквизит не проиндексирован, надёжнее использовать запрос с явным отбором.

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

Если известен GUID записи — например, он получен из внешней системы, файла обмена или строки вида «e0a1f2b3-...», — ссылку можно сконструировать напрямую через метод ПолучитьСсылку() менеджера объекта.

bsl
УИД = Новый УникальныйИдентификатор("e0a1f2b3-4c5d-6e7f-8a9b-0c1d2e3f4a5b");
СсылкаЭлемента = Справочники.Номенклатура.ПолучитьСсылку(УИД);

// Проверка, что запись реально существует
Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", СсылкаЭлемента);
Если Запрос.Выполнить().Пустой() Тогда
    Сообщить("Записи с таким GUID нет в базе");
КонецЕсли;

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

Обратная задача — получить GUID из существующей ссылки — решается через Ссылка.УникальныйИдентификатор(). Это полезно при интеграциях, когда во внешнюю систему нужно передать стабильный идентификатор записи.

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

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

bsl
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Товар
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    СсылкаТовара = Выборка.Товар;
КонецЦикла;

Кроме запроса, ссылки приходят из реквизитов других объектов (например, СтрокаТЧ.Номенклатура — уже ссылка), из параметров процедур форм, из полей выбора и из результата НайтиПоКоду()-подобных методов. Преобразовывать их никуда не нужно — это готовые значения ссылочного типа.

Как проверить результат и не допустить ошибок

Любой поиск ссылки может вернуть «ничего», и корректная обработка этого случая — обязательная часть кода. Минимальный набор проверок: пустая ли ссылка, существует ли запись (для ссылок по GUID), не помечена ли она на удаление.

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

Как проверить результат

Ссылка найдена поиском
Норма

Ссылка.Пустая() возвращает Ложь

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

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

Ссылка по GUID
Норма

Запрос по ссылке возвращает строку

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

Запрос пустой — битая ссылка, записи нет в базе

Актуальность записи
Норма

ПометкаУдаления = Ложь

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

Элемент помечен на удаление — использовать в новых документах нежелательно

Типичные ошибки
01
Сравнение ссылки со строкой или числом вместо проверки Пустая() — условие никогда не сработает как ожидается
02
Использование НайтиПоНаименованию там, где наименования дублируются — находится не тот элемент
03
Обращение к реквизитам через точку внутри цикла — сотни лишних запросов к базе вместо одного пакетного
04
НайтиПоНомеру без указания даты — документ прошлых периодов не находится
05
Запись объекта, созданного по внешнему GUID, без проверки существования — появляются дубли при обмене

Выбор способа под задачу

Единого «правильного» метода нет — выбор определяется тем, что у вас есть на входе и сколько записей нужно обработать.

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

Как выбрать действие

Известен код элемента или номер документаИспользуйте НайтиПоКоду / НайтиПоНомеру, для документа обязательно передайте дату периода
Известен GUID из обмена или внешней системыКонструируйте ссылку через ПолучитьСсылку и проверяйте существование запросом
Нужно найти по ИНН, артикулу или другому реквизитуПроверьте индексацию реквизита и используйте НайтиПоРеквизиту либо запрос
Нужно обработать много записейИспользуйте запрос с полем Ссылка — никаких циклов с поиском по одному

Для разовых операций в обработчиках форм достаточно методов поиска. Для обменов и пакетной обработки всегда переходите на запросы: разница в производительности между «найти тысячу ссылок по одной» и «выбрать тысячу ссылок одним запросом» измеряется порядками.

Итог

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

Ссылка — это идентификатор записи, а не сами данные. Основные способы получения: НайтиПоКоду, НайтиПоНаименованию, НайтиПоРеквизиту, НайтиПоНомеру, ПолучитьСсылку по GUID и выборка запросом. Всегда проверяйте результат на пустоту, а ссылку по GUID — на реальное существование записи.

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

Что вернёт НайтиПоКоду, если элемент не найден?

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

Как получить ссылку на новый, ещё не записанный элемент?

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

Чем опасно обращение к реквизитам через точку от ссылки?

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

Как узнать тип ссылки в коде?

Через функцию ТипЗнч(Ссылка) и сравнение с нужным типом, например: Если ТипЗнч(Ссылка) = Тип("СправочникСсылка.Номенклатура") Тогда .... Альтернатива — получить имя типа строкой через Ссылка.Метаданные().Имя, что удобно для универсальных обработок.

Можно ли получить ссылку из строки вида «Справочник.Номенклатура»?

Да, связку «имя типа + GUID» можно разобрать: получить менеджер через Справочники[Имя] или Документы[Имя] и вызвать ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID)). Именно так работают многие механизмы обмена. Не забудьте проверить существование записи после конструирования.

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

Чаще всего потому, что не передан второй параметр — дата периода. Номер документа уникален только внутри периода нумерации (обычно года), и без даты поиск идёт в текущем периоде. Передайте дату искомого документа вторым параметром.