ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 20875|回复: 44

[原创] [原创]中文小写转阿拉伯数字自定义函数

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2013-1-20 20:43 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:自定义函数开发
本帖最后由 时光鸟 于 2013-3-12 11:01 编辑

    大家因为财务工作等需要,平时用得最频繁的就是阿拉伯数字与中文大写之间的转化,现在网络上都有比较简捷高效的代码,甚至有高人用四行代码就解决了阿拉伯数字转中文大写的问题。
    从规律的角度来看,阿拉伯数字转中文小写也好,转中文大写也罢,我认为都相对比较容易,但是中文大写、小写转阿拉伯数字相对就要麻烦一些,尤其是中文小写,规律性较差,随意表达性大,转阿拉伯数字相以就要麻烦一点,再加上可能平时大家用得不多的原因,中文小写转阿拉伯数字的代码并不多。前一阵本人正好要用,找了一圈也没找到现成的相对完美一点的代码,于是想着自己着手来写一个,也就有了以下的这个函数,虽然代码看上去长了一点(没什么高深的东西,都是字符的简单处理,效率不是问题),但自认为相对来说还是比较完美的,也有一定的纠错转化能力。在对一些BUG进行纠正后,现公布出来,有需要的可以拿去用。转化效果看图片:

未命名.jpg

  1. Private Function toNum(myStr)
  2. '==========================================================
  3. '中文小写转阿拉伯数字函数
  4. 'Writen by 时光鸟
  5. '2012-12-24 于 武汉
  6. 'ver 1.9 beta (update 2013-1-12)
  7. '*改进极个别情况最右侧数量级的右侧为非转化文本时的转化Bug
  8. 'ver 1.8 beta (update 2012-12-30)
  9. '*改进少数情况下把"二"习惯用成"两"的时候的转化问题
  10. '*改进极个别情况下"〇"或"零"后直接跟数量级时的转化问题
  11. '*对小部分中文小写数字的不规范表达增加纠错转化功能
  12. '*增加对中文小写乘法口诀转化的功能支持
  13. 'ver 1.7 beta (update 2012-12-29)
  14. '*改进个别情况下需要在中文小写中同时使用〇和零时的转化问题
  15. '*优化代码结构,提升效率
  16. 'ver 1.6 beta (updat'e 2012-12-28)
  17. '*解决了首位只有数量级时这种简化表达方式转化不正确的Bug
  18. 'ver 1.5 beta (update 2012-12-27)
  19. '*解决了〇右侧有多个数量级时某种情况替换数量不正确的Bug
  20. 'ver 1.4 beta (update 2012-12-27)
  21. '*解决了〇右侧有多个数量级时替换数量不正确的Bug
  22. 'ver 1.3 beta (update 2012-12-26)
  23. '*解决了连续有多个数量级时转化不正确的Bug
  24. 'ver 1.2 beta (update 2012-12-26)
  25. '*解决了中文小写中某种情况下使用汉字“零”时转化不正确的Bug
  26. 'ver 1.1 beta (update 2012-12-25)
  27. '*解决了中文小写中含有〇的情况下时转化不正确的Bug
  28. 'ver 1.0 beta (update 2012-12-24)
  29. '*中文小写转阿拉伯数字正常表达方式转化函数
  30. '==========================================================

  31. Dim strG$, strL$, strN$, strZ$, findZ$, addZ$
  32. Dim i%, m%, n%, k%, Lv%, Rv%, Lx%, Rx%, R1%, R2%, Ly%, Ry%, Tx%
  33. strG = "十百千万亿"
  34. strL = "一二三四五六七八九"
  35. strN = "123456789"
  36. strZ = "〇零"
  37. If myStr = "" Then Exit Function
  38. While (InStr(myStr, Left(strZ, 1)) + InStr(myStr, Right(strZ, 1)) > 0)
  39.     Lv = InStr(myStr, Left(strZ, 1))
  40.     Rv = InStr(myStr, Right(strZ, 1))
  41.     If Lv > 0 Then If Rv = 0 Or Rv > Lv Then findZ = Left(strZ, 1)
  42.     If Rv > 0 Then If Lv = 0 Or Lv > Rv Then findZ = Right(strZ, 1)
  43.     m = InStr(myStr, findZ)
  44.     If m < Len(myStr) And InStr(strG, Mid(myStr, m + 1, 1)) Then
  45.        myStr = Left(myStr, m) & "一" & Mid(myStr, m + 1)
  46.     End If
  47.     If Mid(myStr, m - 1, 1) <> "" Then Lx = InStr(strG, Mid(myStr, m - 1, 1)) Else Lx = 0
  48.     If Mid(myStr, m + 2, 1) <> "" Then R1 = InStr(strG, Mid(myStr, m + 2, 1)) Else R1 = 0
  49.     If Mid(myStr, m + 3, 1) <> "" Then R2 = InStr(strG, Mid(myStr, m + 3, 1)) Else R2 = 0
  50.     If R2 = 5 Then Rx = R1 + R2 + 3 Else Rx = R1 + R2
  51.     If Lx > 0 And Lx < R1 Then Rx = 0
  52.     If Lx > R1 And Lx < R2 Then Rx = R1
  53.     If Lx = 5 Then Lx = Lx + 3
  54.     If Lx = 0 And Rx = 0 Then Lx = 2
  55.     myStr = Replace(myStr, findZ, Mid(10 ^ (Lx - Rx - 1), 2), 1, 1)
  56. Wend
  57. Do
  58.   If Len(myStr) < 2 Then Exit Do
  59.   If Mid(myStr, n + 1, 1) <> "" Then Ly = InStr(strG, Mid(myStr, n + 1, 1)) Else Ly = 0
  60.   If Mid(myStr, n + 2, 1) <> "" Then Ry = InStr(strG, Mid(myStr, n + 2, 1)) Else Ry = 0
  61.   If Ly > 0 And Ry > 0 Then
  62.      If Ly = 5 Then addZ = Mid(10 ^ (Ly + 3), 2) Else addZ = Mid(10 ^ Ly, 2)
  63.      myStr = Left(myStr, n + 1) & addZ & Mid(myStr, n + 2)
  64.      n = n + Len(addZ)
  65.   Else
  66.      n = n + 1
  67.   End If
  68. Loop Until (n = Len(myStr) - 1)
  69. If Len(myStr) > 3 And InStr(strL, Left(myStr, 1)) * InStr(strL, Mid(myStr, 2, 1)) Then
  70.    If Len(myStr) = 4 And Mid(myStr, 3, 1) = "得" Then myStr = Left(myStr, 1) & "×" & Replace(Mid(myStr, 2), "得", "=")
  71.    If Len(myStr) < 6 And InStr(strL, Mid(myStr, 3, 1)) > 0 And InStr(strG, Mid(myStr, 4, 1)) > 0 Then
  72.       myStr = Left(myStr, 1) & "×" & Mid(myStr, 2, 1) & "=" & Mid(myStr, 3)
  73.    End If
  74. End If
  75. If InStr(myStr, "两") > 0 Then myStr = Replace(myStr, "两", "二")
  76. If InStr(strG, Left(myStr, 1)) > 0 Then myStr = "一" & myStr
  77. If Len(myStr) > 1 Then
  78.    For i = Len(myStr) - 1 To 1 Step -1
  79.       k = InStr(strG, Right(myStr, 1))
  80.       If k = 5 Then myStr = myStr & Mid(10 ^ (k + 3), 2) Else If k > 0 Then myStr = myStr & Mid(10 ^ k, 2)
  81.       If k = 0 Then
  82.          Tx = InStr(strG, Mid(myStr, i, 1))
  83.          If Tx > 0 And InStr(strL, Mid(myStr, i + 1, 1)) = 0 And Mid(myStr, i + 1, 1) <> "0" Then
  84.             If Tx = 5 Then addZ = Mid(10 ^ (Tx + 3), 2) Else addZ = Mid(10 ^ Tx, 2)
  85.             myStr = Left(myStr, i) & addZ & Mid(myStr, i + 1)
  86.          End If
  87.      End If
  88.    Next i
  89. End If
  90. For i = 1 To Len(strL)
  91.    If i <= Len(strG) And InStr(myStr, Mid(strG, i, 1)) Then myStr = Replace(myStr, Mid(strG, i, 1), "")
  92.    If InStr(myStr, Mid(strL, i, 1)) > 0 Then myStr = Replace(myStr, Mid(strL, i, 1), Mid(strN, i, 1))
  93. Next i
  94. toNum = myStr
  95. End Function
