高阶应用技巧有哪些内容 (高阶运用excel)

「高阶应用」利用API来实现中文简繁转换

Word里有一个简繁转换功能,很靓仔,一秒钟全文转换完毕

Excel中也有这个功能,不过是外置COM加载项的形式,用起来就没有Word里那么靓仔了

这个功能呢,说到底其实就一个API

声明如下:

Private Declare Function LCMapStringA Lib "kernel32" ( _
 ByVal Locale As Long, _
 ByVal dwMapFlags As Long, _
 ByVal lpSrcStr As String, _
 ByVal cchSrc As Long, _
 ByVal lpDestStr As String, _
 ByVal cchDest As Long) As Long

参数很简单:

第1个:Locale,代表语言环境,有简繁转换需求的场景,基本上不需要管这个参数

第2个:dwMapFlags,这个是转换目标的标识符,我们这里只需要关注两个

Const LCMAP_SIMPLIFIED_CHINESE = &H2000000 '繁体转简体

Const LCMAP_TRADITIONAL_CHINESE = &H4000000 '简体转繁体

第3个:源字符串指针

第4个:源字符串长度

第5个:目标字串指针

第6个:目标字串长度

说来说去,就第2个参数有用

但是呢,在调用的时候要注意,VB6的字符串的典型问题。

先看代码

Private Declare Function LCMapStringA Lib "kernel32" ( _
 ByVal Locale As Long, _
 ByVal dwMapFlags As Long, _
 lpSrcStr As Any, _
 ByVal cchSrc As Long, _
 lpDestStr As Any, _
 ByVal cchDest As Long) As Long
Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As String) As Long
Private Const LCMAP_SIMPLIFIED_CHINESE = &H2000000 '繁体转简体
Private Const LCMAP_TRADITIONAL_CHINESE = &H4000000 '简体转繁体
Function ConvertChinese(ByVal srcString As String, ByVal bSimplified As Boolean) As String
 Dim lngLength As Long
 Dim strBuffer As String
 lngLength = lstrlenA(srcString) '不使用lenB
 If lngLength = 0 Then GoTo lExit '不使用Exit Function
 strBuffer = Space(lngLength - 1)
 If bSimplified Then
 LCMapStringA 0&, LCMAP_SIMPLIFIED_CHINESE, ByVal srcString, lngLength, ByVal strBuffer, lngLength '转简体
 Else
 LCMapStringA 0&, LCMAP_TRADITIONAL_CHINESE, ByVal srcString, lngLength, ByVal strBuffer, lngLength '转繁体
 End If
 ConvertChinese = strBuffer
lExit:
End Function

调用也很简单:

Debug.Print ConvertChinese("中华人民共和国LoveLive", False)

输出结果:在我的垃圾笔记本上时间消耗大概是0.01毫秒

中華人民共和國LoveLive

这里做两处解释:

一、这里我用了lstrlenA这个API来计算长度,为啥不用len或者lenB呢,具体原因,你自己可以改了试试,这是VB妈妈的特征决定的,只有这样才行,要不然结果里就会有多余的字符串

有的人说,没关系,有多余的,我最后处理完,先处理一下再返回

还是那句话,您说得都对,您开心就好,我脸上笑嘻嘻,心里MMP

二、我的API改了声明,byval lpSrcStr As String改成了ByRef lpSrcStr As Any

这是为了提高效率,你说传字符串和传其指针到底哪一个效率高呢?

虽然由于VB妈妈的原因,这里也并没有传递字符串本身的指针,而是传递了字符串缓冲区的指针

但是这样也能快不一些

当然,也有些人说用W版的函数还能更快,好的,我也写了W版的

Private Declare Function LCMapStringW Lib "kernel32" ( _
 ByVal Locale As Long, _
 ByVal dwMapFlags As Long, _
 lpSrcStr As Any, _
 ByVal cchSrc As Long, _
 lpDestStr As Any, _
 ByVal cchDest As Long) As Long
Private Const LCMAP_SIMPLIFIED_CHINESE = &H2000000 '繁体转简体
Private Const LCMAP_TRADITIONAL_CHINESE = &H4000000 '简体转繁体
Function ConvertChinese(ByVal srcString As String, ByVal bSimplified As Boolean) As String
 Dim lngLength As Long
 Dim strBuffer As String
 lngLength = Len(srcString) '不使用lenB
 If lngLength = 0 Then GoTo lExit '不使用Exit Function
 strBuffer = Space(lngLength)
 If bSimplified Then
 LCMapStringW 0&, LCMAP_SIMPLIFIED_CHINESE, ByVal StrPtr(srcString), lngLength, ByVal StrPtr(strBuffer), lngLength '转简体
 Else
 LCMapStringW 0&, LCMAP_TRADITIONAL_CHINESE, ByVal StrPtr(srcString), lngLength, ByVal StrPtr(strBuffer), lngLength '转繁体
 End If
 ConvertChinese = strBuffer
lExit:
End Function

调用同上,时间消耗大概是上面的一半左右

也是两个地方简单解释:

一、这里少了一个API,为什么呢,因为W版的函数,就不需要VB妈妈代管AU<->UA转换了,所以算字符个数就可以了

二、因为现在是W版函数了,需要用StrPtr直接获取字符串的数据地址,为啥呢,因为没有AU转换了