问题描述
据我所知,Excel使用UTF-16表示字符串文字。我从控制台(Mac)/文件(Windows)中读取,在两种情况下,字符编码都混乱了。我必须找到在两个平台上都可以使用的解决方案,因此ADO流不是一个选择。我进行了一些调试,发现实际字节是:
Bytes | displayed as | Should be | Correct byte 258,129 | Ă | Á | 193 258,356 | ĂŤ | Í | 205 313,176 | Ű | Ű | 219 313,144 | Ĺ | Ő | 213 258,347 | Ăś | Ü | 220 258,8211 | Ă– | Ö | 214 258,353 | Ăš | Ú | 218 258,8220 | Ă“ | Ó | 211 258,8240 | É | É | 201
(来自古老的匈牙利测试用语ÁRVÍZTŰRŐTÜKÖRFÚRÓGÉP,其中包含我们所有的特殊字符)。 我正在寻找一种在Mac和Windows上都能生成正确字符串的算法。 谢谢!
解决方法
我必须解决此问题,所以提出了以下功能,可以成功转换128到255之间的字符
Private Function utf8ToUTF16(ByVal strText As String) As String
Dim i&,l1%,l2%,l3%
For i = 1 To Len(strText)
l1 = Asc(Mid(strText,i,1))
If i <> Len(strText) Then l2 = Asc(Mid(strText,i + 1,1))
Select Case l1
Case 194
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l2): i = i + 1
Case 195
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l2 + &H40): i = i + 1
Case 197
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l2 + &HC0): i = i + 1
Case 203
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l2 + &H240): i = i + 1
Case 226
If l2 = 128 Then
l3 = Asc(Mid(strText,i + 2,1))
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l3 + &H1F80)
i = i + 2
ElseIf l2 = 130 Then
l3 = Asc(Mid(strText,1))
utf8ToUTF16 = utf8ToUTF16 & WorksheetFunction.Unichar(l3 + &H2000)
i = i + 2
End If
Case Else
utf8ToUTF16 = utf8ToUTF16 & Chr(l1)
End Select
Next i
End Function
现在将“ ĂRVĂŤZTĹRĹTĹśKĂ–RFĂšRĂ”GÉP传递给此函数(从标准UTF-8编码文件读取)将返回“ÁRVÍZTŰRŐTÜKÖRFÚRÓGÉP”。
- 注意:当然,这不是最有效的代码。每当我调用它时,我总是在尽可能短的字符串上使用它。目前,我使用它来解码cURL的结果,然后将整个HTML冻结。
编辑
现在我有一些时间来清理它。
Private Function utf8ToUTF16(ByVal strText As String) As String
Dim i&,l1&,l2&,l3&,l4&,l&
For i = 1 To Len(strText)
l1 = Asc(Mid(strText,1))
If i + 1 <= Len(strText) Then l2 = Asc(Mid(strText,1))
If i + 2 <= Len(strText) Then l3 = Asc(Mid(strText,1))
If i + 3 <= Len(strText) Then l4 = Asc(Mid(strText,i + 3,1))
Select Case l1
Case 1 To 127
l = l1
Case 194 To 223
l = ((l1 And &H1F) * 2 ^ 6) Or (l2 And &H3F)
i = i + 1
Case 224 To 239
l = ((l1 And &HF) * 2 ^ 12) Or ((l2 And &H3F) * 2 ^ 6) Or (l3 And &H3F)
i = i + 2
Case 240 To 255
l = ((l1 And &H7) * 2 ^ 18) Or ((l2 And &H3F) * 2 ^ 12) Or ((l3 And &H3F) * 2 ^ 6) Or (l4 And &H3F)
i = i + 4
Case Else
l = 63 ' question mark
End Select
utf8ToUTF16 = utf8ToUTF16 & IIf(l < 55296,WorksheetFunction.Unichar(l),"?")
Next i
End Function
我意识到,高于55295(D7FF)的字符将不会出现,因此它将输出一个问号代替占位符。
,我发现这个简单的 VBA 代码适用于文本文件中的西班牙重音字符。给定一个带有 UTF-8 双字符的字符串,它返回一个带有重音字符的字符串:
Function UTF8to16(str As String) As String
Dim position As Long,strConvert As String,codeReplace As Integer,strOut As String
strOut = str
position = InStr(strOut,Chr(195))
If position > 0 Then
Do Until position = 0
strConvert = Mid(strOut,position,2)
codeReplace = Asc(Right(strConvert,1))
If codeReplace < 255 Then
strOut = Replace(strOut,strConvert,Chr(codeReplace + 64))
Else
strOut = Replace(strOut,Chr(34))
End If
position = InStr(strOut,Chr(195))
Loop
End If
UTF8to16 = strOut
End Function