律师工作中,经常遇到使用相同模板制作大量同类型文件的场景,例如群体性诉讼案件的法律文书,或某些非诉讼业务中合同、通知、回执之类文件。
在文件结构完全一致,仅有特定位置的信息、数据不同的情况下,利用Office组件的邮件合并功能,可以实现文件的快速批量生成。就此,已经有一些高手的教程流传,比如下面两篇:
邮件合并功能其实是Office中宏的一种具体应用,直接被作为预置功能固化在软件中。而宏是基于VBA(Visual Basic for Applications)实现的。对于略有基础的应用者,直接采用编程方式实现与预置组件类同的功能目标,有时会更加简单直接、灵活高效。
下面就介绍利用简单编程,实现与邮件合并相似的文本置换效果,从而批量生成法律文书的方法。
任务设定
某国企改制程序中,需根据职工安置方案设定的条件,生成全部职工的安置补偿合同,合同格式均相同,仅个人信息、数据不同。
软件环境
Windows 10, Office2016(Excel+Word)
操作步骤
1. 新建一个文件夹,随便命名,比如“VBA”。 打开文件夹,在根目录下新建一个docx文档,命名为“模板”;新建一个xlsx文档,随便命名,比如“批量生成”。
2. 编辑docx文档,起草模板的文本内容。这里的关键在于,每份文件之间的差异化信息,要用特定的字符标记出来,便于后面执行自动查找和替换。
这个文档中选择采用英文标记,因为这是一份纯中文的文件,英文单词在其中具有特异性,不会与文档中其他部分文字混淆,从而避免“误伤”的可能。举个例子:假定某份模板文档中用“工资”两个汉字作为待替换标记,由于它本身是一个常用词,如果在文档内其他(不需要替换的)文字内容中出现了这两个字,在自动生成的文件中也会被一并替换,造成错误。
完成后关闭文档。后面的自动生成步骤中,如果文档处于打开状态,可能无法被调用。
提示:示例文件内容乱写的,不要借鉴,否则造成执业事故后果自负……
3. 打开xlsx文档,在第一张表(sheet1)中编辑数据。数据列的内容与文档中需要替换的内容分别对应。
注意:第一行不要填有效数据,可以写标题,空着也行。因为后面的代码设定从第二行开始提取数据。
提示:这个示例表中D、E列的数值相同,是前面B、C两列的数据乘积,直接用公式生成;大小写的标准写法可以通过单元格格式设置实现。都是Excel的常规应用。
4. 切到“视图”菜单,点击“宏”标签。
5. 在弹出的对话框中给项目命名,随便填。然后点击“创建”。
6. 编程界面,右边红框内就是代码编辑区域。接下来,让我们一行一行写代码……
7. ——怎么可能。厚道如笔者,当然已经把代码准备好了。如下(重点部分加了详细注释,不再另外说明):
Sub production()
Dim mypath, docname, i, wApp '定义变量
MkDir ThisWorkbook.Path & "\批量生成" '在当前路径下创建名为“批量生成”的文件夹,用于存放生成的文件
mypath = ThisWorkbook.Path & "\批量生成\" '指定“mypath”(本例定义的工作路径)为“批量生成”文件夹
For i = 2 To [a1048576].End(xlUp).Row '指定后面执行的循环范围,从第2行开始,到最后一个非空单元格为止
docname = "补偿协议-" & Range("A" & i) & ".docx" '定义自动生成的文件名为“补偿协议-”+“A列i行的值(相应的姓名)”+“.docx”
FileCopy ThisWorkbook.Path & "\" & "模板.docx", mypath & docname '复制当前路径下的“模板.docx”文件到指定路径(就是“批量生成”文件夹),并按上述规则重命名
Set wApp = CreateObject("word.application") '调用word程序打开文件,执行后面操作
With wApp
.Visible = False
.Documents.Open mypath & docname '打开上面复制并重命名的文件
Do While .Selection.Find.Execute("name") '在文件中检索“name”字符串
.Selection.Text = Range("A" & i).Text '使用表格A列i行的值(即相应的姓名)替换找到的“name”字符串
.Selection.HomeKey Unit:=6 '光标置于文件开头
Loop '循环
'(直到找不到“name”为止,当前文档中所有“name”字符串都已被替换)
Do While .Selection.Find.Execute("seniority") '(下面都是一样的结构,就是分别用相应列中提取出来i行的值,替换各个预设的字符串,不重复)
.Selection.Text = Range("B" & i).Text
.Selection.HomeKey Unit:=6
Loop
Do While .Selection.Find.Execute("unit")
.Selection.Text = Range("C" & i).Text
.Selection.HomeKey Unit:=6
Loop
Do While .Selection.Find.Execute("compensation")
.Selection.Text = Range("D" & i).Text
.Selection.HomeKey Unit:=6
Loop
Do While .Selection.Find.Execute("inwords")
.Selection.Text = Range("E" & i).Text
.Selection.HomeKey Unit:=6
Loop
Do While .Selection.Find.Execute("status")
.Selection.Text = Range("F" & i).Text
.Selection.HomeKey Unit:=6
Loop
Do While .Selection.Find.Execute("id")
.Selection.Text = Range("G" & i).Text
.Selection.HomeKey Unit:=6
Loop
Do While .Selection.Find.Execute("phone")
.Selection.Text = Range("H" & i).Text
.Selection.HomeKey Unit:=6
Loop
Do While .Selection.Find.Execute("address")
.Selection.Text = Range("I" & i).Text
.Selection.HomeKey Unit:=6
Loop
Do While .Selection.Find.Execute("bank")
.Selection.Text = Range("J" & i).Text
.Selection.HomeKey Unit:=6
Loop
Do While .Selection.Find.Execute("account")
.Selection.Text = Range("K" & i).Text
.Selection.HomeKey Unit:=6
Loop
.Documents.Save
.Quit
End With
Next
Set wApp = Nothing
End Sub
复制以上代码,粘贴到代码编辑器内,替换原有全部内容。
8. 点击“保存”按钮,对当前工作存档。结果弹出一个对话框。
这是创建文件时的一个疏忽:默认的xlsx格式不支持在文件中保存宏。这毕竟是可执行的代码,有安全风险。早些年大名鼎鼎的“宏病毒”很多人应该还有印象,虽然如今已经不多见了。
也没关系,保存为支持宏的格式就行了。点击上面对话框中的“否”,在“保存类型”下拉选单中选择“Excel 启用宏的工作簿”,保存即可。
文件已经另存为支持宏的格式(扩展名为xlsm)。
9. 打开新保存的“批量生成.xlsm”文件。同样,点开“宏”标签,选定刚才创建的项目,点击“执行”按钮,代码开始运行。等上一会儿。
10. 运行完毕。当前路径下出现了“批量生成”文件夹。
打开新的文件夹,表格里共有10个人的数据,生成10份文档,都在这里。
随便打开一份,核对信息,无误。
扩展提示
实现特定字符串查找和替换功能的模块如图所示。
每个红框内是一个字符串的替换模块,蓝色下划线标出的是需改动的值。如果需要增加、减少、调整替换目标和内容,对代码做相应修改即可。
总结
重复一遍,这种方法的优点是:在文档和数据处理的直观性、便捷性方面表现更好(比如,像本例中这样自定义规则给批量生成的文件命名,用邮件合并似乎就实现不了),特别是需要替换的内容较多时,优势可能更为明显。
另外,如有能力增加或修订代码,还可以实现更多、更精确、更灵活的定制功能。
最后附上涉及的两个文件模板(无毒)。如果打开Excel表时,程序提示宏已被禁用,点击启用即可。
谢谢观赏(业界良心,此处可以有掌声)