复制代码



补充内容 (2013-6-17 11:19):
修正升级后的Ver2.0 版就移步 6 楼,感谢excelhome论坛"星语心愿"朋友的反馈意见!

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-6-14 10:50 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
终于找到了! 太好了,不过仍得加一句:On Error Resume Next'才能通过。容错方面可能还需大量各类型数据测试才更完善。
这么好的函数怎么没人顶呢。支持原创!

点评

顶的人少说明使用面窄。  发表于 2013-6-14 10:59

TA的精华主题

TA的得分主题

发表于 2013-6-14 11:34 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-6-16 12:16 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
aman1516 发表于 2013-6-14 10:50
终于找到了! 太好了,不过仍得加一句:On Error Resume Next'才能通过。容错方面可能还需大量各类型数据测试 ...

这个使用面是比较窄,我也是在网上找了好久没找到好用的,才想着要自己写一个用

TA的精华主题

TA的得分主题

发表于 2013-6-17 01:30 | 显示全部楼层
岔河十七组,草坪二十一组等就不对了。还有,可以写成代码吗?不要写成自定义函数。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-6-17 11:14 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 时光鸟 于 2013-6-17 12:04 编辑
星语心愿 发表于 2013-6-17 01:30
岔河十七组,草坪二十一组等就不对了。还有,可以写成代码吗?不要写成自定义函数。

已确认问题的存在,现已修正!(原来没打算支持中文小写数字与普通中文混杂这种情况的,呵呵)
自定义函数代码如下,请测试!
自定义函数用起来是最方便,如果想用做过程,写个sub调用就行了,sub调用方式请下载附件测试!如有问题请及时回复,感谢excelhome论坛"星语心愿"朋友的反馈!
QQ图片20130617111654.jpg

  1. Private Function toNum(myStr)
  2. '==========================================================
  3. '中文小写转阿拉伯数字函数
  4. 'Writen by 时光鸟
  5. '2012-12-24 于 武汉

  6. 'ver 2.0 beta (update 2013-6-17)
  7. '*改进数量级左侧为非转化文本时的转化Bug(感谢excelhome论坛"星语心愿"朋友的反馈)
  8. 'ver 1.9 beta (update 2013-1-12)
  9. '*改进极个别情况最右侧数量级的右侧为非转化文本时的转化Bug
  10. 'ver 1.8 beta (update 2012-12-30)
  11. '*改进少数情况下把"二"习惯用成"两"的时候的转化问题
  12. '*改进极个别情况下"〇"或"零"后直接跟数量级时的转化问题
  13. '*对小部分中文小写数字的不规范表达增加纠错转化功能
  14. '*增加对中文小写乘法口诀转化的功能支持
  15. 'ver 1.7 beta (update 2012-12-29)
  16. '*改进个别情况下需要在中文小写中同时使用〇和零时的转化问题
  17. '*优化代码结构,提升效率
  18. 'ver 1.6 beta (updat'e 2012-12-28)
  19. '*解决了首位只有数量级时这种简化表达方式转化不正确的Bug
  20. 'ver 1.5 beta (update 2012-12-27)
  21. '*解决了〇右侧有多个数量级时某种情况替换数量不正确的Bug
  22. 'ver 1.4 beta (update 2012-12-27)
  23. '*解决了〇右侧有多个数量级时替换数量不正确的Bug
  24. 'ver 1.3 beta (update 2012-12-26)
  25. '*解决了连续有多个数量级时转化不正确的Bug
  26. 'ver 1.2 beta (update 2012-12-26)
  27. '*解决了中文小写中某种情况下使用汉字“零”时转化不正确的Bug
  28. 'ver 1.1 beta (update 2012-12-25)
  29. '*解决了中文小写中含有〇的情况下时转化不正确的Bug
  30. 'ver 1.0 beta (update 2012-12-24)
  31. '*中文小写转阿拉伯数字正常表达方式转化函数发布
  32. '==========================================================

  33. Dim strG$, strL$, strN$, strZ$, findZ$, addZ$
  34. Dim i%, m%, n%, k%, Lv%, Rv%, Lx%, Rx%, R1%, R2%, Ly%, Ry%, Tx%, flagP%
  35. strG = "十百千万亿"
  36. strL = "一二三四五六七八九"
  37. strN = "123456789"
  38. strZ = "〇零"
  39. If myStr = "" Then Exit Function
  40. While (InStr(myStr, Left(strZ, 1)) + InStr(myStr, Right(strZ, 1)) > 0)
  41.     Lv = InStr(myStr, Left(strZ, 1))
  42.     Rv = InStr(myStr, Right(strZ, 1))
  43.     If Lv > 0 Then If Rv = 0 Or Rv > Lv Then findZ = Left(strZ, 1)
  44.     If Rv > 0 Then If Lv = 0 Or Lv > Rv Then findZ = Right(strZ, 1)
  45.     m = InStr(myStr, findZ)
  46.     If m < Len(myStr) And InStr(strG, Mid(myStr, m + 1, 1)) Then
  47.        myStr = Left(myStr, m) & "一" & Mid(myStr, m + 1)
  48.     End If
  49.     If Mid(myStr, m - 1, 1) <> "" Then Lx = InStr(strG, Mid(myStr, m - 1, 1)) Else Lx = 0
  50.     If Mid(myStr, m + 2, 1) <> "" Then R1 = InStr(strG, Mid(myStr, m + 2, 1)) Else R1 = 0
  51.     If Mid(myStr, m + 3, 1) <> "" Then R2 = InStr(strG, Mid(myStr, m + 3, 1)) Else R2 = 0
  52.     If R2 = 5 Then Rx = R1 + R2 + 3 Else Rx = R1 + R2
  53.     If Lx > 0 And Lx < R1 Then Rx = 0
  54.     If Lx > R1 And Lx < R2 Then Rx = R1
  55.     If Lx = 5 Then Lx = Lx + 3
  56.     If Lx = 0 And Rx = 0 Then Lx = 2
  57.     myStr = Replace(myStr, findZ, Mid(10 ^ (Lx - Rx - 1), 2), 1, 1)
  58. Wend
  59. Do
  60.   If Len(myStr) < 2 Then Exit Do
  61.   If Mid(myStr, n + 1, 1) <> "" Then Ly = InStr(strG, Mid(myStr, n + 1, 1)) Else Ly = 0
  62.   If Mid(myStr, n + 2, 1) <> "" Then Ry = InStr(strG, Mid(myStr, n + 2, 1)) Else Ry = 0
  63.   If Ly > 0 And Ry > 0 Then
  64.      If Ly = 5 Then addZ = Mid(10 ^ (Ly + 3), 2) Else addZ = Mid(10 ^ Ly, 2)
  65.      myStr = Left(myStr, n + 1) & addZ & Mid(myStr, n + 2)
  66.      n = n + Len(addZ)
  67.   Else
  68.      n = n + 1
  69.   End If
  70. Loop Until (n = Len(myStr) - 1)
  71. If Len(myStr) > 3 And InStr(strL, Left(myStr, 1)) * InStr(strL, Mid(myStr, 2, 1)) Then
  72.    If Len(myStr) = 4 And Mid(myStr, 3, 1) = "得" Then myStr = Left(myStr, 1) & "×" & Replace(Mid(myStr, 2), "得", "=")
  73.    If Len(myStr) < 6 And InStr(strL, Mid(myStr, 3, 1)) > 0 And InStr(strG, Mid(myStr, 4, 1)) > 0 Then
  74.       myStr = Left(myStr, 1) & "×" & Mid(myStr, 2, 1) & "=" & Mid(myStr, 3)
  75.    End If
  76. End If
  77. If InStr(myStr, "两") > 0 Then myStr = Replace(myStr, "两", "二")

  78. If InStr(strG, Left(myStr, 1)) > 0 Then myStr = "一" & myStr
  79. While (flagP <= Len(myStr) - 2)
  80.   flagP = flagP + 1
  81.   If InStr(strG, Mid(myStr, flagP + 1, 1)) > 0 And InStr(strG & strL & strZ & strN & "1234567890", Mid(myStr, flagP, 1)) = 0 Then
  82.      myStr = Left(myStr, flagP) & "一" & Mid(myStr, flagP + 1)
  83.   End If
  84. Wend

  85. If Len(myStr) > 1 Then
  86.    For i = Len(myStr) - 1 To 1 Step -1
  87.       k = InStr(strG, Right(myStr, 1))
  88.       If k = 5 Then myStr = myStr & Mid(10 ^ (k + 3), 2) Else If k > 0 Then myStr = myStr & Mid(10 ^ k, 2)
  89.       If k = 0 Then
  90.          Tx = InStr(strG, Mid(myStr, i, 1))
  91.          If Tx > 0 And InStr(strL, Mid(myStr, i + 1, 1)) = 0 And Mid(myStr, i + 1, 1) <> "0" Then
  92.             If Tx = 5 Then addZ = Mid(10 ^ (Tx + 3), 2) Else addZ = Mid(10 ^ Tx, 2)
  93.             myStr = Left(myStr, i) & addZ & Mid(myStr, i + 1)
  94.          End If
  95.      End If
  96.    Next i
  97. End If
  98. For i = 1 To Len(strL)
  99.    If i <= Len(strG) And InStr(myStr, Mid(strG, i, 1)) Then myStr = Replace(myStr, Mid(strG, i, 1), "")
  100.    If InStr(myStr, Mid(strL, i, 1)) > 0 Then myStr = Replace(myStr, Mid(strL, i, 1), Mid(strN, i, 1))
  101. Next i
  102. toNum = myStr
  103. End Function
