Разработка и Конфигурация · 13 мин
Как в 1С получить ссылку на элемент справочника
Как получить ссылку на элемент справочника в 1С: методы НайтиПоКоду, НайтиПоНаименованию, ПолучитьСсылку по GUID и запрос. Примеры кода, проверка пустой ссылки, типичные ошибки.
Ссылка на элемент справочника — один из самых востребованных объектов при разработке на платформе 1С:Предприятие. Через ссылку выполняется обращение к реквизитам элемента, запись связанных данных, сравнение значений и передача элемента между процедурами. Понимание того, как правильно получить ссылку, избавляет от типичных ошибок: обращений к несуществующим объектам, лишних запросов к базе и падения кода на пустых значениях.
Встроенный язык 1С предлагает несколько способов получения ссылки: поиск по коду, по наименованию, по реквизиту, по уникальному идентификатору (GUID), а также через запрос. Каждый способ имеет свою область применения, скорость работы и ограничения. Ниже разобраны все основные варианты с примерами кода, приёмами проверки результата и типичными ошибками.
Что такое ссылка и чем она отличается от объекта
В 1С элемент справочника существует в двух представлениях: СправочникСсылка и СправочникОбъект. Ссылка — это лёгкий указатель на запись в базе данных: она содержит уникальный идентификатор и позволяет читать реквизиты элемента, но не изменять их. Объект — это полная копия данных элемента в памяти, которую можно модифицировать и записать.
Разделение важно для производительности. Получение объекта через метод ПолучитьОбъект() вызывает чтение всей записи из базы и блокирует её при изменении. Если нужно только сравнить значение или прочитать пару реквизитов, достаточно ссылки. Присваивание ссылки реквизиту документа или другого справочника не требует загрузки объекта вообще.
Ссылка существует даже для ещё не записанного элемента: платформа может сгенерировать её заранее через ПолучитьСсылку() без параметров. Это используется, когда нужно сначала создать ссылку, а затем записать объект с уже известным идентификатором — например, при обмене данными между базами.
Поиск ссылки по коду
Метод НайтиПоКоду() — самый быстрый способ поиска, потому что код справочника проиндексирован. Он подходит, когда код элемента известен заранее: например, при загрузке данных из внешних систем, где код служит ключом синхронизации.
ЭлементСсылка = Справочники.Номенклатура.НайтиПоКоду("000000123");
Если ЭлементСсылка.Пустая() Тогда
Сообщить("Элемент с кодом не найден");
Иначе
Сообщить("Найден: " + ЭлементСсылка.Наименование);
КонецЕсли;
У метода есть второй необязательный параметр — ПоискПоПолномуКоду. По умолчанию для иерархических справочников поиск идёт по коду в пределах родителя, а если передать Истина, платформа будет искать по полному коду с учётом иерархии. Третий параметр позволяет ограничить поиск конкретным родителем.
Обратите внимание на тип кода. Если код справочника числовой, а вы передаёте строку (или наоборот), поиск может не сработать. Для строковых кодов с нефиксированной длиной ведущие нули влияют на результат сравнения — это частая причина «неработающего» поиска.
Поиск по наименованию и по реквизиту
Метод НайтиПоНаименованию() ищет элемент по точному совпадению наименования. Важно: поиск регистронезависим, но чувствителен к пробелам и полной строке — частичное совпадение не сработает.
КонтрагентСсылка = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка");
Если КонтрагентСсылка.Пустая() Тогда
// элемента нет — можно создать новый
КонецЕсли;
Для поиска по любому другому реквизиту используется НайтиПоРеквизиту(). Типичный пример — поиск контрагента по ИНН или товара по штрихкоду:
Найденный = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7707083893");
Оба метода возвращают первый найденный элемент. Если в базе несколько элементов с одинаковым наименованием или значением реквизита, нет гарантии, какой именно вернётся. Когда дубли недопустимы, лучше использовать запрос с явной сортировкой или контролировать уникальность на уровне данных.
Получение ссылки по уникальному идентификатору (GUID)
Когда известен GUID элемента — например, он пришёл из другой базы при обмене или из внешнего хранилища — ссылку получают методом ПолучитьСсылку():
Ид = Новый УникальныйИдентификатор("b3f5a1c2-1234-4abc-9def-0123456789ab");
ЭлементСсылка = Справочники.Номенклатура.ПолучитьСсылку(Ид);
Особенность этого способа: метод не проверяет, существует ли элемент в базе. Он просто конструирует ссылку из идентификатора. Если элемента с таким GUID нет, вы получите «битую ссылку» — объект с признаком удалённой записи. Поэтому после ПолучитьСсылку обязательна проверка существования:
Если ЭлементСсылка.ПолучитьОбъект() = Неопределено Тогда
Сообщить("Элемент с таким GUID не существует");
КонецЕсли;
Альтернативный способ проверки без загрузки объекта — запрос по ссылке. Он быстрее и не создаёт объект в памяти, что важно при массовой проверке идентификаторов.
Получение ссылки через запрос
Запрос — универсальный способ, когда условия поиска сложнее одного реквизита: несколько отборов, поиск по подстроке, отбор по владельцу или родителю, сортировка для выбора нужного дубля.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Артикул = &Артикул
| И НЕ Номенклатура.ПометкаУдаления";
Запрос.УстановитьПараметр("Артикул", "АРТ-1001");
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ЭлементСсылка = Выборка.Ссылка;
КонецЕсли;
Преимущества запроса: поля выбираются явно, можно сразу исключить помеченные на удаление, отсортировать дубли по дате создания и взять первый. Недостаток — больше кода и чуть большие накладные расходы на одиночный поиск по индексированному полю, где НайтиПоКоду работает быстрее.
Сравнение вариантов
Самый быстрый поиск по индексу. Подходит, когда код известен и уникален. Не работает для поиска по другим полям.
Простой синтаксис, но только точное совпадение и первый найденный элемент. Медленно на больших таблицах без индекса.
Единственный способ восстановить ссылку из внешнего идентификатора. Требует отдельной проверки существования элемента.
Гибкие условия, отбор дублей, исключение помеченных. Оптимален для массовой обработки и сложных отборов.
Создание нового элемента и получение его ссылки
Когда элемент нужно создать программно, ссылка появляется после записи объекта. Стандартная последовательность выглядит так:
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Новый товар";
// заполнение других реквизитов
НовыйЭлемент.Записать();
НоваяСсылка = НовыйЭлемент.Ссылка;
Если ссылка нужна до записи — например, чтобы зарегистрировать её в плане обмена или передать в другую процедуру — используют связку ПолучитьСсылку() и УстановитьСсылкуНового():
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НоваяСсылка = Справочники.Номенклатура.ПолучитьСсылку();
НовыйЭлемент.УстановитьСсылкуНового(НоваяСсылка);
НовыйЭлемент.Наименование = "Товар с заданным GUID";
НовыйЭлемент.Записать();
Такой приём гарантирует, что объект запишется именно с тем идентификатором, который вы сохранили заранее. Без УстановитьСсылкуНового платформа сгенерирует новый GUID при записи, и заранее полученная ссылка окажется битой.
Проверка результата и работа с пустой ссылкой
Любой поиск может ничего не найти, и код обязан это обрабатывать. НайтиПоКоду, НайтиПоНаименованию и НайтиПоРеквизиту при отсутствии результата возвращают пустую ссылку. Проверка выполняется двумя способами:
Если ЭлементСсылка.Пустая() Тогда
// элемент не найден
КонецЕсли;
// или через менеджер
Если Справочники.Номенклатура.ПустаяСсылка() = ЭлементСсылка Тогда
// элемент не найден
КонецЕсли;
Обращение к реквизитам пустой ссылки вернёт значения по умолчанию (пустые строки, нули), а не ошибку — из-за этого дефект может остаться незамеченным и «протечь» дальше по логике. Обращение к реквизитам битой ссылки (несуществующего элемента) также не вызывает исключения при чтении через точку, но объект для неё получить нельзя.
Как проверить результат
Метод Пустая() возвращает Ложь, реквизиты читаются
Пустая() = Истина — элемент не найден, искать причину в типе кода
Запрос по ссылке возвращает запись
Запрос пуст — ссылка битая, элемент отсутствует в базе
Свойство Ссылка заполнено, элемент открывается в списке
Ссылка пустая — запись не выполнена, смотреть исключения в ЖурналеРегистрации
Типичные ошибки и ограничения
Отдельная группа проблем связана с правами доступа. Пользователь без права чтения справочника получит пустой результат поиска без какого-либо сообщения об ошибке. Если код «внезапно» перестал находить элементы после настройки ролей, первым делом проверьте права и ограничения RLS на уровне записей.
В управляемых формах и на клиенте есть ограничение: методы НайтиПоКоду и подобные вызывают серверный контекст. В тонком клиенте поиск из клиентской процедуры потребует вызова серверной процедуры — это нормально, но массовые обращения стоит собирать в один серверный вызов, чтобы не плодить сетевые обращения.
При обмене между базами надёжнее синхронизировать элементы по GUID, а не по коду или наименованию: код может повторяться в разных узлах, а наименование пользователи редактируют. GUID элемента неизменен на протяжении всей его жизни.
Выбор способа под задачу
Как выбрать действие
Для одиночного поиска по коду или наименованию методы менеджера справочника проще и читабельнее. Для всего остального — GUID, сложные условия, массовая обработка, контроль дублей — запрос даёт больше контроля и предсказуемую производительность. В любом случае результат поиска должен проходить проверку на пустую ссылку до того, как значение уйдёт в дальнейшую логику.
Что важно запомнить
Ссылку получают через менеджер справочника: НайтиПоКоду, НайтиПоНаименованию, НайтиПоРеквизиту, ПолучитьСсылку по GUID или запросом. Результат всегда проверяется через Пустая(), а для ссылки по GUID — дополнительно проверяется существование элемента. Для чтения реквизитов достаточно ссылки, объект нужен только для изменения данных.
Частые вопросы
Как получить ссылку на предопределённый элемент справочника?
Через менеджер по имени предопределённого элемента: Справочники.Валюты.НайтиПредопределенный("Рубль") — либо прямым обращением Справочники.Валюты.Рубль, если имя задано в конфигураторе. Второй вариант короче, но при переименовании элемента в конфигурации код придётся править.
Чем битая ссылка отличается от пустой?
Пустая ссылка — это штатное значение «ничего не выбрано», её Пустая() возвращает Истина. Битая ссылка содержит GUID несуществующего элемента: Пустая() вернёт Ложь, но элемент в базе отсутствует. Проверяется запросом по ссылке или попыткой получить объект — он вернёт Неопределено.
Как найти все элементы с одинаковым наименованием, а не первый?
Методы НайтиПоНаименованию возвращают только один элемент. Для получения всех дублей используйте запрос с условием по наименованию без ограничения ПЕРВЫЕ 1 и обойдите выборку в цикле.
Можно ли получить ссылку на группу справочника?
Да, теми же методами: НайтиПоКоду и НайтиПоНаименованию имеют параметр, указывающий искать среди групп, либо можно проверить свойство ЭтоГруппа у найденной ссылки. Создаётся группа методом СоздатьГруппу() вместо СоздатьЭлемент().
Почему НайтиПоКоду не находит элемент, который точно есть?
Чаще всего причины три: несовпадение типа кода (строка вместо числа), ведущие нули или пробелы в строковом коде, а также поиск внутри родителя при иерархическом справочнике — попробуйте передать параметр поиска по полному коду равным Истина. Реже виноваты права доступа или RLS.
Как получить ссылку на клиенте в управляемой форме?
Напрямую методы поиска на тонком клиенте недоступны. Вынесите поиск в серверную процедуру общего модуля с признаком Сервер и вызывайте её из клиентского кода, передавая параметры поиска и получая обратно найденную ссылку.