【问题标题】:Excel VBA: Open UTF-16 XMLExcel VBA:打开 UTF-16 XML
【发布时间】:2017-06-27 14:03:52
【问题描述】:

我目前正在努力在 Excel 中使用 VBA 打开一个 utf-16 编码的 XML 文件。

我当前的名为 EntireFile 的字符串变量当前开始如下:

ÿþ<?xml version="1.0" encoding="utf-16"?>
<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 

如您所见,开头的某些字符似乎不正确。

我通过以下方式获取字符串变量:

Open PathToFile For Input As #1
    Do Until EOF(1)
              Line Input #1, textline
              EntireFile = EntireFile & textline

根据 Notepad++,文件是用 UCS-2 Little Endian 格式化的,但是通过互联网快速搜索发现这是 Microsoft 等价于 UTF-16?

我尝试了仅删除前两个字符的蛮力方法,但留下一个空字符串。

所有的谷歌结果都包括保存没有 BOM 的 XML 文件,但这与我正在寻找的相反。

已经感谢您的宝贵时间

【问题讨论】:

    标签: xml excel vba utf-16 byte-order-mark


    【解决方案1】:

    您可以使用 Win32 API 函数来转换编码。

    Private Declare Function WideCharToMultiByte Lib "kernel32.dll" ( _
                             ByVal CodePage As Long, _
                             ByVal dwFlags As Long, _
                             ByVal lpWideCharStr As Long, _
                             ByVal cchWideChar As Long, _
                             ByVal lpMultiByteStr As Long, _
                             ByVal cbMultiByte As Long, _
                             ByVal lpDefaultChar As Long, _
                             ByVal lpUsedDefaultChar As Long) As Long
    
    Private Declare Function MultiByteToWideChar Lib "kernel32.dll" ( _
                             ByVal CodePage As Long, _
                             ByVal dwFlags As Long, _
                             ByVal lpMultiByteStr As Long, _
                             ByVal cbMultiByte As Long, _
                             ByVal lpWideCharStr As Long, _
                             ByVal cchWideChar As Long) As Long
    
    Private Const CP_UTF16 As Long = 1200&
    
    Private Function ConvertToUTF16(ByRef Source As String) As Byte()
    
        Dim Length As Long
        Dim Pointer As Long
        Dim Size As Long
        Dim Buffer() As Byte
    
        Length = Len(Source)
        Pointer = StrPtr(Source)
        Size = WideCharToMultiByte(CP_UTF16, 0, Pointer, Length, 0, 0, 0, 0)
        ReDim Buffer(0 To Size - 1)
    
        WideCharToMultiByte CP_UTF16, 0, Pointer, Length, VarPtr(Buffer(0)), _
            Size, 0, 0
    
        ConvertToUTF16 = Buffer
    
    End Function
    
    Private Function ConvertFromUTF16(ByRef Source() As Byte) As String
    
        Dim Size As Long
        Dim Pointer As Long
        Dim Length As Long
        Dim Buffer As String
    
        Size = UBound(Source) - LBound(Source) + 1
        Pointer = VarPtr(Source(LBound(Source)))
        Length = MultiByteToWideChar(CP_UTF16, 0, Pointer, Size, 0, 0)
        Buffer = Space$(Length)
        MultiByteToWideChar CP_UTF16, 0, Pointer, Size, StrPtr(Buffer), Length
        ConvertFromUTF16 = Buffer
    
    End Function
    

    Private Const CP_UTF16 As Long = 1200&amp; 表示代码页 1200,即 UTF-16 little andian。

    你可以在这里看到所有代码页的列表https://msdn.microsoft.com/de-de/library/windows/desktop/dd317756(v=vs.85).aspx

    【讨论】:

    • 感谢您的回答。我尝试将您的代码块添加为模块,并在填充后使用 EntireFile 从我的代码内部调用函数 CovertToUTF16(我公开)。 WideCharToMultiByte 让我的索引超出范围。我很确定这是我的错误,因为这是一个导入的函数,但我不知道在哪里。
    • 我再次浏览了整个代码,发现如果 Len(Source) 没有返回 3000(这显然是错误的),导入的函数将按预期执行。
    猜你喜欢
    • 2021-02-11
    • 2011-01-07
    • 1970-01-01
    • 2011-07-02
    • 2021-07-29
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多