Как перекодировать строки из Unicode (формата \uXXXX) в 1С 7.7

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Проблема работы с современными кодировками в платформе 1С:Предприятие 7.7 стоит достаточно остро, так как эта версия программы была разработана задолго до повсеместного внедрения стандарта Unicode. Одной из часто встречающихся задач является декодирование строк вида \u0410\u043d\u0442\u043e\u043d (что соответствует имени "Антон"). В этой статье мы подробно разберем, как научить "семерку" понимать такие последовательности, используя как встроенные средства, так и возможности системных компонентов Windows.

Метод 1: Использование MSScriptControl (JavaScript)

Разберем самый изящный и производительный способ — использование COM-объекта MSScriptControl.ScriptControl. Поскольку формат \uXXXX является родным для языка JavaScript, мы можем делегировать задачу преобразования движку JScript, который присутствует в любой современной операционной системе Windows. Проанализируем, почему это работает: COM-интерфейс при передаче строки обратно в 1С автоматически выполняет преобразование типов, если символы входят в кириллический диапазон Windows-1251.

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


Функция ДекодироватьUnicode(ВходнаяСтрока)
    Перем Скрипт, Результат;
    Скрипт = СоздатьОбъект("MSScriptControl.ScriptControl");
    Скрипт.Language = "JScript";
    // Оборачиваем строку в кавычки для корректной интерпретации в JS
    Попытка
        Результат = Скрипт.Eval("'" + ВходнаяСтрока + "'");
        Возврат Результат;
    Исключение
        Возврат ВходнаяСтрока; // Если произошла ошибка, возвращаем оригинал
    КонецПопытки;
КонецФункции

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

Метод 2: Использование объекта HTMLFile

Выясним причину, по которой иногда ScriptControl может быть недоступен (например, из-за ограничений прав доступа или специфических настроек безопасности). В таком случае мы можем воспользоваться объектом htmlfile. Это встроенный движок Internet Explorer, который умеет парсить скрипты и работать с текстовыми потоками.

Посмотрим на алгоритм реализации через htmlfile:


Функция UnescapeUnicodeHTML(Стр)
    Перем Док, Окно;
    Док = СоздатьОбъект("htmlfile");
    Док.write("<script>var result = '" + Стр + "';</script>");
    Окно = Док.parentWindow;
    Возврат Окно.result;
КонецФункции

В данном примере мы записываем скрипт прямо в документ, а затем через свойство parentWindow забираем значение переменной. Это позволяет избежать проблем с кодировкой на этапе передачи данных.

Метод 3: Алгоритм ручного декодирования (Native 1C)

Рассмотрим ситуацию, когда использование внешних COM-объектов невозможно или нежелательно. В этом случае нам придется реализовать алгоритм декодирования на чистом языке 1С 7.7. Это требует понимания того, как устроена кодировка ANSI (Windows-1251) и как она соотносится с Unicode.

Разберем задачу по шагам:

  1. Поиск маркера: Сначала нам нужно найти вхождение подстроки \u с помощью функции Найти().
  2. Извлечение шестнадцатеричного кода: Берем 4 символа, следующих сразу за маркером (например, "0410").
  3. Конвертация HEX в DEC: Преобразуем полученное шестнадцатеричное число в десятичное. Для этого напишем вспомогательную функцию.
  4. Маппинг символов: Так как кириллица в Unicode начинается с кода 1040 (символ "А"), а в Win-1251 этот же символ имеет код 192, мы применяем формулу смещения.

Проанализируем код такой реализации:


Функция ИзHexВДес(Знач СтрHex)
    СтрHex = Врег(СтрHex);
    СписокЗначений = "0123456789ABCDEF";
    Рез = 0;
    Для х = 1 По СтрДлина(СтрHex) Цикл
        Симв = Сред(СтрHex, х, 1);
        Поз = Найти(СписокЗначений, Симв) - 1;
        Рез = Рез * 16 + Поз;
    КонецЦикла;
    Возврат Рез;
КонецФункции

Функция ДекодироватьВручную(ВходнаяСтрока)
    Стр = ВходнаяСтрока;
    Поз = Найти(Стр, "\u");
    Пока Поз > 0 Цикл
        КодHex = Сред(Стр, Поз + 2, 4);
        КодDec = ИзHexВДес(КодHex);
        
        // Логика замены для кириллицы
        Если (КодDec >= 1040) И (КодDec <= 1103) Тогда
            Симв1251 = Симв(КодDec - 1040 + 192);
        ИначеЕсли КодDec = 1025 Тогда // Буква Ё
            Симв1251 = Симв(168);
        ИначеЕсли КодDec = 1105 Тогда // Буква ё
            Симв1251 = Симв(184);
        Иначе
            Симв1251 = "?"; // Для символов вне Win-1251
        КонецЕсли;
        
        Стр = Лев(Стр, Поз - 1) + Симв1251 + Сред(Стр, Поз + 6);
        Поз = Найти(Стр, "\u");
    КонецЦикла;
    Возврат Стр;
КонецФункции

Важный момент: Данный метод будет работать корректно только для кириллического алфавита. Если в строке встретятся специфические символы (например, греческие буквы или сложные математические знаки), они не смогут быть отображены в стандартном интерфейсе 1С 7.7, так как в таблице Windows-1251 для них просто нет места.

Метод 4: Использование ADODB.Stream для сложных случаев

Проанализируем ситуацию, когда данные приходят не в виде строки с экранированными символами \uXXXX, а в виде чистого бинарного потока UTF-8. В этом случае использование вышеперечисленных функций бесполезно. Нам поможет объект ADODB.Stream.

Рассмотрим, как выполнить преобразование всего потока данных:


Функция ИзUTF8в1251(ТекстUTF8)
    Перем Stream;
    Stream = СоздатьОбъект("ADODB.Stream");
    Stream.Type = 2; // adTypeText
    Stream.Charset = "windows-1251";
    Stream.Open();
    Stream.WriteText(ТекстUTF8);
    Stream.Position = 0;
    Stream.Charset = "utf-8";
    Результат = Stream.ReadText();
    Возврат Результат;
КонецФункции

Следует помнить, что ADODB.Stream — это мощный инструмент именно для перекодировки байтовых последовательностей. Если ваш источник данных — это JSON-ответ от веб-сервиса, где кириллица уже заэкранирована в \uXXXX, используйте Метод 1 или Метод 3.

Рекомендации и итоги

Подведем итог нашему исследованию. Для большинства задач в 1С 7.7 оптимальным выбором будет MSScriptControl (Метод 1). Он наиболее универсален, поддерживает не только кириллицу, но и любые управляющие символы (переносы строк, табуляции), заэкранированные в Unicode-формате.

Если же вы работаете в закрытом контуре безопасности, где создание COM-объектов запрещено, используйте алгоритм ручного маппинга. Не забывайте отдельно обрабатывать буквы "Ё" и "ё", так как их коды в Unicode находятся вне основного диапазона кириллицы, и стандартная формула смещения к ним не применима.

Помните: 1С 7.7 ограничена кодировкой ANSI. Любой символ, которого нет в вашей системной локали (обычно это Windows-1251), при попытке вывода на экран или записи в справочник превратится в знак вопроса. Если ваша задача требует полноценной поддержки мультиязычности, рассмотрите возможность перехода на платформу 1С 8.3.

← На главную