VBA - конвертировать строку в UNICODE

Мне нужно преобразовать строку HTML из сочетания символов кириллицы и латиницы в UNICODE.

Я попробовал следующее:

Public HTML As String
    Sub HTMLsearch()

    GetHTML ("http://nfs.mobile.bg/pcgi/mobile.cgi?act=3&slink=6jkjov&f1=1")
    MsgBox HTML
    HTML = StrConv(HTML, vbUnicode)
    MsgBox HTML
End Sub

Function GetHTML(URL As String) As String
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", URL, False
        .Send
        HTML = .ResponseText
    End With
End Function

Вы можете увидеть, что до и после StrConv. Если вы хотите получить HTML в файле, вы можете использовать следующий код:

Public HTML As String
    Sub HTMLsearch()

    GetHTML ("http://nfs.mobile.bg/pcgi/mobile.cgi?act=3&slink=6jkjov&f1=1")

    Dim path As String

    path = ThisWorkbook.path & "\html.txt"
    Open path For Output As #1
    Print #1, HTML
    Close #1

    HTML = StrConv(HTML, vbUnicode)

    path = ThisWorkbook.path & "\htmlUNICODE.txt"
    Open path For Output As #1
    Print #1, HTML
    Close #1
End Sub

Function GetHTML(URL As String) As String
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", URL, False
        .Send
        HTML = .ResponseText
    End With
End Function

ИДЕИ?

2 ответа

Решение

Поддержка Unicode в VBA не так уж велика.

Можно обрабатывать строки Unicode, но вы не сможете увидеть реальные символы с Debug.Print или же MsgBox - они будут отображаться как ? там.

Вы можете установить " Панель управления"> "Регион и язык"> вкладка "Администрирование"> "Текущий язык для программ, не поддерживающих Юникод", на "Русский", чтобы переключиться на другую кодовую страницу, что позволит вам видеть буквы кириллицы в окнах сообщений VBA вместо вопросительных знаков. Но это только косметическое изменение.


Ваша настоящая проблема здесь в другом.

Сервер (nfs.mobile.bg) отправляет документ как Content-Type: text/html, Нет информации о кодировке символов. Это означает, что получатель должен самостоятельно определить кодировку символов.

Браузер делает это, просматривая поток байтов ответа и делая предположения. В вашем случае полезный <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> тег присутствует в источнике HMTL. Следовательно, поток байтов должен интерпретироваться как Windows-1251, которая является кодовой страницей кириллицы ANSI в Windows.

Таким образом, у нас даже нет Unicode здесь!

При отсутствии какой-либо дополнительной информации, responseText собственность XMLHTTP объект по умолчанию us-ascii, Расширенные символы из кириллицы отсутствуют в ASCII, поэтому они будут преобразованы в фактические знаки вопроса и будут потеряны. Вот почему вы не можете использовать responseText для всего.

Тем не менее, оригинальные байты ответа все еще доступны, в responseBody свойство, которое представляет собой массив Byte,

В VBA вы должны делать то же, что и браузер. Вы должны интерпретировать поток байтов как определенный набор символов. ADODB.Stream object может сделать это за вас, и это тоже довольно просто:

' reference: "Microsoft XML, v6.0" (or any other version)
' reference: "Microsoft ActiveX Data Objects 6.1 library" (or any other version)
Option Explicit

Sub HTMLsearch()
    Dim url As String, html As String

    url = "http://nfs.mobile.bg/pcgi/mobile.cgi?act=3&slink=6jkjov&f1=1"
    html = GetHTML(url, "Windows-1251")

    ' Cyrillic characters are supported in Office, so they will appear correctly
    ActiveDocument.Range.InsertAfter html
End Sub

Function GetHTML(Url As String, Optional Charset As String = "UTF-8") As String
    Dim request As New MSXML2.XMLHTTP
    Dim converter As New ADODB.stream

    ' fetch page
    request.Open "GET", Url, False
    request.send

    ' write raw bytes to the stream
    converter.Open
    converter.Type = adTypeBinary
    converter.Write request.responseBody

    ' switch the stream to text mode and set charset
    converter.Position = 0
    converter.Type = adTypeText
    converter.Charset = Charset

    ' read text characters from the stream, close the stream
    GetHTML = converter.ReadText
    converter.Close
End Function

Я использовал MS Word здесь и звоню HTMLsearch() правильно пишет кириллицу на странице. Они все еще выглядят как ? в MsgBox для меня, хотя, но теперь это просто проблема отображения, вызванная тем, что созданный VBA пользовательский интерфейс не может работать с Unicode.

Мои производственные заказы поступают из многих стран. это единственная функция VBA, которую я смог найти, которая действительно работает.

Private Const CP_UTF8 = 65001

Private Declare Function MultiByteToWideChar Lib "kernel32" ( _
   ByVal CodePage As Long, ByVal dwFlags As Long, _
   ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, _
   ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long


Public Function sUTF8ToUni(bySrc() As Byte) As String
   ' Converts a UTF-8 byte array to a Unicode string
   Dim lBytes As Long, lNC As Long, lRet As Long

   lBytes = UBound(bySrc) - LBound(bySrc) + 1
   lNC = lBytes
   sUTF8ToUni = String$(lNC, Chr(0))
   lRet = MultiByteToWideChar(CP_UTF8, 0, VarPtr(bySrc(LBound(bySrc))), lBytes, StrPtr(sUTF8ToUni), lNC)
   sUTF8ToUni = Left$(sUTF8ToUni, lRet)
End Function

Пример использования:

Dim sHTML As String
Dim bHTML() As Byte
bHTML = GetHTML("http://yoururlhere/myorderdata.php")
sHTML = sUTF8ToUni(bHTML)
sHTML = Mid(sHTML, 2)  'strip off Byte Order Mark: EF BB BF
Другие вопросы по тегам