使用Python为Visio元素填充颜色时代码不生效如何解决
Visio通过pywin32修改Server母版填充色不生效的解决方案
问题原因
当前代码不生效是三个核心问题导致的:
Servers.vss中的Server是多层嵌套的组合形状,默认绑定Visio主题配色规则,直接修改Fillforegnd单元格会被主题属性覆盖,不会实际生效- 遍历子形状时,线条、文本框等子形状没有填充属性,访问
Fillforegnd单元格会静默抛出COM错误,中断后续有效形状的修改流程 - 默认母版开启了渐变填充配置,仅修改前景色会显示渐变效果,无法得到纯色填充
可行修复方案
基础修复(无嵌套分组场景)
拖放形状后先关闭顶层形状的主题关联,再遍历有效子形状修改填充属性,修正后的完整代码如下:
import win32com.client as w32 visio = w32.Dispatch("visio.Application") visio.Visible = 1 doc = visio.Documents.Add("Detailed Network Diagram.vst") page = doc.Pages.Item(1) page.Name = "My drawing" stn2 = visio.Documents("Servers.vss") server = stn2.Masters("Server") serv = page.Drop(server, 0, 0) # 先配置顶层形状的填充规则,关闭主题继承 serv.CellsU("FillPattern").FormulaForceU = 1 # 设为纯色填充 serv.CellsU("ThemeProperties").FormulaForceU = 0 # 禁用主题属性覆盖 serv.CellsU("FillForegnd").FormulaForceU = "RGB(255,0,0)" serv.CellsU("FillBkgnd").FormulaForceU = "RGB(255,0,0)" # 遍历子形状,仅修改存在填充属性的形状 for ssh in serv.Shapes: if ssh.CellExistsU("Fillforegnd", 0): ssh.CellsU("FillPattern").FormulaForceU = 1 ssh.CellsU("ThemeProperties").FormulaForceU = 0 ssh.CellsU("Fillforegnd").FormulaForceU = "RGB(255,0,0)" ssh.CellsU("FillBkgnd").FormulaForceU = "RGB(255,0,0)"
兼容嵌套分组的通用方案
如果你的Visio版本中Server母版存在多层嵌套分组,一级遍历无法覆盖所有内部形状,可以用递归函数遍历所有层级的形状,代码如下:
import win32com.client as w32 def set_solid_fill(shape, rgb_color: str): """递归给形状及所有子形状设置纯色填充,关闭主题覆盖""" # 仅处理存在填充属性的形状 if shape.CellExistsU("Fillforegnd", 0): shape.CellsU("FillPattern").FormulaForceU = 1 shape.CellsU("ThemeProperties").FormulaForceU = 0 shape.CellsU("FillForegnd").FormulaForceU = rgb_color shape.CellsU("FillBkgnd").FormulaForceU = rgb_color # 递归遍历子形状 if shape.Shapes.Count > 0: for sub_shape in shape.Shapes: set_solid_fill(sub_shape, rgb_color) if __name__ == "__main__": visio = w32.Dispatch("visio.Application") visio.Visible = 1 doc = visio.Documents.Add("Detailed Network Diagram.vst") page = doc.Pages.Item(1) page.Name = "My drawing" stn2 = visio.Documents("Servers.vss") server = stn2.Masters("Server") serv = page.Drop(server, 0, 0) # 调用填充函数,设置纯红色 set_solid_fill(serv, "RGB(255,0,0)")
注意事项
- 单元格名不区分大小写,
Fillforegnd和FillForegnd效果一致 - 如果使用的是Visio 2013以前的版本,没有
ThemeProperties单元格,可以注释掉对应行,直接修改FillForegnd即可生效 - 不要将形状的
FillForegndTrans(填充透明度)设为非0值,否则会显示透明效果
内容的提问来源于stack exchange,提问作者Eladtopaz
相关产品推荐
相关产品推荐

