用AutoHotkey一键处理word域,实现类似vlookup查找并处理数据,比如数字转大写金额

效果

实现整个文档,根据数字批量生成大写金额的功能,如

首付款金额(¥1000元)
尾款金额(¥2000元)

一键转成

首付款金额壹仟元整(¥1000元)
尾款金额贰仟元整(¥2000元)

思路

  1. word插入Excel表,借Excel公式生成大写金额,参考数字自动转换为中文大写金额,效果可以,后来不知道什么原因出现Excel表出错,就放弃了
  2. 选中数字金额并标记为书签,大写金额位置插入,根据书签的内容转成大写金额写到域,也有两种方式
    1. 用word内置的域代码域chinesenum2: 代码类似REF zhifu1 \* chinesenum2,其中zhifu1是书签名。问题是的显示文字是,不知道能否更改,所以也放弃了
    2. 用脚本更新域的值,具体步骤如下

步骤

  1. 给对应的数字添加书签:选中数字,按Ctrl-Shift-F5插入书签→输入名称如zhifu1→点击添加
  2. 大写金额处插入域:按Ctrl-F9并输入对应的书签名称如zhifu1,这样域和书签就可以关联起来。
  3. 运行ahk代码即可完成
  4. 重要说明:修改书签的数字时,不要从末尾修改,比如在100后面加23变成10023,但书签认为数字还是100,所以要在中间插入数字
ad := ComObjActive("Word.application").ActiveDocument
;获取所有书签和值
objBM := map()
loop(ad.Bookmarks.count) {
    bm := ad.Bookmarks.item(A_Index)
    objBM[bm.name] := bm.range.text
}
;遍历域
loop(ad.fields.count) {
    f := ad.fields.item(A_Index)
    code := trim(f.code.text)
    if (objBM.has(code)) ;找到匹配的书签
        f.result.text := toAmount(number(objBM[code])) ;显示大写值
}

;数字转大写金额
;作者:sikongshan
;更新日期:2022年09月14日
;限制:因为不涉及到大数值计算,可以到20位或者更高,但是中文转回阿拉伯的时候,超过17位数值则会有问题(受限于ahk计算),下次考虑拼接方式避免
toAmount(num) {
    sNum := string(num)
    arrNum := StrSplit(sNum,".")
    if (strlen(arrNum[1])>17) ;设定20位,
        return sNum
    res:=""
    objNum := {0:"零",1:"壹",2:"贰",3:"叁",4:"肆",5:"伍",6:"陆",7:"柒",8:"捌",9:"玖"}
    objDanwu := {1:"元",2:"拾",3:"佰",4:"仟",5:"万",6:"拾",7:"佰",8:"仟",9:"亿",10:"拾",11:"佰",12:"仟",13:"兆",14:"拾",15:"佰",16:"仟",17:"万",18:"拾",19:"佰",20:"仟"}
    objDicimal := {1:"角",2:"分",3:"毫",4:"厘"}
    ;整数部分
    loop(strlen(arrNum[1]))
        res := objNum[substr(arrNum[1], -A_Index, 1)] . objDanwu[A_Index] . res
    loop 3 {
        res:=RegExReplace(res,"零(拾|佰|仟)","零")
        res:=RegExReplace(res,"零{1,3}","零")
        res:=RegExReplace(res,"零(?=(兆|亿|万|元))","")
        res:=RegExReplace(res,"亿零万","亿")
        res:=RegExReplace(res,"兆零亿","兆")
    }
    ;小数部分
    if(arrNum.length > 1) {
        DP := arrNum[2]
        res .= "零"
        loop parse, DP {
            A_LoopField
            if(A_Index>5)
                break
            if(A_LoopField=0)
                continue
            res .= format("{1}{2}", objNum[A_LoopField],objDicimal[A_Index])
        }
    } else {
        res .= "整"
    }
    return res
}
posted @ 2025-02-12 13:13  火冷  阅读(97)  评论(0)    收藏  举报