如何更新Visio文档中的模具
在工程设计领域,流程图设计是许多企业不可或缺的一环。Visio,作为备受推崇的流程图设计工具,正在成为越来越多企业的首选,以期通过规范化的流程设计来提升整体工作效率。 尽管Visio提供了丰富的内置模具库,但在实际应用中,通用模具往往难以满足企业独特的业务需求。为了更好地适应企业的特殊流程和标准,许多企业纷纷转向定制模具库的方向,这与我们从外企的学习中所观察到的趋势是一致的。然而,由于缺乏指导性的方法,企业在推广和运用Visio时可能会面临一系列挑战。其中一个普遍存在的问题是在初版模具库建立后,如何有效地进行迭代更新。 本文将讨论Visio文档中模具更新的实现。首先介绍用户从模具库拖拽至绘图页时的背后过程,揭示为什么文档中的形状实例不会随模具库的更新而更新。随后介绍手动更新的方法。最后,提供比较两种自动化更新的方法及实现刚方法模具需满足的条件。 拖拽背后的故事 当用户首次从模具库拖拽模具到绘图页(Page)时,Visio在后台完成了多个操作。首先,Visio会在文档的文档模具(Document Stencil)中创建该模具的副本,然后再在绘图页上创建针对该模具形状的实例。由于文档模具默认是隐藏的,所以用户可能无法察觉到这一点。(要显示文档模具,首先需要在“选项”-“自定义功能区”中启用“开发者”选项卡。然后,在“开发者”选项卡-“显示/隐藏”分组中勾选“文档模具”。) 当用户再一次从模具库拖拽同一个模具时,Visio将检查文档模具中是否已存在该模具的副本。如果副本已经存在,Visio将直接创建实例。那么Visio是如何判断模具已存在的?在默认情况下Visio会比较模具的UniqueID属性。因此,即使两个模具具有相同的名称,Visio也可以通过UniqueID判断它们的对应关系。每当用户编辑并保存模具时,模具的UniqueID会发生变化。所以拖拽修改后的模具到绘图页时,可以观察到文档模具中出现了新的副本。这也就是为什么修改了模具库中的模具,绘图页中的实例没有被更新。 这显然与我们的期望不符。我们希望图纸中的实例永远与最新的模具一致。 手动更新 要将实例引用的模具修改为最新的模具,一种已知的方法是使用“主页”-“更改形状”对图纸中的实例进行更改。但是,对于已包含大量实例的文档,这个操作费时费力。尤其是当新版模具与旧模具的差异并不大时,用户很容易发生遗漏。 使用COM批量更新 借助COM组件,我们可以通过创建自动化程序的方式批量选择某一模具的实例,然后调用Shape.ReplaceShape()方法,实现批量更改这些实例的形状。 要获取文档模具中模具在文档中的所有实例,我们可以调用遍历文档中的所有形状,并筛选出Shape.Master等于文档模具中的Master情况。关键代码如下: public IEnumerable<IVShape> GetInstances(IVMaster master) { var instances = document.Pages.OfType<IVPage>() .SelectMany(x => x.Shapes.OfType<IVShape>()).Where(x => x.Master == master).ToList(); return instances; } 要找出模具库中对应的新模具,需要使用到模具的另一个ID属性————BaseID。模具的BaseID是在模具被创建的时候生成的,随后不会发生改变。因此,可以通过BaseID找到模具库中的同源模具。但是,使用这种方式时,要求模具库中的BaseID具有唯一性。一种常见的错误是管理员在创建模具时,采用的不是首先在绘图页绘制模具形状再拖拽至模具库,而是直接将模具库中的模具复制成了新的模具并编辑该模具。此时,模具库中的代表不通类型的模具具有相同的BaseID。 关键代码: public IVMaster GetLatestMaster(IVDocument document, string baseID) { var latestMaster = document.Masters.OfType<IVMaster>() .SingleOrDefault(x => x.BaseID == baseID); return latestMaster; } 然后,遍历这些事例,并将形状替换为新版本的模具。 public void Replace(IEnumerable<IVShape> instances, IVMaster latestMaster) { foreach (var instance in instances) { instance.ReplaceShape(latestMaster); } } 使用COM方式更新的好处是可以直接在原文件中进行修改。然而,由于UI的频繁更新可能导致方法执行时间较长,特别是在复杂的涂装车间原理图中,可能需要数分钟。因此,为了提升用户的使用体验,开发者可能会考虑加入进度条,以直观地显示更新进度。但是Visio使用STA模型且UI更新过程会向主线程封送消息,如果使用WPF组件,UI线程会发生阻塞,因此应使用WinForm。...