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

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

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

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

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

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

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

Как пользователю выбрать элемент справочника в форме

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

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

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

Как программно найти элемент по коду

Метод НайтиПоКоду — самый быстрый способ, потому что код справочника обычно проиндексирован и уникален в рамках серии или всего справочника. Метод вызывается у менеджера справочника и возвращает ссылку.

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

Если ЭлементСсылка.Пустая() Тогда

Сообщить("Элемент с таким кодом не найден");

КонецЕсли;

Учтите нюансы: у справочника может быть отключена нумерация (длина кода равна нулю) — тогда метод бесполезен. Если включены серии кодов (в пределах подчинения или группы), один и тот же код может повторяться, и у метода есть дополнительные параметры для уточнения области поиска.

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

Метод НайтиПоНаименованию ищет точное совпадение строки с наименованием (без учёта регистра). Он не ищет «по части строки» — для поиска по подстроке нужен запрос с конструкцией ПОДОБНО.

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

Когда идентификатором служит не код и не наименование, а, например, ИНН, артикул или штрихкод, используется НайтиПоРеквизиту:

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

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

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

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

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

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

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

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

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

Метод Пустая() возвращает Ложь

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

Пустая() возвращает Истина — элемент не существует

Корректность элемента
Норма

Реквизиты читаются, ПометкаУдаления = Ложь

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

Элемент помечен на удаление или содержит устаревшие данные

Производительность
Норма

Поиск в цикле занимает приемлемое время

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

Загрузка «зависает» — поиск идёт по неиндексированному реквизиту

Когда искать запросом вместо методов поиска

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Номенклатура.Ссылка КАК Ссылка

|ИЗ Справочник.Номенклатура КАК Номенклатура

|ГДЕ Номенклатура.Наименование ПОДОБНО &Шаблон

| И НЕ Номенклатура.ПометкаУдаления";

Запрос.УстановитьПараметр("Шаблон", "%" + СтрокаПоиска + "%");

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

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

НайденнаяСсылка = Выборка.Ссылка;

КонецЕсли;

Сравнение вариантов

НайтиПоКоду

Самый быстрый, код индексирован. Не подходит, если нумерация отключена или коды повторяются в сериях

НайтиПоНаименованию

Только точное совпадение строки. Риск дублей, если наименования не уникальны

НайтиПоРеквизиту

Гибкий поиск по ИНН, артикулу и т.п. Требует индекса на реквизите для больших справочников

Запрос

Любые условия, ПОДОБНО, несколько полей. Чуть больше кода, но оптимален для сложных отборов

Что делать, если элемент не найден

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

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

Ограничения и безопасные границы

На клиенте в управляемом приложении методы НайтиПо* недоступны без серверного вызова — поиск выполняется в серверной процедуре. Помещайте такой код в процедуры с директивой &НаСервере или в общие модули с признаком «Сервер».

При массовых загрузках избегайте поиска внутри цикла по одному элементу: выгоднее один запросом получить соответствие «ключ → ссылка» для всей пачки данных и затем брать ссылки из памяти. Это снижает число обращений к базе с тысяч до одного.

Изменение и создание элементов справочников в рабочей базе выполняйте с учётом прав доступа и при необходимости — в копии базы. Ошибочная массовая запись в справочник, на который ссылаются документы, способна нарушить отчётность.

Итог

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

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

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

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

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

Как найти элемент по части наименования?

Методы НайтиПоНаименованию для этого не подходят — они ищут точное совпадение. Используйте запрос с условием Наименование ПОДОБНО &Шаблон, где шаблон содержит символы % по краям искомой подстроки.

Почему НайтиПоКоду не находит существующий элемент?

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

Можно ли выполнить поиск на клиенте в управляемой форме?

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

Что вернёт поиск, если подходящих элементов несколько?

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

Как проверить, что ссылка не «битая»?

Битая ссылка возникает после физического удаления элемента. Программно её можно выявить запросом: если выборка по условию Ссылка = &Ссылка пуста, значит объекта в базе нет. Для интерактивной проверки используйте обработку поиска и удаления битых ссылок.