Python通过win32com访问Visio自定义模具报错求解决方案
如何用Python访问Visio“我的形状”中的自定义模具
问题描述
我有一段能在Visio已打开时添加基础形状的Python代码,但想访问Visio中「更多形状->我的形状」下的自定义模具。尝试把代码里的:
stnObj = appVisio.Documents("Basic Shapes.vss")
替换成:
stnObj = appVisio.Documents("More Shapes\My Shapes\mycustomStencil.vss")
后,在打开模具的代码行报错,错误信息:
Message=(-2147352567, 'Exception occurred.', (0, 'Drawing4 - Visio Professional', '\n\nThis file name is not valid.', None, 0, -2032466859), None)
原可正常运行的基础代码:
import win32com.client appVisio = win32com.client.Dispatch("Visio.Application") doc = appVisio.Documents.Add("Basic Diagram.vst") pagObj = doc.Pages.Item(1) stnObj = appVisio.Documents("Basic Shapes.vss") shpObj1 = pagObj.Drop(stnObj.Masters("Square"), 4, 7) shpObj1.Text = "Square text"
问题原因
「更多形状->我的形状」是Visio界面里的导航分类名称,不是模具文件的实际存储路径,直接用这个虚拟路径会导致Visio无法定位到文件。
解决方法
方法1:使用模具的绝对路径
Windows系统中,“我的形状”默认存储路径为 C:\Users\[你的用户名]\Documents\My Shapes。找到你的自定义模具实际位置后,用绝对路径访问,注意Python中路径要用**双反斜杠\\或者原始字符串r""**避免转义问题:
import win32com.client appVisio = win32com.client.Dispatch("Visio.Application") doc = appVisio.Documents.Add("Basic Diagram.vst") pagObj = doc.Pages.Item(1) # 替换成你的实际路径 stnObj = appVisio.Documents.Open(r"C:\Users\YourUsername\Documents\My Shapes\mycustomStencil.vss") shpObj = pagObj.Drop(stnObj.Masters("你的自定义形状名称"), 4, 7) shpObj.Text = "自定义形状文本"
提示:用
Documents.Open()而非直接索引Documents(),因为如果模具未在Visio中打开,直接索引会报错,Open()会主动加载模具文件。
方法2:通过Visio对象模型自动获取“我的形状”路径
避免硬编码绝对路径,可通过Visio的Settings.UserShapePaths获取用户自定义形状的存储路径:
import win32com.client appVisio = win32com.client.Dispatch("Visio.Application") doc = appVisio.Documents.Add("Basic Diagram.vst") pagObj = doc.Pages.Item(1) # 获取“我的形状”文件夹路径(索引0通常对应默认的“我的形状”目录) my_shapes_dir = appVisio.Settings.UserShapePaths(0) stencil_full_path = f"{my_shapes_dir}\\mycustomStencil.vss" # 打开自定义模具 stnObj = appVisio.Documents.Open(stencil_full_path) # 拖放自定义形状 shpObj = pagObj.Drop(stnObj.Masters("你的自定义形状名称"), 4, 7) shpObj.Text = "自定义形状文本"
额外注意事项
- 确认自定义模具的文件名和扩展名正确(比如
.vss适用于旧版Visio,.vssx是新版格式) - 如果模具已在Visio中打开,可直接用
appVisio.Documents("mycustomStencil.vss")索引,但未打开时必须调用Open()方法
内容的提问来源于stack exchange,提问作者ck2199
相关产品推荐
相关产品推荐

