Как найти и обработать английские и русские символы «х» в строке поиска 1С

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

При загрузке данных из внешних источников, таких как Excel, программисты 1С часто сталкиваются с проблемой «визуальных близнецов» или омографов. Типичный пример: обозначение габаритов изделий в формате «1500х800». На первый взгляд символ «х» выглядит стандартно, однако в данных могут одновременно присутствовать как кириллическая «х» (код Unicode 1093), так и латинская «x» (код Unicode 120), а иногда и специальный типографский знак умножения «×» (код Unicode 215).

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

Анализ проблемы: почему символы кажутся одинаковыми?

Первым делом проанализируем ситуацию, описанную в обсуждении. Разработчик часто попадает в ловушку, когда при написании кода в конфигураторе он переключает раскладку клавиатуры, визуально вводит разные символы, но 1С продолжает возвращать 0 при поиске. Это происходит по нескольким причинам:

  1. Особенности RDP и удаленного доступа: Если работа ведется через удаленный рабочий стол, раскладка на локальном компьютере и сервере может не синхронизироваться мгновенно. Вы думаете, что вводите латиницу, но в редактор попадает кириллица.
  2. Автозамены в Excel: Пользователи часто копируют данные из разных источников, и Excel может автоматически заменять обычный «икс» на символ умножения.
  3. Чувствительность функций: Функции поиска в 1С работают со значениями кодов символов, а не с их начертанием.

Чтобы убедиться в различии символов, мы рекомендуем использовать функцию КодСимвола. Давайте посмотрим на пример:


ТекстКириллица = "х"; // Русская
ТекстЛатиница = "x";  // Английская

Сообщить("Код русской х: " + КодСимвола(ТекстКириллица)); // Результат: 1093
Сообщить("Код английской x: " + КодСимвола(ТекстЛатиница)); // Результат: 120

Решение №1: Использование СтрРазделить с набором разделителей

Наиболее элегантный и современный способ, предложенный в обсуждении, — это использование функции СтрРазделить. Она позволяет передать в качестве второго параметра строку, содержащую сразу все возможные варианты разделителей. Платформа воспримет каждый символ в этой строке как отдельный признак для разбиения.

Разберем по шагам, как это реализовать:


// В переменной ИсточникСтрока находится значение типа "1500х800", где "х" может быть любой
ИсточникСтрока = "1500x800"; // Здесь латиница
// Указываем в строке разделителей и русскую, и английскую "х" в обоих регистрах
МассивРазмера = СтрРазделить(ИсточникСтрока, "хxХX", Ложь); 

Если МассивРазмера.Количество() = 2 Тогда
    Длина = СокрЛП(МассивРазмера[0]);
    Ширина = СокрЛП(МассивРазмера[1]);
    Сообщить("Размеры определены: " + Длина + " на " + Ширина);
ИначеЕсли МассивРазмера.Количество() = 1 Тогда
    Диаметр = СокрЛП(МассивРазмера[0]);
    Сообщить("Это диаметр: " + Диаметр);
Иначе
    Сообщить("Некорректный формат строки");
КонецЕсли;

Этот метод хорош тем, что нам не нужно делать вложенные условия Если...ИначеЕсли для каждого типа символа. СтрРазделить выполнит всю работу за один проход.

Решение №2: Предварительная нормализация (очистка) строки

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

Проанализируем пример функции нормализации:


Функция НормализоватьРазделитель(Знач ВходнаяСтрока)
    // Заменяем английский x на русский х
    Результат = СтрЗаменить(ВходнаяСтрока, "x", "х");
    Результат = СтрЗаменить(Результат, "X", "х");
    
    // Дополнительно можно заменить спецсимвол умножения (Unicode 215)
    Результат = СтрЗаменить(Результат, Символ(215), "х");
    
    // Заменяем звездочку, если она используется как разделитель
    Результат = СтрЗаменить(Результат, "*", "х");
    
    Возврат Результат;
КонецФункции

После такой обработки вы можете смело использовать СтрНайти(Строка, "х"), зная, что все варианты разделителей приведены к одному виду.

Решение №3: Работа с регулярными выражениями (RegExp)

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


RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.Pattern = "[xх×\*]"; // Ищем любой x (лат), х (кир), знак умножения или звездочку

Если RegExp.Test(ИсточникСтрока) Тогда
    Matches = RegExp.Execute(ИсточникСтрока);
    ПозицияРазделителя = Matches.Item(0).FirstIndex + 1;
    Сообщить("Разделитель найден в позиции: " + ПозицияРазделителя);
КонецЕсли;

Использование регулярных выражений позволяет сделать код максимально гибким к ошибкам ввода пользователей в Excel.

Решение №4: Проверка состава строки (только цифры или латиница)

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


Функция СодержитТолькоЛатиницу(СтрокаПроверки)
    Для Индекс = 1 По СтрДлина(СтрокаПроверки) Цикл
        Код = КодСимвола(Сред(СтрокаПроверки, Индекс, 1));
        // Диапазоны кодов латиницы: A-Z (65-90) и a-z (97-122)
        Если Не ((Код >= 65 И Код <= 90) Или (Код >= 97 И Код <= 122)) Тогда
            Возврат Ложь;
        КонецЕсли;
    КонецЦикла;
    Возврат Истина;
КонецФункции

Такой посимвольный перебор с анализом КодСимвола — это самый надежный способ, когда нужно гарантировать точность до конкретного знака Юникода.

Практические рекомендации по работе с символами в конфигураторе

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

Подводя итог, можно сказать, что проблема «английских иксов» решается либо расширением списка разделителей в СтрРазделить, либо принудительной нормализацией строки. Выбор метода зависит от ваших требований к производительности и сложности входящих данных.

← На главную