Разработка и Конфигурация · 10 мин
Как получить ссылку на объект в 1С программно
Как программно получить ссылку на объект в 1С: методы ПолучитьСсылку, НайтиПоКоду, НайтиПоНаименованию, работа с уникальным идентификатором и типичные ошибки.
Ссылка — основной способ обращения к данным в 1С: любой элемент справочника, документ, элемент плана счетов или иной объект ссылочного типа существует в базе как уникальная запись, и работать с ней из кода можно только через ссылку. При этом у начинающих разработчиков часто возникает путаница между ссылкой и объектом: ссылка — это «указатель» на запись в базе, а объект — полная копия данных, полученная через метод ПолучитьОбъект(). Для большинства задач достаточно ссылки, и грузить объект целиком не нужно.
Получить ссылку программно можно несколькими способами: по уникальному идентификатору, по коду или номеру, по наименованию, из результата запроса, из реквизита другого объекта или из параметра, переданного в процедуру. Выбор способа зависит от того, какими данными о нужной записи вы располагаете. Ниже разобраны все основные варианты с примерами кода и типичными ошибками.
Чем ссылка отличается от объекта
Ссылка — это лёгкий идентификатор записи в базе. Присвоение переменной ссылки не вызывает обращения к данным: платформа хранит только тип объекта и его уникальный идентификатор. Обращение к реквизитам через точку (Ссылка.Наименование) заставляет платформу неявно прочитать данные из базы — это удобно, но в циклах приводит к множеству мелких запросов.
Объект получают вызовом Ссылка.ПолучитьОбъект() — это полная копия данных в памяти, которую можно изменять и записывать методом Записать(). Если задача сводится к чтению пары реквизитов или передаче значения в отбор, объект получать не нужно: это лишняя нагрузка на сервер.
Получение ссылки по коду или номеру
Самый частый сценарий — найти элемент справочника по коду или документ по номеру. Для этого у менеджера объекта есть методы НайтиПоКоду() и НайтиПоНомеру(). Методы возвращают ссылку или пустую ссылку, если запись не найдена.
СсылкаТовара = Справочники.Номенклатура.НайтиПоКоду("000000123");
Если СсылкаТовара.Пустая() Тогда
Сообщить("Элемент не найден");
КонецЕсли;
// Документ по номеру за период
СсылкаДокумента = Документы.РеализацияТоваровУслуг.НайтиПоНомеру("000000045", ТекущаяДатаСеанса());Обратите внимание на два нюанса. Во-первых, для НайтиПоКоду() есть второй параметр — код в пределах подчинения (по умолчанию поиск идёт по всему справочнику). Во-вторых, для документов номер уникален только в пределах периода (обычно года), поэтому вторым параметром передаётся дата, определяющая интервал поиска. Если дату не указать, поиск будет идти в текущем периоде нумерации, и документ прошлого года может не найтись.
Поиск ссылки по наименованию и реквизиту
Метод НайтиПоНаименованию() ищет элемент справочника по точному совпадению наименования. Третий параметр отвечает за точное соответствие: значение Истина исключает частичные совпадения. Учтите, что наименования могут дублироваться — метод вернёт первый найденный элемент, что не всегда ожидаемо.
СсылкаКонтрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка", Истина);
// Поиск по произвольному реквизиту
СсылкаПоИНН = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7701234567");Метод НайтиПоРеквизиту() работает только с реквизитами, для которых в конфигураторе включено индексирование, — иначе поиск будет выполняться полным перебором и на больших справочниках заметно замедлит работу. Если реквизит не проиндексирован, надёжнее использовать запрос с явным отбором.
Получение ссылки по уникальному идентификатору (GUID)
Если известен GUID записи — например, он получен из внешней системы, файла обмена или строки вида «e0a1f2b3-...», — ссылку можно сконструировать напрямую через метод ПолучитьСсылку() менеджера объекта.
УИД = Новый УникальныйИдентификатор("e0a1f2b3-4c5d-6e7f-8a9b-0c1d2e3f4a5b");
СсылкаЭлемента = Справочники.Номенклатура.ПолучитьСсылку(УИД);
// Проверка, что запись реально существует
Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", СсылкаЭлемента);
Если Запрос.Выполнить().Пустой() Тогда
Сообщить("Записи с таким GUID нет в базе");
КонецЕсли;Важный подвох: ПолучитьСсылку() не проверяет, существует ли запись в базе. Метод просто формирует ссылку из идентификатора. Если записи с таким GUID нет, вы получите «битую ссылку» — значение, которое выглядит как обычная ссылка, но при обращении к реквизитам возвращает неопределённые значения или ошибку. Поэтому после конструирования ссылки по GUID её существование нужно проверять запросом или через ПолучитьОбъект() с проверкой на Неопределено.
Обратная задача — получить GUID из существующей ссылки — решается через Ссылка.УникальныйИдентификатор(). Это полезно при интеграциях, когда во внешнюю систему нужно передать стабильный идентификатор записи.
Ссылка из запроса, реквизита и других источников
Самый производительный способ получить много ссылок — запрос. Поле Ссылка есть у любой ссылочной таблицы, и выборка вернёт готовые ссылки без дополнительных обращений к базе.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Товар
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СсылкаТовара = Выборка.Товар;
КонецЦикла;Кроме запроса, ссылки приходят из реквизитов других объектов (например, СтрокаТЧ.Номенклатура — уже ссылка), из параметров процедур форм, из полей выбора и из результата НайтиПоКоду()-подобных методов. Преобразовывать их никуда не нужно — это готовые значения ссылочного типа.
Как проверить результат и не допустить ошибок
Любой поиск ссылки может вернуть «ничего», и корректная обработка этого случая — обязательная часть кода. Минимальный набор проверок: пустая ли ссылка, существует ли запись (для ссылок по GUID), не помечена ли она на удаление.
Как проверить результат
Ссылка.Пустая() возвращает Ложь
Пустая() = Истина — запись не найдена, дальнейшее использование даст пустые реквизиты
Запрос по ссылке возвращает строку
Запрос пустой — битая ссылка, записи нет в базе
ПометкаУдаления = Ложь
Элемент помечен на удаление — использовать в новых документах нежелательно
Выбор способа под задачу
Единого «правильного» метода нет — выбор определяется тем, что у вас есть на входе и сколько записей нужно обработать.
Как выбрать действие
Для разовых операций в обработчиках форм достаточно методов поиска. Для обменов и пакетной обработки всегда переходите на запросы: разница в производительности между «найти тысячу ссылок по одной» и «выбрать тысячу ссылок одним запросом» измеряется порядками.
Что важно запомнить
Ссылка — это идентификатор записи, а не сами данные. Основные способы получения: НайтиПоКоду, НайтиПоНаименованию, НайтиПоРеквизиту, НайтиПоНомеру, ПолучитьСсылку по GUID и выборка запросом. Всегда проверяйте результат на пустоту, а ссылку по GUID — на реальное существование записи.
Частые вопросы
Что вернёт НайтиПоКоду, если элемент не найден?
Пустую ссылку соответствующего типа, а не Неопределено. Проверять результат нужно методом Пустая(): Если Ссылка.Пустая() Тогда .... Сравнение с Неопределено не сработает.
Как получить ссылку на новый, ещё не записанный элемент?
Создайте объект через Справочники.Номенклатура.СоздатьЭлемент(), затем вызовите НовыйОбъект.ПолучитьСсылкуНового() — платформа вернёт ссылку, которая будет назначена при записи. Если ссылка нужна заранее (например, для заполнения реквизита другого объекта), можно назначить её самостоятельно через УстановитьСсылкуНового().
Чем опасно обращение к реквизитам через точку от ссылки?
Каждое обращение вида Ссылка.Наименование — это неявное чтение данных из базы. Вне цикла это приемлемо, но внутри цикла по тысяче строк вы получите тысячу отдельных запросов. Правильный подход — один запрос, выбирающий сразу все нужные поля.
Как узнать тип ссылки в коде?
Через функцию ТипЗнч(Ссылка) и сравнение с нужным типом, например: Если ТипЗнч(Ссылка) = Тип("СправочникСсылка.Номенклатура") Тогда .... Альтернатива — получить имя типа строкой через Ссылка.Метаданные().Имя, что удобно для универсальных обработок.
Можно ли получить ссылку из строки вида «Справочник.Номенклатура»?
Да, связку «имя типа + GUID» можно разобрать: получить менеджер через Справочники[Имя] или Документы[Имя] и вызвать ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID)). Именно так работают многие механизмы обмена. Не забудьте проверить существование записи после конструирования.
Почему НайтиПоНомеру не находит документ, который точно есть?
Чаще всего потому, что не передан второй параметр — дата периода. Номер документа уникален только внутри периода нумерации (обычно года), и без даты поиск идёт в текущем периоде. Передайте дату искомого документа вторым параметром.