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

Программист 1С v7.7
← На главную

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

Способ 1. Линейный перебор справочника

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


Спр = СоздатьОбъект("Справочник.Номенклатура");
ИскомоеИмя = "Печенье овсяное с шоколадом 250г";
Найдено = 0;

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

Если Найдено = 1 Тогда
    Сообщить("Элемент найден: " + НайденныйЭлемент);
Иначе
    Сообщить("Элемент не найден");
КонецЕсли;

Анализ метода: Основной недостаток — низкая скорость на больших справочниках (десятки тысяч записей). Однако, как отмечают опытные разработчики, если поиск выполняется разово (например, при импорте данных из Excel), время ожидания может быть вполне приемлемым. В файловом варианте (DBF) 1С считывает данные достаточно быстро, если локальная сеть и дисковая подсистема не перегружены.

Способ 2. Использование встроенного объекта Запрос

Многие программисты забывают, что стандартный объект Запрос в 1С 7.7 может работать быстрее, чем обычный перебор ВыбратьЭлементы(). Это связано с тем, что механизм запросов оптимизирован для работы на уровне движка базы данных. Разберем пример реализации:


ТекстЗапроса = "
|Товар = Справочник.Номенклатура.ТекущийЭлемент;
|ПолнНаим = Справочник.Номенклатура.ПолнНаименование;
|Группировка Товар без групп;
|Условие(СокрЛП(ПолнНаим) = СокрЛП(ИскомоеИмя));
|";

Запрос = СоздатьОбъект("Запрос");
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
    Пока Запрос.Группировка(1) = 1 Цикл
        НайденныйЭлемент = Запрос.Товар;
        Сообщить("Найден через запрос: " + НайденныйЭлемент);
    КонецЦикла;
КонецЕсли;

Проанализируем ситуацию: в SQL-версии платформы такой запрос будет работать значительно быстрее перебора, так как сервер выполнит фильтрацию самостоятельно. В DBF-версии разница будет менее заметна, но объект Запрос всё равно предпочтительнее для разовых операций поиска.

Способ 3. Перевод реквизита в фиксированную длину с индексацией

Если поиск по полному наименованию требуется выполнять регулярно и мгновенно, мы можем изменить свойства реквизита в Конфигураторе. Выясним причину ограничения: индексировать можно только строки фиксированной длины не более 240 символов.

  1. Зайдите в Конфигуратор.
  2. Найдите нужный справочник и реквизит ПолнНаименование.
  3. Измените тип с «Строка неограниченной длины» на «Строка» и установите длину (например, 200 символов).
  4. Установите флажок «Сортировка».
  5. Выполните сохранение конфигурации (потребуется монопольный доступ).

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

После этой манипуляции вы сможете использовать максимально быстрый метод поиска:


Спр = СоздатьОбъект("Справочник.Номенклатура");
Если Спр.НайтиПоРеквизиту("ПолнНаименование", ИскомоеИмя, 1) = 1 Тогда
    НайденныйЭлемент = Спр.ТекущийЭлемент();
КонецЕсли;

Способ 4. Метод «Контрольной строки» или префикса (оптимальный)

Если вы не хотите менять тип основного поля (например, вам критично хранить описания по 500-1000 символов), рассмотрим создание вспомогательного реквизита. Это профессиональный подход, позволяющий сохранить гибкость и обеспечить скорость.

Создадим новый реквизит КраткоеПолное (тип Строка, длина 50-100, установлен флаг «Сортировка»). При записи элемента будем помещать в него первые 100 символов полного наименования. Поиск будет происходить в два этапа: сначала по индексу ищем частичное совпадение, а затем среди найденных проверяем точное соответствие.


Спр = СоздатьОбъект("Справочник.Номенклатура");
Префикс = Лев(СокрЛП(ИскомоеИмя), 100);

// Ищем по индексированному полю
Спр.ВыбратьЭлементыПоРеквизиту("КраткоеПолное", Префикс, 1, 1);
Пока Спр.ПолучитьЭлемент() = 1 Цикл
    // Дополнительная проверка на полное совпадение
    Если СокрЛП(Спр.ПолнНаименование) = СокрЛП(ИскомоеИмя) Тогда
        НайденныйЭлемент = Спр.ТекущийЭлемент();
        // Успех!
        Прервать;
    КонецЕсли;
КонецЦикла;

Этот метод позволяет практически мгновенно сузить область поиска с миллиона записей до 1-5 элементов, что не влияет на производительность системы.

Способ 5. Использование внешних компонент (1С++ и прямые запросы)

Для крупных баз данных на MS SQL Server лучшим решением будет использование внешней компоненты 1С++. Она позволяет выполнять прямые SQL-запросы к таблицам базы данных, минуя объектную модель 1С. Это сокращает время поиска до миллисекунд.

Рассмотрим пример кода (при условии, что компонента загружена):


ТекстЗапроса = "
|SELECT id as [Элемент $Справочник.Номенклатура]
|FROM $Справочник.Номенклатура
|WHERE CAST($Справочник.Номенклатура.ПолнНаименование AS VARCHAR(8000)) = :Имя
|";
// В SQL Server строки неограниченной длины часто хранятся как TEXT/IMAGE
// Требуется приведение типов для сравнения

Однако, как справедливо замечено в обсуждении, использование внешних компонент накладывает риски при обновлении парка компьютеров (нужно не забывать копировать dll файлы в каталог программы или базы данных).

Особенности сравнения данных

При поиске по полному наименованию, особенно если данные приходят из внешних источников (Excel, CSV), проанализируем возможные ловушки:

Резюме и рекомендации

Выясним, какой метод выбрать в вашем случае:

  1. Если база небольшая и поиск нужен редко — используйте линейный перебор (Способ 1).
  2. Если вы не боитесь менять конфигурацию и длина наименования не превышает 240 знаков — сделайте поле фиксированным и индексированным (Способ 3).
  3. Для высоконагруженных систем без использования ВК используйте метод префикса (Способ 4).
  4. Для работы с огромными справочниками в SQL-версии оптимальным будет внедрение прямых запросов через 1С++ (Способ 5).

Помните, что архитектура 1С 7.7 накладывает определенные ограничения на работу с большими объемами текстовых данных, поэтому правильный выбор метода поиска — залог стабильной и быстрой работы вашей учетной системы.

← На главную