复制代码


中文小写转数字V2.0【时光鸟原创】.rar

20.38 KB, 下载次数: 308

TA的精华主题

TA的得分主题

发表于 2013-6-17 13:10 | 显示全部楼层
改得很及时啊,谢谢了。在试呢,如果有问题再向您请教了。

TA的精华主题

TA的得分主题

发表于 2013-6-17 16:21 | 显示全部楼层
不断完善了,“○”这里出错了,没转换过来:
桃六百○六
二千○一
二千○一十
二千○一十三

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-6-17 18:29 | 显示全部楼层
本帖最后由 时光鸟 于 2013-6-17 18:30 编辑
aman1516 发表于 2013-6-17 16:21
不断完善了,“○”这里出错了,没转换过来:
桃六百○六
二千○一

呵呵,你用这个”〇“ 试试,你的用法不规范,正规的用法是数字键盘中的专用”〇“ 符号(见下图),而不是word,excel中的特殊字符圈圈”○“,把两放在一起一比较就出来了”〇○“,呵呵!

QQ图片20130617182707.jpg

TA的精华主题

TA的得分主题

发表于 2013-6-17 19:27 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
Good!  是数字中的“○”,可能输入法版本不同,或半角全角的问题。不管怎样,用替换或复制方法,只要数据中的“○”与代码中的“○”一致就OK。太强了!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-18 14:50 , Processed in 0.039712 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表