Как найти элемент справочника по наименованию на сервере в 1С?

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

При переходе на клиент-серверную архитектуру и управляемые формы разработчики нередко сталкиваются с ошибкой: «Процедура или функция с указанным именем не определена» при попытке найти элемент справочника по строке наименования. Давайте проанализируем причины этой ошибки и подробно разберем, как правильно выполнять поиск на сервере.

Выясним причину ошибки

Разберем, почему возникает подобное исключение при выполнении кода:

  1. Вызов функции без указания менеджера объекта. В платформе 1С:Предприятие метод НайтиПоНаименованию не является глобальной функцией. Он принадлежит исключительно объекту СправочникМенеджер.<ИмяСправочника>. Попытка вызвать его напрямую приведет к ошибке компиляции.
  2. Попытка вызова метода не от того объекта. Данного метода нет у ссылки (СправочникСсылка.<Имя>) или объекта (СправочникОбъект.<Имя>). Попытка вызвать его через конструкцию вида Ссылка.НайтиПоНаименованию(...) также завершится ошибкой.
  3. Выполнение контекста на клиенте. Менеджеры справочников и глобальная коллекция Справочники недоступны на тонком и веб-клиенте. Если код выполняется в клиентской процедуре без директивы передачи управления на сервер (&НаСервере или &НаСервереБезКонтекста), обратиться к менеджеру не удастся.
  4. Заблуждение относительно доступности в Синтакс-помощнике. Метод доступен в контекстах: Сервер, Толстый клиент, Внешнее соединение, Мобильное приложение (сервер). Таким образом, на сервере метод полностью функционален, если соблюден правильный синтаксис вызова.

Правильный синтаксис использования метода НайтиПоНаименованию

Рассмотрим, как должен выглядеть корректный вызов метода на сервере. Обращение обязательно выполняется через коллекцию Справочники к конкретному менеджеру:


&НаСервереБезКонтекста
Функция НайтиТоварПоНаименованию(СтрокаПоиска)
    
    // Ищем точное совпадение наименования
    НайденнаяСсылка = Справочники.Номенклатура.НайтиПоНаименованию(СтрокаПоиска, Истина);
    
    Если Не НайденнаяСсылка.Пустая() Тогда
        Возврат НайденнаяСсылка;
    Иначе
        Возврат Неопределено;
    КонецЕсли;
    
КонецФункции

Разберем параметры этого метода подробнее:

  1. Наименование (тип Строка) — строка с наименованием искомого элемента.
  2. ТочноеСоответствие (тип Булево, по умолчанию Ложь) — критически важный параметр. Если оставить значение по умолчанию (Ложь), поиск будет выполняться по началу строки. Например, при поиске строки «Болт» метод может вернуть «Болт М8х30». Для поиска строгого совпадения обязательно передавайте Истина.
  3. Родитель (тип СправочникСсылка) — группа справочника, внутри которой необходимо производить поиск (если справочник иерархический).
  4. Владелец (тип СправочникСсылка) — элемент-владелец (используется для подчиненных справочников).

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

Ограничения метода НайтиПоНаименованию

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

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

Альтернатива: поиск с помощью объекта Запрос

Посмотрим на более надежный и профессиональный способ поиска элементов на сервере — использование объекта Запрос. Этот подход позволяет отсечь помеченные на удаление элементы, учесть порядок записей и сразу прочитать сопутствующие реквизиты без повторного обращения к базе.


&НаСервереБезКонтекста
Функция НайтиНоменклатуруЗапросом(НаименованиеДляПоиска)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |	Номенклатура.Ссылка КАК Ссылка
        |ИЗ
        |	Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |	Номенклатура.Наименование = &Наименование
        |	И НЕ Номенклатура.ПометкаУдаления
        |УПОРЯДОЧИТЬ ПО
        |	Номенклатура.Код ВОЗР";
        
    Запрос.УстановитьПараметр("Наименование", НаименованиеДляПоиска);
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    Если Выборка.Следующий() Тогда
        Возврат Выборка.Ссылка;
    КонецЕсли;
    
    Возврат Справочники.Номенклатура.ПустаяСсылка();
    
КонецФункции

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

← На главную