Разработка и Конфигурация · 9 мин
Как выбрать элемент справочника в 1С
Как программно выбрать элемент справочника в 1С: НайтиПоКоду, НайтиПоНаименованию, НайтиПоРеквизиту, проверка пустой ссылки, типичные ошибки и примеры кода.
Выбор элемента справочника — одна из самых частых задач в 1С: она встречается и у пользователя, который заполняет документ, и у разработчика, который пишет обработку или обмен данными. Под «выбрать элемент» обычно понимают либо интерактивный подбор значения в поле ввода, либо программный поиск существующей ссылки по коду, наименованию или произвольному реквизиту.
Ключевая особенность платформы 1С:Предприятие в том, что справочник — это таблица ссылочных данных, и работа с ним ведётся через объектную модель: Справочники.Номенклатура.НайтиПоКоду(...) и аналогичные методы. Результатом поиска всегда является ссылка, а не сам объект, что важно учитывать при проверке результата.
Ниже разобраны оба сценария: как пользователю подобрать элемент в форме и как разработчику найти ссылку программно, проверить, что поиск действительно удался, и не допустить типовых ошибок — дублей, битых ссылок и лишних вызовов сервера.
Как пользователю выбрать элемент справочника в форме
В управляемых формах поле со ссылкой на справочник поддерживает ввод по началу наименования или кода: начните печатать, и платформа покажет выпадающий список подходящих элементов. Выберите нужный клавишами или мышью — ссылка запишется в поле без открытия полной формы списка.
Если быстрый ввод не помог, нажмите кнопку выбора (или клавишу F4) — откроется форма выбора справочника. В ней доступны поиск по подстроке, отбор по реквизитам и переход по иерархии групп. Для иерархических справочников удобно сначала открыть нужную группу, чтобы список сократился.
Полезный приём — кнопка «Показать все» или очистка отбора, если элемент «не находится»: часто причина в том, что в форме выбора остался установленный ранее отбор или включён режим отображения только одной группы.
Как программно найти элемент по коду
Метод НайтиПоКоду — самый быстрый способ, потому что код справочника обычно проиндексирован и уникален в рамках серии или всего справочника. Метод вызывается у менеджера справочника и возвращает ссылку.
ЭлементСсылка = Справочники.Номенклатура.НайтиПоКоду("00012345");
Если ЭлементСсылка.Пустая() Тогда
Сообщить("Элемент с таким кодом не найден");
КонецЕсли;
Учтите нюансы: у справочника может быть отключена нумерация (длина кода равна нулю) — тогда метод бесполезен. Если включены серии кодов (в пределах подчинения или группы), один и тот же код может повторяться, и у метода есть дополнительные параметры для уточнения области поиска.
Поиск по наименованию и по произвольному реквизиту
Метод НайтиПоНаименованию ищет точное совпадение строки с наименованием (без учёта регистра). Он не ищет «по части строки» — для поиска по подстроке нужен запрос с конструкцией ПОДОБНО.
СсылкаКонтрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка");
Когда идентификатором служит не код и не наименование, а, например, ИНН, артикул или штрихкод, используется НайтиПоРеквизиту:
СсылкаКонтрагент = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7701234567");
Ограничение метода: поиск по реквизиту без индекса на большом справочнике выполняется медленно. Если такой поиск выполняется часто (например, при загрузке данных), реквизиту стоит включить индексирование в конфигураторе.
Проверка результата поиска
Любой метод поиска при неудаче возвращает пустую ссылку, а не вызывает исключение. Поэтому проверка обязательна: Если Ссылка.Пустая() Тогда .... Пропуск этой проверки — главный источник ошибок вида «Поле объекта не обнаружено» при попытке прочитать реквизит несуществующего элемента.
Если нужны данные элемента, а не только ссылка, вызовите Ссылка.ПолучитьОбъект(). Но делайте это только когда объект действительно будет изменён или нужно много реквизитов: для чтения одного-двух значений эффективнее запрос, который не выгружает объект целиком.
Как проверить результат
Метод Пустая() возвращает Ложь
Пустая() возвращает Истина — элемент не существует
Реквизиты читаются, ПометкаУдаления = Ложь
Элемент помечен на удаление или содержит устаревшие данные
Поиск в цикле занимает приемлемое время
Загрузка «зависает» — поиск идёт по неиндексированному реквизиту
Когда искать запросом вместо методов поиска
Методы НайтиПо* удобны для одиночного поиска по одному условию. Запрос выигрывает, когда условий несколько, нужен поиск по части строки, отбор по пометке удаления или одновременное получение реквизитов элемента.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Номенклатура.Ссылка КАК Ссылка
|ИЗ Справочник.Номенклатура КАК Номенклатура
|ГДЕ Номенклатура.Наименование ПОДОБНО &Шаблон
| И НЕ Номенклатура.ПометкаУдаления";
Запрос.УстановитьПараметр("Шаблон", "%" + СтрокаПоиска + "%");
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
НайденнаяСсылка = Выборка.Ссылка;
КонецЕсли;
Сравнение вариантов
Самый быстрый, код индексирован. Не подходит, если нумерация отключена или коды повторяются в сериях
Только точное совпадение строки. Риск дублей, если наименования не уникальны
Гибкий поиск по ИНН, артикулу и т.п. Требует индекса на реквизите для больших справочников
Любые условия, ПОДОБНО, несколько полей. Чуть больше кода, но оптимален для сложных отборов
Что делать, если элемент не найден
Стандартная стратегия в обменах и загрузках: не нашли — создали новый элемент. Для этого получают объект через Справочники.Номенклатура.СоздатьЭлемент(), заполняют реквизиты и записывают. Важно записывать в транзакции, если создание — часть большой загрузки, чтобы при сбое не осталось наполовину заполненных данных.
Прежде чем создавать дубль, убедитесь, что поиск выполнялся по правильному ключу. Частая ситуация: элемент существует, но код в файле отличается пробелами или лидирующими нулями — тогда поиск не находит его, и обработка плодит дубли. Нормализуйте значение (СокрЛП, приведение длины кода) перед поиском.
Ограничения и безопасные границы
На клиенте в управляемом приложении методы НайтиПо* недоступны без серверного вызова — поиск выполняется в серверной процедуре. Помещайте такой код в процедуры с директивой &НаСервере или в общие модули с признаком «Сервер».
При массовых загрузках избегайте поиска внутри цикла по одному элементу: выгоднее один запросом получить соответствие «ключ → ссылка» для всей пачки данных и затем брать ссылки из памяти. Это снижает число обращений к базе с тысяч до одного.
Изменение и создание элементов справочников в рабочей базе выполняйте с учётом прав доступа и при необходимости — в копии базы. Ошибочная массовая запись в справочник, на который ссылаются документы, способна нарушить отчётность.
Что важно запомнить
Элемент справочника выбирают методами НайтиПоКоду, НайтиПоНаименованию, НайтиПоРеквизиту или запросом; результат всегда проверяют через Пустая(). Для частого поиска по реквизиту включайте индексирование, а перед созданием нового элемента исключайте возможность дубля.
Частые вопросы
Чем ссылка отличается от объекта справочника?
Ссылка — это лёгкий идентификатор элемента, её можно хранить в реквизитах и сравнивать без чтения данных из базы. Объект — это полная копия данных элемента в памяти, которую получают методом ПолучитьОбъект() и используют для изменения и записи.
Как найти элемент по части наименования?
Методы НайтиПоНаименованию для этого не подходят — они ищут точное совпадение. Используйте запрос с условием Наименование ПОДОБНО &Шаблон, где шаблон содержит символы % по краям искомой подстроки.
Почему НайтиПоКоду не находит существующий элемент?
Чаще всего причина в несовпадении формата кода: лидирующие нули, пробелы или код задан как число вместо строки. Также проверьте, не используются ли серии кодов — тогда код уникален только внутри группы или владельца.
Можно ли выполнить поиск на клиенте в управляемой форме?
Нет, методы менеджера справочника доступны только на сервере. Вынесите поиск в серверную процедуру формы или общий серверный модуль и возвращайте на клиент только готовую ссылку.
Что вернёт поиск, если подходящих элементов несколько?
Методы НайтиПоНаименованию и НайтиПоРеквизиту вернут один из найденных элементов без гарантии, какой именно. Если уникальность не обеспечена, надёжнее использовать запрос с выборкой всех совпадений и обрабатывать дубли явно.
Как проверить, что ссылка не «битая»?
Битая ссылка возникает после физического удаления элемента. Программно её можно выявить запросом: если выборка по условию Ссылка = &Ссылка пуста, значит объекта в базе нет. Для интерактивной проверки используйте обработку поиска и удаления битых ссылок.