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