通过Python或VBA脚本在同一窗口中打开Visio图形和设计文件
我希望有人能给我建议,如何解决我在使用Visio设计文档时遇到的问题。我有好几百个.vsdx文件,每个文件里的形状都会在新窗口中打开。
问题在于如何让Visio强制把所有形状都在同一个窗口中打开。
我的目标是实现类似“选项 > 高级 > 在同一个窗口中打开所有形状”的效果。
我尝试了两种方法,但都没有成功:
- Python脚本
import os
import win32com.client
directory = "C:\\Users\\User\\Documents\\Designs"
def process_visio_files(directory):
print("Visio Started.")
visio.Visible = False # Run Visio in the background
for root, dirs, files in os.walk(directory):
if "Archiv" in root:
continue # Skip folders containing "Archiv"
for file in files:
if file.endswith('.vsdx'):
print("File is {}".format(file))
full_path = os.path.join(root, file)
# Process the Visio file
document = visio.Documents.Open(full_path)
dir(document)
document.PropertyToPreventSeparateWindows = True # HERE IS WHERE I NEED TO DO SOME MAGIC FOR THE SHAPES TO OPEN IN THE SAME WINDOW
document.Save()
document.Close()
visio.Quit()
process_visio_files(directory)
我找不到用Python实现所需更改的方法。用VBA稍微成功了一些。
- VBA脚本(这个脚本会关闭一些形状,所有不是以只读模式打开的形状):
Sub ProcessVisioFilesInFolders()
Dim rootFolder As String
rootFolder = "C:\Users\User\Documents\Designs\"
ProcessFolder rootFolder
End Sub
Sub ProcessFolder(folderPath As String)
Dim fs As Object
Dim folder As Object
Dim subfolder As Object
Dim file As Object
Dim visioApp As Object
On Error Resume Next
' Try to get an existing instance of Visio
Set visioApp = GetObject(, "Visio.Application")
On Error GoTo 0
If visioApp Is Nothing Then
' If Visio is not running, create a new instance
Set visioApp = CreateObject("Visio.Application")
visioApp.Visible = True ' Make Visio application visible
End If
' Create FileSystemObject
Set fs = CreateObject("Scripting.FileSystemObject")
MsgBox "Processing folder: " & folderPath
' Loop through all files in the folder
For Each file In fs.GetFolder(folderPath).Files
If LCase(file.Name) Like "*.vsdx" Then
MsgBox "Processing file: " & file.Path
' Process .vsdx files
ProcessVisioFile visioApp, file.Path
End If
Next file
' Loop through all subfolders in the folder
For Each subfolder In fs.GetFolder(folderPath).SubFolders
' Check if the subfolder name contains 'Archiv'
If InStr(1, subfolder.Name, "Archiv", vbTextCompare) = 0 Then
' Recursively process subfolders
ProcessFolder subfolder.Path
Else
MsgBox "Skipping 'Archiv' subfolder: " & subfolder.Path
End If
Next subfolder
End Sub
Sub ProcessVisioFile(visioApp As Object, filePath As String)
Dim doc As Object
Dim win As Object
Dim shapeSheetWin As Object
' Open the Visio file
Set doc = visioApp.Documents.Open(filePath)
' Ensure Visio application is visible and brought to the front
visioApp.Visible = True
' Introduce a delay to allow the application to become active
Dim startTime As Double
startTime = Timer
Do While Timer < startTime + 1 ' Adjust the delay as needed
DoEvents
Loop
' Loop through all windows
For Each win In visioApp.Windows
If win.Type = 1 Then ' visDrawing type
' Your processing logic here
On Error Resume Next
win.HideShapesheet
On Error GoTo 0
ElseIf win.Type = 2 Then ' visStencil type
' Close stencil windows
Set shapeSheetWin = win
shapeSheetWin.Close
End If
Next win
' Save the changes to the Visio file
MsgBox "Saving changes to Visio file: " & filePath
doc.Save
' Close the Visio file
MsgBox "Closing Visio file: " & filePath
doc.Close
End Sub
有没有人能分享一下,如何解决形状在不同窗口中打开的问题?
1 个回答
1
在你最初的帖子中,我看到第一张图片里有很多以只读方式打开的模板,这些模板是在不同的窗口中显示的……
这不是形状表窗口!!!
我没有遇到过同样的问题,所以我用代码创建了一个示例
Option Base 1
Sub Prepare()
Dim pth(3) As String, curpath As String, i As Integer
pth(1) = "C:\My Shapes\19_inch_Rack_flexible_RU.vss"
pth(2) = "C:\My Shapes\Favorites.vssx"
pth(3) = "C:\My Shapes\GOST_R_21.1101-2013.vss"
For i = LBound(pth) To UBound(pth)
curpath = pth(i)
Documents.OpenEx curpath, visOpenRO ' open stencil in new window as read-only
Next
ActiveDocument.DocumentSheet.OpenSheetWindow ' add Document ShapeSheet window
End Sub
在我这边,下面的代码会关闭所有窗口,如果窗口的类型不是绘图窗口的话。请多了解一下 VisWinTypes 枚举 (Visio)!
下面的代码可以关闭所有非绘图窗口
Sub Test()
Dim va As Application, vw As Window
Set va = Application
For Each vw In va.Windows
Debug.Print vw.Caption, vw.Type, vw.SubType
If Not vw.Type = visDrawing Then vw.Close ' visDrawing = 1 Python dont know Visio internal constants
Next
ActiveDocument.ContainsWorkspaceEx = False ' prevent save document workspace (a lot of RO-opened stencils)
ActiveDocument.Save
End Sub
ActiveDocument.ContainsWorkspaceEx = False
这一行代码可以防止保存工作区(所有只读模板)。请查看这篇文章 Document.ContainsWorkspaceEx 属性 (Visio)。
~~现在我没有Python环境,我会稍后再找……~~
我在Jupyter Notebook中试了这段代码,它在我这边可以正常工作……
import win32com.client
app = win32com.client.Dispatch('Visio.Application')
app.Visible = True
for i in range(app.windows.count,1,-1):
vw = app.windows(i)
if vw.Type!=1:
vw.close
app.ActiveDocument.ContainsWorkspaceEx = False
app.ActiveDocument.Save