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

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

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

Разбираем способы получить ссылку на элемент справочника в 1С на клиенте: через форму, ПредопределенноеЗначение, поиск по коду и наименованию, с примерами кода.

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

Есть несколько рабочих подходов: взять ссылку из данных формы, получить предопределённый элемент через ПредопределенноеЗначение, выполнить поиск в серверной функции и вернуть результат на клиент. Выбор зависит от того, откуда берётся значение — из реквизита формы, из настроек или его нужно найти по произвольным критериям.

Что такое ссылка на справочник и почему её нельзя просто создать

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

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

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

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

&НаКлиенте

Процедура КонтрагентПриИзменении(Элемент)

СсылкаНаКонтрагента = Объект.Контрагент;

Если ЗначениеЗаполнено(СсылкаНаКонтрагента) Тогда

// дальнейшие действия со ссылкой

КонецЕсли;

КонецПроцедуры

Если нужно получить реквизиты этой ссылки (например, ИНН контрагента), разыменование через точку на клиенте в управляемой форме может вызвать неявный серверный вызов на каждое обращение. Правильнее получить все нужные поля одним серверным вызовом или через ОбщегоНазначения.ЗначенияРеквизитовОбъекта на сервере.

Получение предопределённого элемента на клиенте

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

&НаКлиенте

Процедура КомандаПодставитьВалюту(Команда)

ВалютаРуб = ПредопределенноеЗначение("Справочник.Валюты.Рубль");

Объект.Валюта = ВалютаРуб;

КонецПроцедуры

Имя элемента в строке — это имя предопределённого элемента из конфигуратора, а не его наименование в базе. Если элемент переименуют в пользовательском режиме, код продолжит работать; если переименуют в конфигураторе — код сломается, поэтому такие имена лучше не менять после внедрения.

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

Методы НайтиПоКоду, НайтиПоНаименованию и НайтиПоРеквизиту доступны только на сервере. Стандартный приём — создать в модуле формы или общем модуле серверную функцию, которая выполнит поиск и вернёт ссылку на клиент.

&НаСервереБезКонтекста

Функция НайтиНоменклатуруПоКоду(Код)

Возврат Справочники.Номенклатура.НайтиПоКоду(Код);

КонецФункции

&НаКлиенте

Процедура ПодобратьПоКоду(Команда)

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

Если ЗначениеЗаполнено(Ссылка) Тогда

Объект.Номенклатура = Ссылка;

Иначе

ПоказатьПредупреждение(, "Элемент с таким кодом не найден");

КонецЕсли;

КонецПроцедуры

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

Порядок поиска ссылки по коду
  1. 1
    Создайте серверную функцию с директивой &НаСервереБезКонтекста
  2. 2
    Внутри вызовите Справочники.Имя.НайтиПоКоду(Код) и верните результат
  3. 3
    На клиенте вызовите функцию и проверьте результат через ЗначениеЗаполнено
  4. 4
    При успехе заполните реквизит формы полученной ссылкой
  5. 5
    При пустом результате сообщите пользователю, что элемент не найден

Создание нового элемента и получение его ссылки

Иногда элемента в базе нет, и его нужно создать программно. На клиенте это невозможно: создание и запись объекта выполняются только на сервере. Клиент передаёт данные для заполнения, сервер создаёт объект, записывает и возвращает ссылку.

&НаСервереБезКонтекста

Функция СоздатьЕдиницуИзмерения(Наименование)

НовыйЭлемент = Справочники.УпаковкиЕдиницыИзмерения.СоздатьЭлемент();

НовыйЭлемент.Наименование = Наименование;

НовыйЭлемент.Записать();

Возврат НовыйЭлемент.Ссылка;

КонецФункции

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

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

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

&НаСервереБезКонтекста

Функция СсылкаПоUUID(СтрокаUUID)

Идентификатор = Новый УникальныйИдентификатор(СтрокаUUID);

Возврат Справочники.Номенклатура.ПолучитьСсылку(Идентификатор);

КонецФункции

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

Типичные ошибки и как их избежать

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

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

Типичные ошибки
01
Вызов НайтиПоКоду в &НаКлиенте — метод недоступен, перенесите поиск в серверную функцию
02
Отсутствие проверки результата поиска — при пустой ссылке в реквизит запишется пустое значение без предупреждения
03
Получение реквизитов ссылки через точку в цикле на клиенте — десятки серверных вызовов, замените одним запросом
04
Сравнение ссылок через строковое представление — медленно и ненадёжно, сравнивайте ссылки напрямую
05
Создание элемента без проверки дублей — справочник засоряется повторяющимися записями

Проверка результата и выбор подхода

После получения ссылки всегда убедитесь, что она заполнена и соответствует ожиданиям. Минимальная проверка — ЗначениеЗаполнено(Ссылка). Для предопределённых элементов и ссылок по UUID дополнительно полезно убедиться, что элемент реально существует в базе, особенно в распределённых и мигрированных системах.

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

Как выбрать способ

Значение уже выбрано пользователем в поле формыБерите ссылку напрямую из реквизита формы, без дополнительных вызовов
Нужен предопределённый элемент конфигурацииИспользуйте ПредопределенноеЗначение прямо на клиенте
Элемент нужно найти по коду, наименованию или реквизитуВыполните поиск в серверной функции и верните ссылку на клиент
Есть строковый UUID из обмена или файлаПреобразуйте через УникальныйИдентификатор и ПолучитьСсылку на сервере
Элемента нет и его нужно создатьСоздавайте объект на сервере, после записи возвращайте Ссылка на клиент
Итог

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

На клиенте доступны только ссылки из данных формы и ПредопределенноеЗначение. Любой поиск, создание и восстановление по UUID выполняются на сервере, а на клиент возвращается готовая ссылка. Результат всегда проверяйте через ЗначениеЗаполнено.

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

Можно ли вызвать НайтиПоНаименованию прямо на клиенте?

Нет. Менеджеры справочников и их методы поиска доступны только в серверном контексте управляемого приложения. Оберните поиск в серверную функцию и вызывайте её из клиентской процедуры.

Чем ПредопределенноеЗначение лучше поиска по наименованию?

Она работает на клиенте без обращения к серверу и привязана к имени элемента в конфигураторе, а не к изменяемому пользователем наименованию. Это быстрее и надёжнее, но применимо только к предопределённым элементам.

Почему ПолучитьСсылку вернула значение, а элемента в базе нет?

Метод формирует ссылку из переданного UUID, не проверяя существование записи. Если элемент с таким идентификатором удалён или никогда не существовал, получится «битая» ссылка. Проверяйте наличие данных запросом или через реквизиты.

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

Обращение Ссылка.Наименование на клиенте вызовет неявный серверный вызов. Для одного поля это допустимо, но при массовых обращениях получите все нужные реквизиты одной серверной функцией и верните структуру.

Как сравнить две ссылки на равенство?

Оператором равенства напрямую: Ссылка1 = Ссылка2. Сравнение ссылок корректно работает без преобразования в строки и не требует обращения к данным объектов.

Что вернёт поиск, если элемент помечен на удаление?

НайтиПоКоду и НайтиПоНаименованию находят и помеченные на удаление элементы. Если такие элементы нужно исключить, дополнительно проверяйте реквизит ПометкаУдаления у найденной ссылки на сервере.