Почему метод НайтиПоРеквизиту не находит элемент в справочнике 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке алгоритмов обмена данными (например, в «Конвертации данных») или прикладной логики разработчики часто используют метод менеджера объекта НайтиПоРеквизиту. Однако бывают ситуации, когда элемент точно присутствует в базе, значение визуально совпадает, но метод упорно возвращает пустую ссылку. Разберем по шагам, почему это происходит и как локализовать проблему.

Причина 1. Путаница между реквизитом объекта и дополнительным реквизитом

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

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

Если требуется найти элемент по дополнительному реквизиту, используем запрос к табличной части:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |	Контрагенты.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Контрагенты.ДополнительныеРеквизиты КАК ДопРеквизиты
    |	ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
    |		ПО ДопРеквизиты.Ссылка = Контрагенты.Ссылка
    |ГДЕ
    |	ДопРеквизиты.Свойство = &Свойство
    |	И ДопРеквизиты.Значение = &Значение";

Запрос.УстановитьПараметр("Свойство", ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Код7"));
Запрос.УстановитьПараметр("Значение", ИскомоеЗначение);

Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
    НайденнаяСсылка = Выборка.Ссылка;
КонецЕсли;

Причина 2. Ограничения платформы и индексирование реквизита

Разберем особенности работы метода НайтиПоРеквизиту на уровне платформы «1С:Предприятие»:

  1. Обязательная индексация: Поиск возможен только по тем реквизитам, для которых в конфигураторе установлено свойство «Индексировать» (или «Индексировать с доп. упорядочиванием»). Если индексация отключена, вызов метода приведет к ошибке выполнения.
  2. Ограничение прав (RLS): Метод выполняется с учетом ограничений доступа текущего сеанса. Если пользователь не имеет прав на чтение конкретного элемента или реквизита, метод вернет пустую ссылку без генерации исключения. В сервисных процедурах и обменах следует использовать УстановитьПривилегированныйРежим(Истина).
  3. Наличие дублей: Метод возвращает только одно первое попавшееся значение. Управлять выборкой при наличии неуникальных значений нельзя.
  4. Параметры иерархии и владельца: Если справочник иерархический или подчиненный, проверьте параметры Родитель и Владелец. Передача непустого значения ограничивает поиск только указанной веткой.

Причина 3. Несовпадение типов и скрытые символы

Выясним технические причины, по которым точное строковое совпадение дает отрицательный результат:

  1. Различие типов данных: Искомый реквизит может иметь ссылочный тип, а в метод передается строка (или наоборот).
  2. Неразрывные пробелы и спецсимволы: При копировании данных из документов или интерфейса в строку могут попадать неразрывные пробелы (Символы.НПП), переносы строк (Символы.ВК, Символы.ПС) или табуляция. Визуально строки неотличимы, но для платформы они различны.
  3. Схожие символы латиницы и кириллицы: Буквы «С», «О», «А», «Е», «Р», набранные в разной раскладке клавиатуры, визуально идентичны, но имеют разные коды символов.
  4. Фиксированная длина строки: Если реквизит имеет фиксированную длину (например, Строка(10)), в базе строка дополняется пробелами справа. При поиске короткой строки без дополняющих пробелов совпадение не будет найдено.

Чек-лист для диагностики проблемы

Если поиск не дает результатов, выполним проверку по следующим шагам:

  1. Проверяем через консоль запросов: Напишем простой запрос к таблице справочника с отбором по реквизиту. Если запрос не находит запись — дело в несовпадении данных.
  2. Проверяем тип и длину значения: Сравним тип метаданных реквизита с типом переменной через ТипЗнч().
  3. Очищаем строку от непечатаемых символов: Применим СокрЛП() и функцию замены неразрывного пробела СтрЗаменить(Значение, Символы.НПП, " ").
  4. Убеждаемся в расположении реквизита: Проверим в конфигураторе, действительно ли поле на форме привязано к реквизиту объекта, а не формируется динамически через дополнительные реквизиты.
← На главную