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

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

1С: что возвращает метод НайтиПоКоду и как работать с результатом

Метод НайтиПоКоду в 1С: что возвращает при успехе и при неудаче, как проверить результат, типичные ошибки и примеры кода для справочников и планов счетов.

Метод НайтиПоКоду() — один из самых используемых способов получить элемент справочника, план видов характеристик, план счетов или план обмена по значению кода. Проблема в том, что разработчики часто неверно трактуют возвращаемое значение: метод не выдаёт ни булево, ни «Неопределено» в привычном смысле, и ошибка в проверке результата приводит к обращениям к пустым ссылкам и трудноуловимым дефектам в обменах данными.

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

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

Что именно возвращает НайтиПоКоду

Тип возвращаемого значения определяется объектом метаданных, у которого вызван метод. Для справочника это СправочникСсылка.<ИмяСправочника>, для плана видов характеристик — ПланВидовХарактеристикСсылка, для плана счетов — ПланСчетовСсылка, для плана обмена — ПланОбменаСсылка. То есть метод всегда возвращает ссылку, а не объект: реквизиты элемента через точку недоступны, пока вы не вызовете ПолучитьОбъект() или не прочитаете данные запросом.

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

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

Стандартная проверка — метод Пустая() у возвращённой ссылки:

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

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

// Элемент не найден — создаём новый или пишем в журнал

Иначе

// Элемент существует, работаем со ссылкой

КонецЕсли;

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

Чего делать нельзя: проверять Результат = Неопределено, полагаться на Если Результат Тогда (ссылка в булевом контексте не даёт надёжной семантики «найдено/не найдено») или сразу обращаться к реквизитам через ПолучитьОбъект() без проверки — при пустой ссылке получите объект с пустыми данными или ошибку.

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

Параметры метода и их влияние на результат

Полная сигнатура: НайтиПоКоду(Код, ПоискПоПолномуКоду, Родитель, Владелец). Параметры после кода опциональны, но меняют поведение.

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

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

Строковые и числовые коды: нюансы поиска

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

Для строкового кода критичны лидирующие нули и регистр. Код "000001234" и "1234" — разные значения. Если код приходит из внешней системы без нулей, приведите его к нужному формату, например: Формат(Число(КодИзФайла), "ЧЦ=9; ЧВН="). Длина кода в форматной строке должна совпадать с длиной кода в метаданных.

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

Метод находит элементы независимо от пометки удаления. Если элемент с кодом помечен на удаление, ссылка будет возвращена как заполненная — и проверка Пустая() её не отсечёт. Если бизнес-логика требует игнорировать помеченные, читайте реквизит через запрос:

Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура

|ГДЕ Код = &Код И НЕ ПометкаУдаления");

Запрос.УстановитьПараметр("Код", "000001234");

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

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

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

КонецЕсли;

Для предопределённых элементов поиск по коду работает, но предпочтительнее обращение по имени предопределённого: Справочники.СтавкиНДС.НДС20 (в обычном режиме) или НайтиПоИмениПредопределенныхДанных(). Код предопределённого элемента может меняться при перенумерации, имя — нет.

Чем заменить НайтиПоКоду

Запрос с отбором по коду

Подходит, когда нужны дополнительные условия (пометка удаления, родитель, отбор по нескольким полям) или сразу нужны реквизиты без ПолучитьОбъект()

НайтиПоНаименованию / НайтиПоРеквизиту

Когда код неизвестен или не уникален; работает медленнее без индекса по реквизиту

ПолучитьСсылку(УникальныйИдентификатор)

Когда известен GUID из внешней системы — самый надёжный способ сопоставления в обменах

Производительность и ограничения

Поиск по коду использует индекс, поэтому одиночный вызов дёшев. Проблемы начинаются в циклах: поиск тысячи элементов по одному — это тысяча обращений к СУБД. В пакетной обработке выгоднее один запрос с условием Код В (&СписокКодов) и соединением с таблицей значений.

Ещё одно ограничение: метод не работает для объектов без кода — у документов есть номер, и для них используется НайтиПоНомеру() с обязательной датой интервала. Для регистров сведений поиска по коду не существует вовсе — там отбор идёт по измерениям.

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

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

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

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

Тип возвращённого значения
Норма

СправочникСсылка нужного вида

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

Неопределено в логике проверки — значит, проверка написана неверно

Поведение при отсутствии элемента
Норма

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

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

Код падает с ошибкой или молча продолжает работу

Поиск существующего элемента
Норма

Ссылка найдена, реквизиты читаются

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

Пустая ссылка при заведомо существующем коде — проверьте формат и нули

Помеченный на удаление элемент
Норма

Поведение соответствует логике (найден или отсечён запросом)

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

Помеченный элемент молча участвует в обработке

FAQ

НайтиПоКоду возвращает Неопределено, если ничего не найдено?

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

Можно ли сразу получить реквизиты найденного элемента?

Через сам метод — нет, он возвращает только ссылку. Реквизиты доступны после НайденнаяСсылка.ПолучитьОбъект() либо через запрос с отбором по коду, что предпочтительнее при чтении без записи, так как не создаёт объект в памяти.

Почему элемент с таким кодом точно есть, но метод его не находит?

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

Найдёт ли метод помеченный на удаление элемент?

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

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

Первый найденный по индексу элемент; какой именно — не гарантируется и может меняться. При неуникальных кодах передавайте родителя или владельца, либо используйте запрос с полным набором условий.

Что быстрее — НайтиПоКоду или запрос?

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

Итог

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

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