2019.03.15更新:已经将个人做好的完整docm 代码附在文后,先上图。
记录几个开发过程中遇到的难点和注意点。
- Word中添加ActiveX控件,如输入框,需要放置在 文本框 中,或者放置在 正文流中。
- 本docm因需要和背景底图搭配,所以需要调整 Activek输入框控件的上下和左右位置,几次使用 放置文本框的办法没有成功。最后是放置在 空白的正文流中去的。
- 如何调整 正文流中的 ActiveX输入控件的上下位置和左右位置。
- 上下位置:粗调,打多个换行符。若要精确调整,设置上面的行的行距为固定值,1磅。
- 左右位置:粗调,直接打多个空格。微调,设置字体大小为1,使劲打空格。
- 控件的宽度和高度调节:“开发工具”-激活“设计模式”,选中控件,点击“属性”,修改Width和 Height,分别对应宽度和高度。
- 控件的事件:在“设计模式”下,双击该控件,VB编辑器会自动为我们生成 Change 事件。如果要手动编写 其它事件代码,则需要 在VB编辑器界面,代码编写区域的顶部的左侧(控件名称列表)和右侧(事件列表),分别选择 控件 和 事件名称。选择后,VB编辑器的代码编写区域会自动出现事件函数代码。
- VB语法:VB语法较奇葩。有C语言经验的要避免利用C经验去想当然。提几个:赋值与比较均是单等号 = ,不等于是 <>或><,而非 != ,代码换行要紧跟下划线_ ,单行注释是一个单引号打头。
- VB语法:VB中最大的奇葩。让你开开眼:
Dim a = 100 \ 1.5
Dim b = 100 \ 2.5
'猜猜 a 和 b 是多少
如果你没有VB经验,你绝对猜不到 ,a 和 b 居然都是 50 !这TM还是严谨的计算机科学么???而其中原理如下:
首先,左斜线 / 是 VB的一般除法,而右斜线 \ ,就比较神奇了。它一般也叫‘整除,但不是数学上的整除。也不是常规的 C语言概念里的 整除,而是获得整数的除法。简单说就是 \ 运算符会自动将左、右的值,先转换为整数,再进行整除运算。而如何将该运算符 左右的值,转换为 整数,就更更更奇葩了!
VB中小数转换整数的规则:当小数部分恰好为 0.5 时,VB会将它转换为最接近的 [[ 偶数值 ]]。多么奇葩的规则。1.5 被硬生生的转换成了 2,而2.5被强制扭曲成了 2 !这就造成了上面 a 和 b都是50的奇怪结果。
如果对我的观点存疑,我也没有好办法,我没有找到官方描述,只搜到了一个相关的官方表述。这就是在VB中针对整除的“四舍六入,五留双”的顺口溜的由来。(该顺口溜仅适用于VB语言,且仅适用于VB的整除运算规则)
在MSDN有个官方的关于 Fix 函数 和 Int 函数的相关表述,我觉得可以解释为何 VB会如此转换:
当小数部分恰好为 0.5 时,Cint 和 CLng 函数会将它转换为最接近的 [[ 偶数值 ]]
例如,0.5 转换为 0、1.5 转换为 2
Cint 和 CLng 函数不同于 Fix 和 Int 函数,Fix 和 Int 函数会将小数部分截断而不是四舍五入。
并且 Fix 和 Int 函数总是返回与传入的数据类型相同的值。
下面是正文。
应公司财务人员的请求,需在Word中做个:输入阿拉伯数字,自动转换成大写,并填充到Word控件中对应的亿、万、千控件格子的功能,特研究VB。
下面是我在网上搜集的将 阿拉伯数字转换为 中文大写的代码,注释为我添加,方便理解,特记录在此。
有机会把带有宏的原Word也发布,供大家参考。
Function mychange(ByVal Myinput)
'MyinputA 去除空白符且变成整数(去掉小数)后的数字串
'MyinputB 翻转后的数字串
'MyinputC 转换为大写的金额
Dim Temp, TempA, MyinputA, MyinputB, MyinputC
Dim Place As String
Dim J As Integer
Place = "分角元拾佰仟万拾佰仟亿拾佰仟万"
shuzi1 = "壹贰叁肆伍陆柒捌玖"
shuzi2 = "整零元零零零万零零零亿零零零万"
qianzhui = ""
If Val(Myinput) = 0 Then Myinput = 0
If Myinput = "" Then Myinput = 0
If Myinput < 0 Then qianzhui = "负"
'将小数转为整数,去掉小数点, 123.45 -> 12345
Myinput = Int(Abs(Myinput) * 100 + 0.5)
If Myinput > 99999999999# Then
mychange = "输入有误:数字过大"
Exit Function
End If
If Myinput = 0 Then
mychange = "零元零分"
Exit Function
End If
MyinputA = Trim(Str(Myinput))
shuzilong = Len(MyinputA)
'翻转金额,12345->54321
For J = 1 To shuzilong
MyinputB = Mid(MyinputA, J, 1) & MyinputB
Next
'1把阿拉伯数字转为大写, 54321, 5->伍
'2将数字和对应位置的单位拼接,伍肆叁贰壹,伍->伍分
'3拼接时翻转回来, 肆角伍分
'注意0:从 shuzi2 得到单位,而不是从 Place
' 12.10->1210->0121-> 整 壹角 贰元 壹拾
' 10.88->1088->8801->捌分 捌角 元 壹拾
' 30800.25->3080025->5200803->..贰角 元 零 捌佰 零 叁万
' ->叁万 零 捌佰 零 元 贰角...
For J = 1 To shuzilong
Temp = Val(Mid(MyinputB, J, 1))
If Temp = 0 Then
MyinputC = Mid(shuzi2, J, 1) & MyinputC
Else
MyinputC = Mid(shuzi1, Temp, 1) & Mid(Place, J, 1) & MyinputC
End If
Next
'细节:处理零
'10.46 壹拾零元... -> 壹拾元
'10 1234.56 壹拾零万... -> 壹拾万
'10 1234 5678.56壹拾零亿... -> 壹拾亿
'30800.25 上一步得到:叁万 零 捌佰 零 元 贰角伍分
' 注意并不是:叁万 零仟 捌佰 零拾 零元 贰角伍分
'30800.25 叁万零捌佰(零)元.. -> 叁万零捌佰 元..
shuzilong = Len(MyinputC)
For J = 1 To shuzilong - 1
If Mid(MyinputC, J, 1) = "零" Then
Select Case Mid(MyinputC, J + 1, 1)
Case "零", "元", "万", "亿", "整":
MyinputC = left(MyinputC, J - 1) & Mid(MyinputC, J + 1, 30)
J = J - 1
End Select
End If
Next
'贰亿万... -> 贰亿...
shuzilong = Len(MyinputC)
For J = 1 To shuzilong - 1
If Mid(MyinputC, J, 1) = "亿" And Mid(MyinputC, J + 1, 1) = "万" Then
MyinputC = left(MyinputC, J) & Mid(MyinputC, J + 2, 30)
Exit For
End If
Next
mychange = qianzhui & Trim(MyinputC)
End Function
最后我把自己的完整 docm 带有VB代码的完整文件(程序)附上,内有注释。请使用盗版 office 打开(笑),请勿使用正版WPS。最优适配Office2007,其它高于Office2007的均可使用,只是样式不再对齐。Office2003不支持。
CSDN站内下载。我不想要金币的,不知道怎么取消金币,我上传的时候没有选需要金币。
参考资料: