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

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

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

Причина 1: Не указана дата документа при периодической нумерации

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

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

Посмотрим на пример правильного вызова метода:


// Передаем дату для определения периода нумерации
ДатаПоиска = ТекущаяДата(); // или точная дата искомого документа
ИскомыйДокумент = Документы.ЗаказКлиента.НайтиПоНомеру("УИ-0013315", ДатаПоиска);

Если ЗначениеЗаполнено(ИскомыйДокумент) Тогда
    // Объект найден
КонецЕсли;

Причина 2: Несовпадение регистра букв и формат номера

Выясним причину, связанную с написанием номера. Номер документа в 1С является строковым реквизитом. При поиске строковых значений строгой длины имеют значение следующие нюансы:

  1. Регистр символов: строчные и заглавные буквы (например, "уи-0013315" и "УИ-0013315") в зависимости от настроек СУБД и параметров сопоставления строк могут восприниматься как различные значения. В стандартных механизмах платформы префиксы номеров формируются в верхнем регистре.
  2. Ведущие нули и общая длина: если длина номера в метаданных составляет, например, 11 символов, строка должна в точности соответствовать этой длине. Пропуск даже одного ведущего нуля приведет к тому, что метод не найдет объект.
  3. Скрытые символы и пробелы: при копировании номеров из внешних систем в строку могут попадать неразрывные пробелы или дефисы другого типа (например, длинное тире вместо стандартного минуса). Рекомендуется предварительно очищать строку через СокрЛП и проверять специальные символы.

Причина 3: Ограничения метода НайтиПоРеквизиту

Рассмотрим, почему не следует применять метод НайтиПоРеквизиту для поиска по стандартному реквизиту Номер:

  1. Для стандартных реквизитов (Номер, Код, Наименование) платформой предусмотрены специализированные методы НайтиПоНомеру, НайтиПоКоду и НайтиПоНаименованию. Использование универсального поиска по реквизиту для номера не является штатным подходом.
  2. Метод НайтиПоРеквизиту работает только по тем реквизитам, для которых в конфигураторе установлено свойство Индексировать или Индексировать с дополнительным упорядочиванием.
  3. Метод НайтиПоРеквизиту всегда возвращает только один объект и не учитывает периодичность номеров документов, из-за чего при наличии одинаковых номеров в разных годах результат может быть непредсказуемым.

Причина 4: Ограничения прав доступа на уровне записей (RLS)

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

Оптимальное решение: Поиск документа через объект Запрос

Рассмотрим наиболее надежный и гибкий способ поиска объектов в 1С — использование языка запросов. Запрос позволяет явно управлять периодом, фильтрацией и правами доступа:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
    |	ЗаказКлиента.Ссылка КАК Ссылка
    |ИЗ
    |	Документ.ЗаказКлиента КАК ЗаказКлиента
    |ГДЕ
    |	ЗаказКлиента.Номер = &Номер
    |	И ЗаказКлиента.Дата МЕЖДУ &НачалоПериода И &КонецПериода
    |	И НЕ ЗаказКлиента.ПометкаУдаления";

Запрос.УстановитьПараметр("Номер", СокрЛП("УИ-0013315"));
Запрос.УстановитьПараметр("НачалоПериода", НачалоГода(ТекущаяДата()));
Запрос.УстановитьПараметр("КонецПериода", КонецГода(ТекущаяДата()));

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

Если Выборка.Следующий() Тогда
    ИскомыйДокумент = Выборка.Ссылка;
Иначе
    ИскомыйДокумент = Документы.ЗаказКлиента.ПустаяСсылка();
КонецЕсли;

Преимущества поиска через запрос:

  1. Ключевое слово РАЗРЕШЕННЫЕ исключает ошибки нехватки прав доступа при включенном RLS.
  2. Конструкция МЕЖДУ позволяет задать любой произвольный интервал дат независимо от периодичности нумератора.
  3. Возможность добавить дополнительные условия отбора (например, исключить помеченные на удаление документы).
← На главную