Как в 1С 7.7 сохранить результат запроса в кодировке UTF-8 без искажений

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

Работа с современными веб-сервисами из среды 1С:Предприятие 7.7 часто превращается в настоящую проблему из-за ограничений старой платформы. Основная сложность заключается в том, что 1С 7.7 является ANSI-приложением и не поддерживает Unicode (UTF-8) нативно. Когда мы пытаемся получить данные с сайта, который отдает ответ в UTF-8, стандартные строковые переменные 1С превращают текст в нечитаемую «абракадабру» (кракозябры), так как пытаются интерпретировать байты через системную кодовую страницу (обычно Windows-1251).

В этой статье мы подробно разберем, почему стандартные методы не работают, и рассмотрим наиболее эффективное решение, которое позволяет сохранить данные в файл UTF-8, полностью обходя ограничения платформы.

Почему стандартный ResponseText не подходит?

Рассмотрим типичную ошибку. Программист использует объект WinHttp.WinHttpRequest.5.1 и пытается получить текст через свойство ResponseText. Проблема в том, что в момент обращения к этому свойству сам объект WinHttp пытается декодировать полученные байты в строку. Поскольку 1С 7.7 «не понимает» многобайтовые кодировки, происходит необратимая потеря данных. Даже если вы потом попытаетесь записать эту строку в ADODB.Stream с указанием Charset="utf-8", вы просто сохраните уже испорченные символы в формате UTF-8.

Для корректной работы нам необходимо получить данные в «сыром» виде (массив байт) и передать их в поток записи, не задействуя строковые механизмы самой 1С.

Решение проблемы через MSScriptControl и бинарный поток

Наиболее надежный способ, предложенный в сообществе, — это использование промежуточного объекта MSScriptControl.ScriptControl. Этот объект позволяет выполнить код на языке JScript или VBScript, которые умеют корректно передавать бинарные данные между другими COM-объектами.

Разберем алгоритм решения по шагам:

  1. Создаем объект WinHttp и выполняем запрос к сайту.
  2. Создаем объект ADODB.Stream, который будет отвечать за запись файла.
  3. Используем MSScriptControl, чтобы передать свойство ResponseBody (бинарные данные) напрямую в метод Write объекта Stream.
  4. Сохраняем поток в файл на диске.

Рассмотрим пример кода, который реализует этот механизм:


// Создаем объекты для запроса и потока
WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("GET", "https://example.com/data.xml", 0);
WinHttp.Send();

Stream = СоздатьОбъект("ADODB.Stream"); 
Stream.Mode = 3; // ReadWrite
Stream.Type = 1; // Binary (важно: работаем с байтами, а не текстом)
Stream.Open(); 
        
// Используем ScriptControl для обхода ограничений 1С по работе с SafeArray
Скрипт = СоздатьОбъект("MSScriptControl.ScriptControl"); 
Скрипт.Language = "javascript"; 
        
// Добавляем наши объекты в контекст скрипта
Скрипт.AddObject("WinHttp", WinHttp); 
Скрипт.AddObject("Стрим", Stream); 

// Выполняем передачу бинарного тела ответа в поток
// В JScript WinHttp.ResponseBody воспринимается корректно
Скрипт.Eval("Стрим.Write(WinHttp.ResponseBody)"); 
        
// Сохраняем результат в файл. 2 = SaveCreateOverWrite
ПутьКФайлу = "C:\temp\result.xml";
Stream.SaveToFile(ПутьКФайлу, 2);
Stream.Close();

Важный нюанс: Обратите внимание, что мы устанавливаем Stream.Type = 1 (Binary). Это позволяет нам сохранить данные «как есть», байт в байт. Поскольку сайт уже отдал нам данные в UTF-8, файл сохранится именно в этой кодировке без каких-либо дополнительных преобразований со стороны 1С.

Работа с XML через MSXML2.DOMDocument

Если ваша задача — получить именно XML-документ и вы хотите сразу работать с его структурой, можно использовать объект MSXML2.DOMDocument. У него есть метод load(), который умеет принимать объект ResponseStream напрямую.

Проанализируем этот подход:


WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("GET", "https://site.ru/export.xml", 0);
WinHttp.Send();

// Создаем объект XML-документа
XMLДок = СоздатьОбъект("MSXML2.DOMDocument");

// Важно: передаем не текст, а сам объект WinHttp или его ResponseStream
// Это позволит парсеру самому определить кодировку UTF-8 из заголовка XML
XMLДок.load(WinHttp.ResponseStream);

// Теперь можно сохранить XML в файл, он будет в UTF-8
XMLДок.save("d:\data.xml");

Этот метод еще более изящен, так как он избавляет от необходимости использовать ScriptControl, если конечная цель — сохранение или обработка XML-структуры.

Ручная перекодировка (если данные уже в 1С)

Иногда возникают ситуации, когда данные уже попали в строковую переменную 1С в кодировке Windows-1251, и их нужно программно сконвертировать в UTF-8 для отправки обратно на сервер. Для этого можно использовать функцию перебора символов и замены их на соответствующие байтовые последовательности UTF-8. Рассмотрим пример такой функции:


Функция ПреобразоватьСтрокуВУТФ8(Стр)
    Длина = СтрДлина(Стр);
    Итог = "";
    Для Н = 1 По Длина Цикл
        Знак = Сред(Стр, Н, 1);
        Код = КодСимв(Знак);
        Если Код < 128 Тогда
            Итог = Итог + Знак;
        Иначе
            // Обработка кириллицы
            Если (Код >= КодСимв("А")) И (Код <= КодСимв("п")) Тогда
                Итог = Итог + Симв(208) + Симв(144 + Код - КодСимв("А"));
            ИначеЕсли (Код >= КодСимв("р")) И (Код <= КодСимв("я")) Тогда
                Итог = Итог + Симв(209) + Симв(128 + Код - КодСимв("р"));
            ИначеЕсли (Знак = "ё") Тогда
                Итог = Итог + Симв(209) + Симв(145);
            ИначеЕсли (Знак = "Ё") Тогда
                Итог = Итог + Симв(208) + Симв(129);
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    Возврат Итог;
КонецФункции

Внимание: Этот метод подходит только для преобразования обычного текста 1С (ANSI) в формат, который будет выглядеть как UTF-8 при записи в файл. Он не поможет восстановить данные, которые уже были испорчены при получении через ResponseText.

Дополнительные рекомендации

Выясним еще несколько важных моментов, которые могут встретиться при интеграции:

Подводя итог, можно сказать, что использование бинарного потока через ScriptControl является «золотым стандартом» для решения проблем с кодировками в 1С 7.7. Это гарантирует 100% сохранность данных и позволяет интегрировать старые системы с любыми современными API.

← На главную