引言

许多Visio管理员在项目初期都会面临模具频繁更新的问题。由于Visio的机制,每当用户首次从模具库中拖拽模具至绘图页时,实际上是从该模具库中拷贝了模具的副本至文档模具中。这种机制无疑切断了文档模具与原模具库的联系,也造成管理更新模具库后无法将更新应用到已有的绘图上。当绘图上需要更新的形状数量较少时,可以使用Visio提供的更改形状功能手动更新。但是,当绘图页中存在大量的待更新形状时,使用使用程序进行批量更新。

image.png

程序批量更新的方法是遍历文档模具,并通过文档模具中模具的BaseID从模具库中找到源模具,再比较两者的UniqueID是否一致。若UniqueID一致,说明该模具没有更新,应跳过操作;若不一致,说明源模具发生了更新。然后在绘图页中找到所有与该模具关联的形状,然后删除文档模具中的旧模具,再执行Shape.Replace()方法使用新的模具替换形状。

这种方法通常是凑效的,但是在上一周中,我遇到了如下的BUG:更新后的形状显示Obj文本。仔细查看形状shapesheet,可以发现模具中已经定义好的TextField在形状中变成了空白,造成显示错误。

企业微信截图_16947712887795.png

不幸的是,未能在Google中搜到类似的问题反馈。

问题排查

通过查看xml文件,发现该形状的Field节被替换为了<Row IX='0' Del='1'/>。对比未出现显示错误的形状的xml文件可以发现:当TextField取值为空时,Field节应该继承自模具,因此xml文档不应出现Field节;当TextField存在取值时,Row节点内应该有Cell节点。此时,如果手动删除Field节,显示的OBJ文字消失。由此可以推出Field节数据发生了异常。

但是,仍然无法确定该异常的产生是因为形状定义错误还是其他。

回到Visio应用程序中,在源模具中的形状树中删除发生该问题的子形状,再次执行更新程序,原本没有问题的子形状的TextField出现同样的问题。重复执行删除子形状并更新的操作,问题始终出现。当所有的子形状都被删除后,更新后的形状不再显示OBJ。但是,新的问题出现了:形状显示数字3。显然我们并没有在模具的任何形状或子形状中定义过这个数值。

由此可以推出,形状定义并没有问题,而是其他数据导致了Visio更新时的异常行为。

为了确定是哪一部分数据存在问题,我们清空了User、ShapeData等全部用于定义用户数据的Section,问题依然复现。现在,只剩模具的基础数据了(诸如PinX、PinY等Shape节点下的Cell节点)。由于Visio中不能删除基础数据,所以在XML文件中用其他正常模具的基础数据替换问题模具的基础数据。此后,再使用程序对绘图页的形状进行更新,数字3不再出现,也就是这个BUG被修复了。

通过文本对比工具,我们比较了问题模具与正常模具的基础数据。

(此处,因为重启电脑图丢了。。。。。)

比较两者的基础数据并没有特别的地方,除了尺寸和定位存在数值差异外,只有Cell的顺序存在区别。最终也无法确定这个问题到底是怎么产生的。

解决方法

尽管未能找到该问题形成的原因,但通过定位问题位置,我们找到了解决该问题的方法:即使用正常模具的基础数据覆盖问题模具。