Как найти строку во всех данных базы 1С: способы и реализация

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

В практике разработчика 1С часто возникает задача найти конкретный фрагмент текста, не зная точно, в каком объекте он находится. Это может быть поиск забытого комментария, специфического артикула или системного идентификатора, который «проскочил» в пользовательские данные. Стандартные средства не всегда справляются с этой задачей быстро и в полном объеме. В этой статье мы разберем по шагам, как реализовать поиск по всей базе данных, проанализируем возможные инструменты и напишем оптимальный алгоритм.

Способ 1. Использование встроенного полнотекстового поиска (ПТП)

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

Разберемся, почему это происходит:

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

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

Способ 2. Программный перебор всех метаданных (алгоритм «Цикл в цикле»)

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

Рассмотрим структуру метаданных, которую необходимо обработать:

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

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


Процедура ПоискПоСправочнику(МетаданныеОбъекта, ИскомаяСтрока)
    ТекстЗапроса = "";
    СписокСтроковыхПолей = Новый СписокЗначений;
    
    // Проверяем стандартные реквизиты
    Если МетаданныеОбъекта.ДлинаНаименования > 0 Тогда
        СписокСтроковыхПолей.Добавить("Наименование");
    КонецЕсли;
    
    // Проверяем пользовательские реквизиты
    Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл
        Если Реквизит.Тип.СодержитТип(Тип("Строка")) Тогда
            СписокСтроковыхПолей.Добавить(Реквизит.Имя);
        КонецЕсли;
    КонецДля;
    
    Если СписокСтроковыхПолей.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    // Формируем текст запроса с условием ПОДОБНО
    ТекстЗапроса = "ВЫБРАТЬ Ссылка ИЗ " + МетаданныеОбъекта.ПолноеИмя() + " ГДЕ ";
    Для Каждого Поле Из СписокСтроковыхПолей Цикл
        ТекстЗапроса = ТекстЗапроса + Поле.Значение + " ПОДОБНО &Строка ИЛИ ";
    КонецДля;
    
    // Убираем последнее "ИЛИ "
    ТекстЗапроса = Лев(ТекстЗапроса, СтрДлина(ТекстЗапроса) - 4);
    
    Запрос = Новый Запрос(ТекстЗапроса);
    Запрос.УстановитьПараметр("Строка", "%" + ИскомаяСтрока + "%");
    
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        Сообщить("Найдено в " + МетаданныеОбъекта.Имя + ": " + Выборка.Ссылка);
    КонецЦикла;
КонецПроцедуры

Способ 3. Прямые SQL-запросы (для экспертов)

В случае с огромными клиент-серверными базами (сотни гигабайт) 1С-запросы могут выполняться часами. Проанализируем ситуацию с точки зрения SQL-сервера. Прямой поиск по всем таблицам базы данных через SQL Management Studio может оказаться в десятки раз быстрее, так как мы минуем уровень объектной модели 1С.

Для этого можно использовать системные представления SQL, такие как INFORMATION_SCHEMA.COLUMNS, чтобы найти все колонки типов NVARCHAR и NCHAR, а затем запустить по ним динамический SELECT. Однако стоит помнить, что такой метод требует понимания структуры таблиц 1С (например, что справочник Справочник.Номенклатура превращается в таблицу _Reference123).

Способ 4. Современные возможности платформы и БСП

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

Также, если в вашей конфигурации используется Библиотека стандартных подсистем (БСП), обратите внимание на подсистему «Полнотекстовый поиск». Она уже содержит готовые интерфейсные формы и методы для программного управления поиском, что может значительно упростить вам работу.

Важные нюансы и оптимизация производительности

При реализации «поиска везде» крайне важно не «повесить» рабочую базу. Рассмотрим подробнее меры предосторожности:

  1. Фоновые задания: Никогда не запускайте тотальный поиск в основном потоке клиентского приложения. Используйте ФоновыеЗадания.Выполнить().
  2. Многопоточность: Разделите список метаданных на порции. Например, справочники ищет один поток, документы — второй, регистры — третий. Это позволит сократить время ожидания.
  3. Ограничение выборки: Устанавливайте разумный лимит на количество найденных записей (например, первые 1000 совпадений), иначе выгрузка результата в таблицу значений сама по себе может переполнить память.
  4. Типы данных: Помните, что поиск ПОДОБНО по полям неограниченной длины в SQL работает медленнее, чем по строкам фиксированной длины.

Подведем итог: Идеального «коробочного» решения для поиска абсолютно везде не существует из-за особенностей индексации. Однако, сочетая динамические запросы к метаданным и правильное использование фоновых заданий, мы можем создать мощный инструмент, который найдет любую иголку в стоге данных вашей 1С.

← На главную