Как заменить русские буквы на английские в артикулах 1С для правильной сортировки?

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

Многие разработчики сталкиваются с ситуацией, когда артикулы в базе данных выглядят идентично, но сортируются в списках и отчетах хаотично. Причина кроется в использовании омографов — символов кириллицы и латиницы, которые пишутся одинаково, но имеют разные коды (например, русская «А» и английская «A»). Рассмотрим, почему стандартная замена в печатных формах не работает и как реализовать надежный механизм унификации данных.

Анализ проблемы: почему СтрЗаменить при печати — это ошибка

Проанализируем ситуацию, описанную в первом сообщении. Разработчик пытается выполнить СтрЗаменить непосредственно перед выводом артикула в табличный документ. Однако сортировка в 1С (особенно в динамических списках и запросах) происходит на уровне СУБД (SQL Server или PostgreSQL) еще до того, как данные попадут в программный код для печати.

Если в базе данных один артикул записан как "A100" (латиница), а другой как "А100" (кириллица), то в запросе они всегда будут находиться в разных частях списка. Исправление символов "на лету" при выводе на печать изменит внешний вид буквы, но никак не повлияет на порядок строк. Таким образом, мы приходим к выводу: данные должны храниться в базе в унифицированном виде.

Решение 1: Автоматическая замена в обработчике ПередЗаписью

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


Процедура ПередЗаписью(Отказ)
    // Выполняем замену только если это не обмен данными
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Вызываем функцию очистки артикула
    Артикул = ИсправитьЛатиницуВСтроке(Артикул);
КонецПроцедуры

Функция ИсправитьЛатиницуВСтроке(Знач ВходнаяСтрока) Экспорт
    // Создаем соответствие русских букв английским аналогам
    КартаЗамен = Новый Соответствие;
    КартаЗамен.Вставить("А", "A"); КартаЗамен.Вставить("В", "B");
    КартаЗамен.Вставить("Е", "E"); КартаЗамен.Вставить("К", "K");
    КартаЗамен.Вставить("М", "M"); КартаЗамен.Вставить("Н", "H");
    КартаЗамен.Вставить("О", "O"); КартаЗамен.Вставить("Р", "P");
    КартаЗамен.Вставить("С", "C"); КартаЗамен.Вставить("Т", "T");
    КартаЗамен.Вставить("У", "Y"); КартаЗамен.Вставить("Х", "X");
    
    Результат = "";
    Для Позиция = 1 По СтрДлина(ВходнаяСтрока) Цикл
        Символ = Сред(ВходнаяСтрока, Позиция, 1);
        НайденныйСимвол = КартаЗамен.Получить(Врег(Символ));
        
        Если НайденныйСимвол <> Неопределено Тогда
            Результат = Результат + НайденныйСимвол;
        Иначе
            Результат = Результат + Символ;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Результат;
КонецФункции

Этот метод гарантирует, что при каждом сохранении карточки товара артикул будет приведен к единому стандарту латиницы автоматически, независимо от того, какую раскладку использовал пользователь.

Решение 2: Превентивная валидация (Напрягаем пользователя)

Иногда автоматическая замена может быть опасна (например, если в артикуле действительно допустимы и русские, и английские буквы в разных смыслах). В этом случае, как предлагалось в сообщении №15, стоит использовать метод "жесткого отказа". Проанализируем, как реализовать проверку на наличие запрещенных символов кириллицы.

Выясним причину ошибки с помощью функции Библиотеки Стандартных Подсистем (БСП), если ваша конфигурация её использует:


Процедура ПередЗаписью(Отказ)
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Используем БСП для проверки состава строки
    Если НЕ СтроковыеФункцииКлиентСервер.СодержитТолькоЛатиницу(Артикул) Тогда
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
            "В артикуле обнаружены русские буквы! Пожалуйста, используйте только латиницу.",
            ЭтотОбъект,
            "Артикул",
            ,
            Отказ);
    КонецЕсли;
КонецПроцедуры

Такой подход заставляет пользователей быть внимательнее и предотвращает появление "мусора" в базе на этапе ввода данных.

Решение 3: Использование Регулярных выражений (RegExp)

Для более сложных случаев, когда нужно проверить не всю строку, а только её часть (например, первые два символа префикса, как упоминалось в сообщении №25), удобно использовать регулярные выражения. Это особенно актуально, если артикул имеет сложную структуру типа "H1500 Gri/серый".

Рассмотрим пример функции, которая находит кириллицу в начале строки:


Функция СодержитКириллицуВНачале(СтрокаАртикула)
    RegExp = Новый COMОбъект("VBScript.RegExp");
    RegExp.IgnoreCase = Ложь;
    RegExp.Global = Истина;
    // Шаблон ищет любые русские буквы от А до Я в первых двух символах
    RegExp.Pattern = "^[А-Яа-яЁё]{1,2}"; 
    
    Возврат RegExp.Test(СтрокаАртикула);
КонецФункции

Как исправить уже существующие данные?

Если база уже наполнена "кривыми" артикулами, простая вставка кода в модуль объекта не поможет — она сработает только при будущих изменениях. Нам необходимо выполнить групповую обработку. Проанализируем последовательность действий:

  1. Создаем внешнюю обработку или используем стандартную "Групповое изменение реквизитов".
  2. В алгоритме обработки вызываем созданную нами функцию ИсправитьЛатиницуВСтроке.
  3. Важно: Перед массовым изменением обязательно сделайте резервную копию базы данных, так как изменение артикулов может повлиять на поиск в сторонних системах (например, на сайте интернет-магазина).
  4. После исправления данных в базе необходимо перестроить индексы или просто убедиться, что сортировка в динамических списках теперь работает корректно.

Рекомендации по работе с SQL-сортировкой

Помните, что порядок следования строк в запросе определяется параметром Collation (сопоставление) вашей базы данных. В стандартных настройках 1С для России (Cyrillic_General_CI_AS) латинские буквы и цифры обычно предшествуют кириллице. Именно поэтому "смешанные" артикулы разлетаются по разным концам списка. Единственный надежный способ обеспечить предсказуемую сортировку — полное исключение кириллических омографов из полей, предназначенных для идентификации (артикулов, кодов, серийных номеров).

Резюмируем: для решения проблемы не используйте замену в печатных формах. Перенесите логику в ПередЗаписью модуля объекта, внедрите проверку на стороне пользователя и проведите разовую чистку существующих данных с помощью скрипта или групповой обработки.

← На главную