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

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

В процессе разработки в среде 1С:Предприятие 8, особенно в таких комплексных конфигурациях, как УПП 1.3, часто возникает задача поиска элемента, который жестко привязан к другому объекту (владельцу). Классический пример — поиск конкретной кассы, принадлежащей определенной организации. В данной статье мы подробно разберем, как реализовать этот поиск максимально эффективно, какие инструменты использовать и каких ошибок стоит избегать, чтобы не получить «двойку» за качество кода.

Метод 1: Использование запроса — профессиональный подход

Большинство опытных разработчиков сходятся во мнении, что использование объекта Запрос является наиболее правильным и универсальным способом. Рассмотрим подробнее, почему это так. Запрос позволяет не только найти элемент по наименованию и владельцу, но и сразу отсечь помеченные на удаление объекты, а также ограничить выборку для повышения производительности.

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


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

Запрос.УстановитьПараметр("НаименованиеКассы", СокрЛП(НаименованиеКассы));
Запрос.УстановитьПараметр("СсылкаНаОрганизациюВладельца", СсылкаНаОрганизациюВладельца);

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

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

Разберем важные детали этого решения:

  1. Конструкция ВЫБРАТЬ ПЕРВЫЕ 1: Мы добавили это условие, чтобы оптимизировать работу SQL-сервера. Если в базе данных случайно окажется два элемента с одинаковым названием, запрос прекратит работу сразу после нахождения первого совпадения, что экономит ресурсы системы.
  2. Фильтр по пометке удаления: В реальном учете часто создаются дубли, которые впоследствии помечаются на удаление. Если не добавить условие НЕ Кассы.ПометкаУдаления, программа может выбрать недействующий объект, что приведет к ошибкам при проведении документов.
  3. Функция СокрЛП(): Перед передачей строки в параметр запроса крайне важно обрезать лишние пробелы. В справочниках 1С наименования часто содержат невидимые пробелы в конце, что может помешать точному сравнению.

Метод 2: Встроенный метод НайтиПоНаименованию

Если задача стоит максимально просто и вы уверены в чистоте данных, можно воспользоваться встроенным методом менеджера справочника. Однако здесь есть несколько «подводных камней», которые мы сейчас выясним.

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

Посмотрим на пример его реализации для подчиненного справочника:


ИскомоеНаименование = "Основная касса";
ВладелецОрганизация = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7701010101");

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

Если НайденнаяСсылка.Пустая() Тогда
    Сообщить("Касса с таким наименованием не найдена!");
Иначе
    // Проверяем, не помечен ли элемент на удаление, так как метод этого не делает сам
    Если НайденнаяСсылка.ПометкаУдаления Тогда
        Сообщить("Касса найдена, но она помечена на удаление!");
    КонецЕсли;
КонецЕсли;

Важное предостережение: Метод НайтиПоНаименованию по умолчанию имеет второй параметр Ложь. Это означает, что если вы ищете «Касса», а в базе есть «Касса №1», метод может вернуть «Касса №1». Всегда устанавливайте этот параметр в значение Истина для обеспечения точности поиска.

Специфика поиска в УПП 1.3 и учет валюты

Рассматривая справочник «Кассы» в конфигурации УПП 1.3, мы должны учитывать, что кассы разделяются не только по организациям, но и по валютам. В одной организации может быть несколько касс с одинаковым названием, но разными валютами (например, «Основная касса» в рублях и «Основная касса» в долларах).

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


Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка ИЗ Справочник.Кассы 
    |ГДЕ Наименование = &Наименование 
    |И Владелец = &Владелец 
    |И ВалютаДенежныхСредств = &Валюта";

Производительность и индексирование

Выясним причину, по которой поиск может работать медленно. Поиск по строковым полям (наименованию) в 1С эффективен только тогда, когда для этого поля в метаданных установлено свойство Индексировать. В типовых решениях для поля «Наименование» это обычно включено (индексирование с дополнительным упорядочиванием).

Если вы создаете собственный подчиненный справочник, обязательно проверьте настройки индексов. Без индекса при каждом поиске система будет выполнять полное сканирование таблицы (Full Table Scan), что при наличии тысяч записей приведет к существенным задержкам.

Массовый поиск элементов в цикле

Представим ситуацию: вы загружаете данные из Excel, где указаны 1000 организаций и 1000 названий касс. Категорически нельзя вызывать НайтиПоНаименованию или выполнять запрос внутри цикла по строкам файла. Это создаст огромную нагрузку на сервер базы данных.

Вместо этого мы рекомендуем использовать менеджер временных таблиц:

  1. Выгрузите все данные из файла во временную таблицу в запросе.
  2. Выполните левое соединение этой временной таблицы со справочником касс по полям Наименование и Владелец.
  3. Получите все ссылки одним результатом за один сеанс связи с сервером.

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

← На главную