在文章如何在vba中实现字符的Unicode编码与ANSI编码相互转换?中介绍了利用vba内置函数StrConv 实现字符的Unicode编码与ANSI编码的相互转换。
今天,介绍利用api函数WideCharToMultiByte和MultiByteToWideChar 实现字符的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
发表评论