Почему метод FindText в табличном документе через OLE возвращает Неопределено?

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

При интеграции баз данных через механизм COM/OLE нередко требуется программно обратиться к макетам удаленной базы, например, чтобы прочитать предопределенные классификаторы и синхронизировать элементы справочников. Однако при вызове метода FindText (или его русскоязычного аналога НайтиТекст) для табличного документа разработчики часто сталкиваются с ситуацией, когда метод возвращает Неопределено, хотя визуально искомая строка присутствует в документе.

Разберем детально, почему возникает эта ошибка, как влияют параметры поиска на результат, какие подводные камни несет быстрое исправление и как правильно организовать работу с макетами через COM-соединение.

Анализ проблемы и структуры вызова FindText

Рассмотрим исходный фрагмент кода, в котором выполняется поиск страны происхождения в макете классификатора удаленной базы:


ТабличныйДокумент = УдСпрКлассификаторСтранМира.ПолучитьМакет("КлассификаторСтранМира");

ОбластьНаименованиеКраткое = ТабличныйДокумент.Areas.НаименованиеКраткое;

// Попытка найти строку "ПОЛЬША" в заданной области
ТекущаяОбласть = ТабличныйДокумент.FindText(ВРег(Стр), , ОбластьНаименованиеКраткое, Ложь, Истина, Истина, Истина);

Несмотря на то что в ячейке визуально записано «ПОЛЬША», переменная ТекущаяОбласть принимает значение Неопределено.

Вспомним состав и порядок параметров метода НайтиТекст (FindText):

  1. СтрокаПоиска — искомый текст.
  2. СтартоваяЯчейка — ячейка, с которой начинается поиск (необязательный, по умолчанию начало документа).
  3. Область — область табличного документа, в которой производится поиск.
  4. НаправлениеПоиска — перечисление или булево значение направления.
  5. ЯчейкаЦеликом — признак точного соответствия содержимого ячейки искомой строке (по умолчанию Истина).
  6. ПоСловам — поиск только целых слов.
  7. ИгнорироватьРегистр — регистронезависимый поиск (по умолчанию Ложь).

Причина 1: Невидимые символы и параметр «Ячейка целиком»

Проанализируем пятый параметр метода — ЯчейкаЦеликом. Когда мы передаем в него значение Истина, платформа 1С выполняет строгое посимвольное сопоставление всего содержимого ячейки с переданной строкой.

В типовых макетах классификаторов ячейки почти никогда не бывают «чистыми»: в них часто содержатся хвостовые пробелы, начальные отступы, неразрывные пробелы (Символы.НПП) или символы перевода каретки. Если в ячейке находится строка "ПОЛЬША " (с пробелом на конце), а мы ищем "ПОЛЬША", метод вернет Неопределено.

Автор проблемы применил следующее исправление, отключив строгое соответствие ячейке:


// Пятый параметр переключен с Истина на Ложь:
ТекущаяОбласть = ТабличныйДокумент.FindText(ВРег(Стр), , ОбластьНаименованиеКраткое, Ложь, ЛОЖЬ, Истина, Истина);

Поиск сразу начинает находить нужные строки, так как теперь выполняется поиск вхождения подстроки.

Опасности отключения флага «Ячейка целиком»

Обратите внимание: решение с установкой ЯчейкаЦеликом = Ложь таит в себе критическую опасность при работе с географическими названиями и классификаторами. Метод FindText возвращает первое попавшееся совпадение вхождения подстроки. Посмотрим на реальные риски:

  1. При поиске страны «НИГЕР» метод найдет ячейку «НИГЕРИЯ», если она встретится раньше.
  2. При поиске «СУДАН» будет найдена строка «ЮЖНЫЙ СУДАН».
  3. При поиске «ГВИНЕЯ» код может сопоставить данные с «ПАПУА - НОВАЯ ГВИНЕЯ» или «ГВИНЕЯ-БИСАУ».
  4. Запрос по наименованию «КОНГО» вернет «ДЕМОКРАТИЧЕСКАЯ РЕСПУБЛИКА КОНГО».

В результате в базу будут записаны чужие числовые коды и буквенные идентификаторы Альфа-2, что нарушит целостность учета.

Избыточность ручного приведения к регистру

В исходном коде используется конструкция ВРег(Стр) при передаче седьмого параметра ИгнорироватьРегистр = Истина. Обратим внимание: если седьмой параметр включен, платформа выполняет регистронезависимое сопоставление автоматически. Преобразование строки в верхний регистр здесь избыточно и не решает проблему пробельных символов.

Ограничения производительности через OLE/COM

Вызов методов табличного документа через межпроцессный интерфейс OLE/COM работает медленно. В исходном алгоритме на каждый создаваемый элемент справочника выполняются десятки удаленных вызовов:


КодЧисловой         = ТабличныйДокумент.Area(ТекущаяОбласть.Верх, ОбластьКодЧисловой.Лево, ТекущаяОбласть.Низ, ОбластьКодЧисловой.Право).Текст;
НаименованиеКраткое = СокрЛП(ТабличныйДокумент.Area(ТекущаяОбласть.Верх, ОбластьНаименованиеКраткое.Лево, ТекущаяОбласть.Низ, ОбластьНаименованиеКраткое.Право).Текст);
НаименованиеПолное  = СокрЛП(ТабличныйДокумент.Area(ТекущаяОбласть.Верх, ОбластьНаименованиеПолное.Лево, ТекущаяОбласть.Низ, ОбластьНаименованиеПолное.Право).Текст);
КодАльфа2           = ТабличныйДокумент.Area(ТекущаяОбласть.Верх, ОбластьКодАльфа2.Лево, ТекущаяОбласть.Низ, ОбластьКодАльфа2.Право).Текст;

Каждое обращение к свойствам Верх, Низ, Лево, Право, Area и Текст генерирует отдельный сетевой/системный RPC-запрос. При обработке сотен строк загрузка будет выполняться крайне медленно.

Надежные и правильные варианты решения

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

Способ 1. Вынос логики на сторону удаленной базы (Рекомендуемый)

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

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

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


// Очистка текста от пробелов и неразрывного пробела (код 160)
ОчищенныйТекст = СокрЛП(СтрЗаменить(ИсходныйТекст, Символы.НПП, ""));

Затем организуем поиск методом НайтиСтроки или точным сравнением в цикле. Это гарантирует 100% точность идентификации стран и ускорит работу процедуры в десятки раз.

Способ 3. Использование штатных функций БСП

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

← На главную