VBA-convertir la chaîne en UNICODE

je dois convertir la chaîne HTML d'un mélange de symboles cyrilliques et latins en UNICODE.

j'ai essayé la suivante:

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

vous pouvez voir ce qui est avant et après le StrConv. Si vous aimez obtenir le html dans un fichier, vous pouvez utiliser le code suivant:

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

idées?

2
demandé sur industryworker3595112 2014-05-22 18:54:14

2 réponses

le support de VBA pour Unicode n'est pas si génial que ça.

il est possible de manipuler des chaînes Unicode, mais vous ne pourrez pas voir les caractères réels avec Debug.Print ou MsgBox - ils apparaîtront comme ? là.

vous pouvez définir Panneau de configuration > région et langue > onglet administratif > "langage courant pour les programmes non Unicode" à" Russe " passez à une page de code différente, qui serait permet de voir des lettres cyrilliques dans les boîtes de messages VBA au lieu de points d'interrogation. Mais c'est seulement un changement cosmétique.


votre vrai problème est autre chose ici.

the server (nfs.mobile.bg) envoie le document comme Content-Type: text/html . Il n'y a aucune information sur l'encodage des caractères. Cela signifie que le récepteur doit comprendre l'encodage des caractères de lui-même.

un navigateur fait cela en regardant réponse byte stream et faire des suppositions. Dans votre cas, une étiquette utile <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> est présente dans la source HMTL. Par conséquent , le flux byte doit être interprété comme Windows-1251 , qui se trouve être la page de code ANSI Cyrillique dans Windows.

Donc, nous n'avons même pas Unicode ici!

en l'absence de toute information supplémentaire, la propriété responseText de l'objet XMLHTTP est par défaut us-ascii . Les caractères étendus de la L'alphabet cyrillique n'est pas présent en ASCII, donc ils seront convertis en réels points d'interrogation et sont perdus. C'est pourquoi vous ne pouvez pas utiliser responseText pour quoi que ce soit.

cependant, les octets original de la réponse sont encore disponibles, dans la propriété responseBody , qui est un tableau de Byte .

dans VBA vous devez faire la même chose qu'un navigateur ferait. Vous devez interpréter la byte-stream comme un jeu de caractères. L'objet ADODB.Stream peut faire cela pour vous, et c'est assez simple, aussi:

' 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 Html As String

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

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

Function GetHTML(Url As String) 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

    ' read text characters from the stream
    converter.Position = 0
    converter.Type = adTypeText
    converter.Charset = "Windows-1251"

    ' set return value, close the stream
    GetHTML = converter.ReadText
    converter.Close
End Function

j'ai utilisé MS Word ici et appelant HTMLsearch() écrit correctement les caractères cyrilliques à la page. Ils apparaissent toujours comme ? dans un MsgBox pour moi, cependant, mais maintenant c'est purement un problème d'affichage, causé par le fait que L'interface utilisateur créée par VBA ne peut pas traiter avec Unicode.

7
répondu Tomalak 2014-05-23 02:01:44

mes données de commande de production proviennent de nombreux pays. c'est la seule fonction vba que j'ai pu trouver qui fonctionne vraiment.

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

Exemple D'Usage:

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
2
répondu hamish 2015-04-22 08:08:58