Разработка и Конфигурация · 12 мин
НайтиПоРеквизиту в 1С: как работает поиск элемента по реквизиту
Как работает метод НайтиПоРеквизиту в 1С: синтаксис, параметры, примеры кода, типичные ошибки и отличия от НайтиПоКоду и НайтиПоНаименованию.
Метод НайтиПоРеквизиту — один из базовых инструментов разработчика 1С для поиска элемента справочника, плана видов характеристик, плана счетов или плана видов расчёта по значению произвольного реквизита. В отличие от НайтиПоКоду или НайтиПоНаименованию, которые работают со стандартными полями, этот метод позволяет искать по любому реквизиту объекта, включая добавленные в конфигурацию самостоятельно.
Типовой сценарий использования — интеграция и обмен данными: внешняя система передаёт, например, ИНН контрагента или артикул номенклатуры, и программа должна найти соответствующий элемент в базе. Если элемент найден — он обновляется, если нет — создаётся новый. Именно поэтому понимание тонкостей работы метода напрямую влияет на корректность обменов и отсутствие дублей в справочниках.
Метод возвращает ссылку на найденный объект. Если подходящих элементов несколько, будет возвращён первый из них (какой именно — не гарантируется и зависит от физического порядка данных). Если ничего не найдено, метод возвращает пустую ссылку соответствующего типа. Это важно учитывать при построении логики: отсутствие проверки результата приводит к ошибкам обращения к пустой ссылке.
Синтаксис и параметры метода
Общий вид вызова метода выглядит так:
НайденнаяСсылка = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", "АРТ-12345");
НайденнаяСсылка = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7707083893");
Если НайденнаяСсылка.Пустая() Тогда
Сообщить("Контрагент не найден");
Иначе
Сообщить("Найден: " + НайденнаяСсылка);
КонецЕсли;Метод принимает до четырёх параметров:
- Имя реквизита (обязательный) — строка с именем реквизита, как оно задано в конфигураторе. Регистр букв не важен, но ошибка в имени вызовет исключение во время выполнения.
- Значение (обязательный) — искомое значение. Тип значения должен соответствовать типу реквизита: строку нельзя искать по числовому реквизиту без приведения типов.
- Родитель (необязательный) — ссылка на группу, внутри которой выполняется поиск. Актуально для иерархических справочников.
- Владелец (необязательный) — ссылка на владельца для подчинённых справочников (например, поиск договора в рамках конкретного контрагента).
Если параметры Родитель или Владелец не указаны, поиск выполняется по всему справочнику. Указание этих параметров сужает выборку и ускоряет поиск, но требует точного понимания структуры данных: элемент, лежащий в другой группе, найден не будет.
Как работает поиск внутри платформы
При вызове НайтиПоРеквизиту платформа формирует запрос к таблице справочника с условием равенства реквизита переданному значению. Если по реквизиту построен индекс (он создаётся автоматически для реквизитов с признаком «Индексировать» в конфигураторе), поиск выполняется быстро даже на больших таблицах. Если индекса нет, СУБД выполняет полное сканирование таблицы, что на справочнике в сотни тысяч элементов заметно нагружает сервер.
Для строковых реквизитов поиск выполняется на точное совпадение с учётом заданной в конфигураторе длины строки. Сравнение строк в 1С по умолчанию нечувствительно к регистру, но чувствительно к пробелам: значение «АРТ-1 » с пробелом на конце не будет найдено по строке «АРТ-1». Это одна из самых частых причин «необъяснимых» промахов при обменах.
Для реквизитов составного типа (например, реквизит может хранить ссылку на разные справочники) поиск работает корректно, но переданное значение должно совпадать и по типу, и по значению. Передача строки вместо ссылки не приведёт к автоматическому поиску по наименованию — метод просто ничего не найдёт.
Практические примеры использования
Поиск контрагента по ИНН
Классическая задача при загрузке документов из внешних систем. ИНН хранится как строка, поэтому перед поиском стоит очистить значение от пробелов и нецифровых символов, если источник данных этим грешит.
ИНН = СокрЛП(ДанныеФайла.ИНН);
КонтрагентСсылка = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", ИНН);
Если КонтрагентСсылка.Пустая() Тогда
НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйКонтрагент.Наименование = ДанныеФайла.Название;
НовыйКонтрагент.ИНН = ИНН;
НовыйКонтрагент.Записать();
КонтрагентСсылка = НовыйКонтрагент.Ссылка;
КонецЕсли;
Поиск в подчинённом справочнике
Для справочников с владельцем (договоры контрагентов, единицы измерения номенклатуры) параметр Владелец ограничивает область поиска и заодно страхует от нахождения «чужого» элемента с тем же значением реквизита.
ДоговорСсылка = Справочники.ДоговорыКонтрагентов.НайтиПоРеквизиту(
"Номер", "145/2026", , КонтрагентСсылка);
Обратите внимание на пропущенный третий параметр (Родитель) — запятые сохраняют позиционность аргументов.
- 1Сформируйте значение поиска: СокрЛП, приведение типа, очистка от лишних символов
- 2Вызовите НайтиПоРеквизиту с нужными параметрами Родитель и Владелец
- 3Проверьте результат методом Пустая() до любого обращения к реквизитам
- 4Если ссылка пустая — создайте элемент или зафиксируйте ошибку в журнале
- 5Если ссылка найдена — получите объект через ПолучитьОбъект() только при необходимости изменения данных
Отличия от НайтиПоКоду и НайтиПоНаименованию
Все три метода возвращают ссылку, но различаются областью поиска и поведением. НайтиПоКоду работает с кодом элемента и требует учёта типа кода (число или строка) и его длины — строковый код «0000123» не равен «123». НайтиПоНаименованию ищет по наименованию и по умолчанию выполняет поиск по точному совпадению, хотя поддерживает режим поиска по маске через третий параметр.
Сравнение методов поиска
Быстрый поиск по индексированному коду. Ограничение: чувствителен к типу и формату кода, не подходит для произвольных полей.
Поиск по наименованию, поддерживает поиск по маске. Ограничение: наименования часто не уникальны, результат непредсказуем при дублях.
Поиск по любому реквизиту, включая пользовательские. Ограничение: без индекса медленный на больших таблицах, не ищет по табличным частям.
Гибкий поиск с любыми условиями, соединениями и сортировкой. Ограничение: больше кода, требует навыков работы с языком запросов.
Выбор метода зависит от задачи. Если нужен поиск по уникальному бизнес-идентификатору (ИНН, артикул, штрихкод), НайтиПоРеквизиту — правильный выбор. Если условий несколько или нужно искать по части строки с учётом сложной логики, лучше сразу использовать запрос.
Производительность и индексация
Главный фактор скорости НайтиПоРеквизиту — наличие индекса по реквизиту. Откройте конфигуратор, найдите реквизит справочника и проверьте свойство «Индексировать» (или «Индексировать с доп. упорядочиванием»). Для реквизитов, по которым регулярно выполняется поиск в обменах, индексацию следует включать обязательно.
Вторая типичная проблема — вызов метода в цикле. Если обрабатывается тысяча строк файла и для каждой выполняется НайтиПоРеквизиту, база получит тысячу отдельных обращений. На больших объёмах эффективнее собрать все искомые значения в массив и выполнить один запрос с условием «В», а затем сопоставить результаты через соответствие.
В клиент-серверном режиме каждый вызов НайтиПоРеквизиту — это отдельное обращение к СУБД. При загрузке больших файлов выносите поиск в один запрос с параметром-таблицей значений: время обмена может сократиться в десятки раз без изменения логики.
Типичные ошибки и их последствия
Самая распространённая ошибка — работа с результатом без проверки на пустую ссылку. Вызов НайденнаяСсылка.Наименование при пустой ссылке завершится ошибкой «Поле объекта не обнаружено» или аналогичной, а обмен прервётся на середине.
Вторая группа ошибок связана с типами данных. Поиск числового кода строкой, поиск ссылки строкой с её представлением, передача даты строкой — во всех этих случаях метод либо вернёт пустую ссылку, либо вызовет исключение. Перед вызовом приводите значение к типу реквизита.
Когда НайтиПоРеквизиту не подходит
Есть ситуации, где метод бессилен или неоптимален. Поиск по реквизиту табличной части, поиск по нескольким условиям одновременно, поиск по части строки, поиск с учётом регистра или без него в нестандартном режиме — всё это решается только запросом. Также метод не работает с документами: у документов нет НайтиПоРеквизиту, поиск выполняется запросом или через НайтиПоНомеру.
Как выбрать инструмент поиска
Проверка результата и отладка
После вызова метода полезно убедиться, что найден именно тот элемент, который ожидался. Минимальный набор проверок: ссылка не пустая, элемент не помечен на удаление, найденный элемент принадлежит нужному владельцу или группе. Помеченные на удаление элементы НайтиПоРеквизиту находит наравне с обычными — это частая причина появления «мусорных» ссылок в документах.
Если Не НайденнаяСсылка.Пустая()
И Не НайденнаяСсылка.ПометкаУдаления Тогда
// Элемент пригоден к использованию
КонецЕсли;
Как проверить результат поиска
Пустая() возвращает Ложь
Пустая() возвращает Истина — элемент отсутствует или ошибка в значении поиска
ПометкаУдаления = Ложь
Элемент помечен на удаление — нужно исключить или восстановить
Ссылка.Владелец совпадает с ожидаемым
Найден элемент другого владельца — добавьте параметр Владелец в вызов
Поиск выполняется мгновенно
Заметная пауза — проверьте индексацию реквизита в конфигураторе
FAQ
Что возвращает НайтиПоРеквизиту, если найдено несколько элементов?
Метод возвращает ссылку на один из найденных элементов, при этом какой именно — не определено и может меняться после реструктуризации базы. Если реквизит должен быть уникальным, контролируйте уникальность на уровне конфигурации или проверяйте дубли запросом.
Почему метод не находит элемент, который точно есть в базе?
Чаще всего причины три: лишние пробелы в искомом значении (помогает СокрЛП), несовпадение типов значения и реквизита, либо заданы параметры Родитель или Владелец, исключающие нужный элемент из области поиска. Также проверьте, что в имени реквизита нет опечатки.
Можно ли искать по реквизиту частично, по подстроке?
Нет, НайтиПоРеквизиту выполняет только точное сравнение. Для поиска по части строки используйте запрос с оператором ПОДОБНО и символами подстановки.
Работает ли метод с помеченными на удаление элементами?
Да, помеченные на удаление элементы участвуют в поиске на общих основаниях. Если это нежелательно, добавьте в логику проверку свойства ПометкаУдаления у найденной ссылки.
Есть ли НайтиПоРеквизиту у документов?
Нет, у менеджеров документов такой метод отсутствует. Для поиска документа по реквизиту используйте запрос к таблице документа с нужным условием.
Как ускорить поиск, если справочник очень большой?
Включите индексацию реквизита в конфигураторе, сужайте область поиска параметрами Родитель и Владелец, а при массовой обработке заменяйте множественные вызовы метода одним запросом с условием В по массиву значений.
Что важно запомнить
НайтиПоРеквизиту ищет элемент справочника или плана по точному значению реквизита и возвращает ссылку либо пустую ссылку. Всегда проверяйте результат методом Пустая(), приводите тип значения к типу реквизита, очищайте строки от пробелов и включайте индексацию для реквизитов, по которым идёт регулярный поиск. Для сложных условий, табличных частей и документов используйте запрос.