如何在vba中实现字符的unicode编码和utf-8编码相互转换?

在文章如何在vba中实现字符的Unicode编码与ANSI编码相互转换?中介绍了利用vba内置函数StrConv 实现字符的Unicode编码与ANSI编码的相互转换。

今天,介绍利用api函数WideCharToMultiByteMultiByteToWideChar  实现字符的unicode编码和utf-8编码相互转换。

其中WideCharToMultiByte语法如下:

int WideCharToMultiByte(
  _In_      UINT    CodePage,
  _In_      DWORD   dwFlags,
  _In_      LPCWSTR lpWideCharStr,
  _In_      int     cchWideChar,
  _Out_opt_ LPSTR   lpMultiByteStr,
  _In_      int     cbMultiByte,
  _In_opt_  LPCSTR  lpDefaultChar,
  _Out_opt_ LPBOOL  lpUsedDefaultChar
);

其中参数codepage表示要以什么字符集进行转换,具体的值可以从Code Page Identifiers获取到。

一般的几个常用的值为Const CP_UTF8 = 65001(表示转换为UTF-8),Const CP_ACP = 0(标准转换为系统默认的ANSI编码)

dwFlags参数一般为0,lpWideCharStr参数指的指向要转换的字符串的指针,cchWideChar参数表示要转换的字符串的字符数,lpMultiByteStr参数为指向接收转换后的字节的缓存区的指针,cbMultiByte参数表示以字节为单位表示的lpMultiByteStr参数的缓存区的字节大小,如果cbMultiByte参数设置为0,则WideCharToMultiByte函数将返回实际转换后需要的字节数,lpDefaultChar参数和lpUsedDefaultChar参数一般设置为0。

类似的MultiByteToWideChar 参数的语法如下:

int MultiByteToWideChar(
_In_ UINT CodePage,
_In_ DWORD dwFlags,
_In_ LPCSTR lpMultiByteStr,
_In_ int cbMultiByte,
_Out_opt_ LPWSTR lpWideCharStr,
_In_ int cchWideChar
);

其中参数codepage表示要以什么字符集进行转换,dwFlags参数一般为0,lpMultiByteStr参数表示指向待转换字符串的指针,cbMultiByte参数表示以字节为单位表示的lpMultiByteStr参数的字节大小。lpWideCharStr参数表示指向的转换后的结果字符串的指针,cchWideChar参数表示转换后的字符串的字符数,如果cchWideChar参数设置为0,则MultiByteToWideChar 函数将返回实际转换后的字符串的字符数。

根据以上的分析,可以使用如下的代码实现字符的Unicode编号到UTF-8编码的相互转换

Public Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, _
ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, _
ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, _
ByVal lpUsedDefaultChar As Long) As Long
Public Declare Function MultiByteToWideChar Lib "kernel32.dll" (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 Const CP_UTF8 = 65001
Public Const CP_ACP = 0

Sub QQ1722187970()
    'unicode 转 utf-8
    '定义要转换的字符串变量
   Dim str1 As String
   str1 = "我   sadfa\sadf和asdf"
   '定义一个变量存储接收实际转换后的字符的字节数
   Dim bByte As Long
   '先调用WideCharToMultiByte函数获取缓冲区字节数
   bByte = WideCharToMultiByte(CP_UTF8, 0, StrPtr(str1), Len(str1), 0, 0, 0, 0)
   Debug.Print bByte
   '定义一个字节数组变量存储转换后的字符字节
   Dim arr() As Byte
   ReDim arr(bByte - 1)
   '再次调用WideCharToMultiByte函数填充字节到arr数组中
   WideCharToMultiByte CP_UTF8, 0, StrPtr(str1), Len(str1), VarPtr(arr(0)), bByte, 0, 0
   '遍历字节验证16进制值,可以将字符输入文本文件另存为UTF-8,用二进制查看器打开验证对比
   For k = 0 To UBound(arr)
       Debug.Print VBA.Hex(arr(k))
   Next k
   
   'utf-8 转 unicode
    '定义接受转换后的字符串变量
    Dim str2 As String
    '定义存储实际转换后的字符串字符数的变量
    Dim lCount As Long
    '先调用MultiByteToWideChar函数获取实际转换后的字符串字符数
    lCount = MultiByteToWideChar(CP_UTF8, 0, VarPtr(arr(0)), bByte, StrPtr(str2), 0)
    '然后填充缓冲区
    str2 = Space(lCount)
    '再次调用MultiByteToWideChar函数填充到字符串变量str2中
    MultiByteToWideChar CP_UTF8, 0, VarPtr(arr(0)), bByte, StrPtr(str2), lCount
    '输出转换后的字符串
    Debug.Print str2
End Sub

 

 

       

发表评论