При интеграции баз данных через механизм COM/OLE нередко требуется программно обратиться к макетам удаленной базы, например, чтобы прочитать предопределенные классификаторы и синхронизировать элементы справочников. Однако при вызове метода FindText (или его русскоязычного аналога НайтиТекст) для табличного документа разработчики часто сталкиваются с ситуацией, когда метод возвращает Неопределено, хотя визуально искомая строка присутствует в документе.
Разберем детально, почему возникает эта ошибка, как влияют параметры поиска на результат, какие подводные камни несет быстрое исправление и как правильно организовать работу с макетами через COM-соединение.
Рассмотрим исходный фрагмент кода, в котором выполняется поиск страны происхождения в макете классификатора удаленной базы:
ТабличныйДокумент = УдСпрКлассификаторСтранМира.ПолучитьМакет("КлассификаторСтранМира");
ОбластьНаименованиеКраткое = ТабличныйДокумент.Areas.НаименованиеКраткое;
// Попытка найти строку "ПОЛЬША" в заданной области
ТекущаяОбласть = ТабличныйДокумент.FindText(ВРег(Стр), , ОбластьНаименованиеКраткое, Ложь, Истина, Истина, Истина);
Несмотря на то что в ячейке визуально записано «ПОЛЬША», переменная ТекущаяОбласть принимает значение Неопределено.
Вспомним состав и порядок параметров метода НайтиТекст (FindText):
Истина).Ложь).Проанализируем пятый параметр метода — ЯчейкаЦеликом. Когда мы передаем в него значение Истина, платформа 1С выполняет строгое посимвольное сопоставление всего содержимого ячейки с переданной строкой.
В типовых макетах классификаторов ячейки почти никогда не бывают «чистыми»: в них часто содержатся хвостовые пробелы, начальные отступы, неразрывные пробелы (Символы.НПП) или символы перевода каретки. Если в ячейке находится строка "ПОЛЬША " (с пробелом на конце), а мы ищем "ПОЛЬША", метод вернет Неопределено.
Автор проблемы применил следующее исправление, отключив строгое соответствие ячейке:
// Пятый параметр переключен с Истина на Ложь:
ТекущаяОбласть = ТабличныйДокумент.FindText(ВРег(Стр), , ОбластьНаименованиеКраткое, Ложь, ЛОЖЬ, Истина, Истина);
Поиск сразу начинает находить нужные строки, так как теперь выполняется поиск вхождения подстроки.
Обратите внимание: решение с установкой ЯчейкаЦеликом = Ложь таит в себе критическую опасность при работе с географическими названиями и классификаторами. Метод FindText возвращает первое попавшееся совпадение вхождения подстроки. Посмотрим на реальные риски:
В результате в базу будут записаны чужие числовые коды и буквенные идентификаторы Альфа-2, что нарушит целостность учета.
В исходном коде используется конструкция ВРег(Стр) при передаче седьмого параметра ИгнорироватьРегистр = Истина. Обратим внимание: если седьмой параметр включен, платформа выполняет регистронезависимое сопоставление автоматически. Преобразование строки в верхний регистр здесь избыточно и не решает проблему пробельных символов.
Вызов методов табличного документа через межпроцессный интерфейс OLE/COM работает медленно. В исходном алгоритме на каждый создаваемый элемент справочника выполняются десятки удаленных вызовов:
КодЧисловой = ТабличныйДокумент.Area(ТекущаяОбласть.Верх, ОбластьКодЧисловой.Лево, ТекущаяОбласть.Низ, ОбластьКодЧисловой.Право).Текст;
НаименованиеКраткое = СокрЛП(ТабличныйДокумент.Area(ТекущаяОбласть.Верх, ОбластьНаименованиеКраткое.Лево, ТекущаяОбласть.Низ, ОбластьНаименованиеКраткое.Право).Текст);
НаименованиеПолное = СокрЛП(ТабличныйДокумент.Area(ТекущаяОбласть.Верх, ОбластьНаименованиеПолное.Лево, ТекущаяОбласть.Низ, ОбластьНаименованиеПолное.Право).Текст);
КодАльфа2 = ТабличныйДокумент.Area(ТекущаяОбласть.Верх, ОбластьКодАльфа2.Лево, ТекущаяОбласть.Низ, ОбластьКодАльфа2.Право).Текст;
Каждое обращение к свойствам Верх, Низ, Лево, Право, Area и Текст генерирует отдельный сетевой/системный RPC-запрос. При обработке сотен строк загрузка будет выполняться крайне медленно.
Чтобы избежать ошибочной записи смежных стран и ускорить обмен, применим один из следующих подходов.
Вместо того чтобы тянуть макет через COM и по ячейкам вычитывать данные, создадим в удаленной информационной базе экспортную функцию общего модуля. Передадим в нее наименование страны, выполним поиск и очистку строк внутри базы-источника и вернем готовый результат или уже созданную ссылку. Это сокращает десятки межпроцессных вызовов до одного.
Если мы не можем изменять удаленную конфигурацию, выгрузим макет один раз в локальную структуру или таблицу значений. При заполнении колонок обязательно очистим строки от пробелов и неразрывных пробелов:
// Очистка текста от пробелов и неразрывного пробела (код 160)
ОчищенныйТекст = СокрЛП(СтрЗаменить(ИсходныйТекст, Символы.НПП, ""));
Затем организуем поиск методом НайтиСтроки или точным сравнением в цикле. Это гарантирует 100% точность идентификации стран и ускорит работу процедуры в десятки раз.
Если подключаемая конфигурация построена на базе «1С:Библиотеки стандартных подсистем» (БСП), в ней уже присутствуют служебные механизмы классификатора стран мира. Вместо прямого парсинга макета надежнее вызывать штатные экспортные процедуры БСП, предназначенные для загрузки и подбора классификаторов.