惯例先说下背景。
生产、研发业务上往往使用大量word和excel文档来作为资料载体,如操作规程、控制手册、卡片……,这些文档会反复使用到一些设备、工艺等参数数据。参数属性主要是名称、编码、正常范围、报警上下限、单位等,这些参数对应的属性值,是会发生变化的。
文档中使用参数的地方,中文的表达方式多种多样,人来阅读文档没啥问题。但是引用参数的文档,实际没有存在“物理”上的关联关系。当参数属性值调整时,需要更新相应的文档,这时候就出现问题了。因为没有关联关系,没有技术手段自动识别,只能人工一点点改文档,这工作量是相当大,找到需要修改的地方就不容易,并且很容易发生漏改、误改问题,从而导致不一致的问题。
很明显,这是一个模板技术的应用场景。解决该问题,常见的方案是通过软件系统来实现,实现思路如下:
1.对参数进行统一管理,作为管理的基础数据。实现上没什么好说的,常规的应用开发,增删改查,加其他必要的逻辑处理,可通过工作流实现参数的修订与审批,可通过平台实现数据权限控制。
2.对文档进行规范化处理,形成文档模板,通过模板技术,将参数数据填充进模板,生成最终的文档。简单点说,就是把文档中的使用参数的部分,使用约定好的标记来占位,如${HABC1234.name},然后程序替换。HABC1234是参数的唯一性编码,name是参数对应的名称。
3.引入全文搜索技术,使用elastic search,对文档建立索引,实现按参数编码检索该参数被哪些文档文档使用到了(这里实际检索的是文档模板,而不是最终的文档,模板里有参数编码信息,最终文档已经被数据替换了)。
以上基本能解决需求了,在这基础上,还可以做一些小工作,让业务用户使用起来更方便,例如:通过扩展参数属性方式,对参数的基本属性进行组合,如将常用的两个属性,名称和编码组合到一块去,文档中使用时,直接引用这个新属性HABC1234.nameAndCode,而不需要在文档里写{HABC1234.nameAndCode},而不需要在文档里写HABC1234.nameAndCode,而不需要在文档里写{HABC1234.name} {HABC1234.code}。
同理,可以进一步设置一些预置的格式化片段,如
编码:HABC1234
名称:风机温度
范围:20-50摄氏度
同样的,也可以对属性进行运算,例如,求合理范围的平均值。
通过软件系统解决有诸多优点,比如使用简单、管理规范、可扩展性高。但不得不说,软件系统也有一些缺点,比如成本高,交付周期比较长。上面提到,软件系统是常见方案,但放到特定的背景下未必是最优方案。这里说一种轻量级的解决方案,即通过office自身功能来实现。
开始的思路,依然是采用模板,使用office自带的脚本语言 vba来实现占位符的替换。在word中,占位符如何生成,找了下域对象,发现对应的对象。看来下标签,也不是干这事用的。经过长时间的搜索,发现word的一个生僻功能-链接,可以比较好的解决数据引用、关联和更新功能。说实话,这个功能以前从没用过,并且在word的菜单里找了半天,居然没有菜单与之对应。
实现思路如下:
1.使用excel作为参数的数据存储,相当于软件系统中的“数据库”。
2.引用到参数的文档,通过office自身功能,链接到excel的单元格。
3.参数数据更新后,通过office文档的更新链接功能来实现文档同步更新。
下面来说说具体链接怎么用。
先做一个存储参数数据的excel表,命名为“工艺参数清单.xls”,输入示例数据如下:
选中其中A1单元格,复制。
然后新建一个word文档,命名为“操作规程说明.docx”,打开,在word工具栏中选择“选择性粘贴”
在弹出窗口中将默认选中的“粘贴”,变更为“粘贴链接”,选择“无格式文本”,确定,效果如下:
这时候,excel单元格内容已经输出到word文档中了,并且关联了源数据,默认设置是自动更新,当excel里内容变化后,excel和word都处于打开状态,word文档会自动更新。不过当word文档处于关闭状态,这个更新还是需要一个触发,打开word文档后,会自动检测是否有链接,如有,则弹出对话框选择,选择是即可完成更新。
按照上述操作,在word文档中,已经建立了到excel单元格中数据的关联,这个连接实际保存在word文档中,也就是单向链接,excel中不知道被哪些文档引用过,但word中知道自己引用的数据源是哪个。
在链接上右键点击,可出现菜单“更新链接”,以及“链接的工作表对象”,前者作用是看名字即可,后者可继续展开二级菜单,选择编辑链接 或 打开链接 ,会自动打开对应的excel表。选择“链接…”,则会显示本文档使用的所有链接清单。
从上图可以看出,链接的实现机制是关联了磁盘上的excel文件,并且使用了绝对路径,单元格的引用遵循了sheet名+行号+列号的方式。
以上操作,也适用于excel类型的文件,链接到另外一个excel文件的单元格,操作上略有差异,比如选择性粘贴的时候,弹出的对话框中粘贴链接在左下角,如下图:
粘贴后,可看到该链接的形式如下:
查看所有链接,在工具栏里找到了对应功能按钮来打开对话框。
通过以上方式,实际已经实现了维护参数基础数据,并保持文档自动更新的目的。
但是,仅仅做这些其实还不够,需要一些额外的工作来弥补这种轻量级实现方式的一些不足。
首先,关联是引用了绝对路径,因此要求作为数据源的excel文件,磁盘位置和文件名均需要保持不变。特别是多人协作的时候,需要每个人的磁盘存放位置也一致,比如都在C盘或D盘建一个根目录来统一存放,这点需要从管理上来规范。
其次,关联是单向的,如果是参数文件修改了,其实并不知道哪些文档引用了这些参数,总不能把文档全部手工打开一遍,来完成更新吧?文档数量如果是几千份,是不是就疯掉了?这时候,就需要使用vba脚本,写个循环,遍历所有文档,调用更新链接操作,这个脚本我没有实际写,但关键的技术问题做了个验证。
Sub updateField()Dim aField As FieldDim aStory As Range''' Update all fields in the documentFor Each aStory In ActiveDocument.StoryRangesFor Each aField In aStory.FieldsaField.UpdateMsgBox (aField.Code)Next aFieldNext aStoryEnd Sub
以上测试代码能正常完成数据更新,结合目录文件遍历就能实现一个完整的脚本了。从这里也可以看出,链接,本质上是word中域的概念,跟目录、页码等是一回事。
上一篇:C语言综合练习6:制作贪吃蛇
下一篇:近期 NOI\(P\) 总结