我知道我可以通过复制/粘贴手动完成此操作,但我正在寻找一种更简单的方法。
有人知道合并 Visio 文档的快速简便方法吗?我有几个 Visio vsd 文件,它们都是相同的内部文档类型(流程图 - 美国单位)。每个文件都有 1 到 15 页。我想将它们全部合并到一个 Visio 文件中。
我正在使用 Visio for Enterprise Architects (11.4301.8221),因此如果该版本中有执行该操作的程序,那就是我所寻找的,但第三方工具或宏也可以使用。
答案1
这并不容易做到,因为 Visio 没有在页面对象上提供良好的 .Copy 方法。
这可以通过 VBA 来完成,但它并不像我想象的那么简单。
我将在下面粘贴一些 VBA 代码,您可以通过传递一个文件名数组来使用它,这些文件名数组将复制每个文档中的所有页面。但请注意,它不会复制任何页面级形状表值,因为这对我来说太复杂了……所以如果您只是复制形状,这应该适合您(我使用 TryMergeDocs 子程序来测试它,它似乎运行良好)...
Private Sub TryMergeDocs()
Dim Docs() As Variant
Docs = Array("C:\Tmp\JunkVSD\Drawing1.vsd", "C:\Tmp\JunkVSD\Drawing2.vsd", "C:\Tmp\JunkVSD\Drawing3.vsd")
MergeDocuments Docs
End Sub
Sub MergeDocuments(FileNames() As Variant, Optional DestDoc As Visio.Document)
' merge into a new document if no document is provided
On Error GoTo PROC_ERR
If DestDoc Is Nothing Then
Set DestDoc = Application.Documents.Add("")
End If
Dim CheckPage As Visio.Page
Dim PagesToDelete As New Collection
For Each CheckPage In DestDoc.Pages
PagesToDelete.Add CheckPage
Next CheckPage
Set CheckPage = Nothing
' loop through the FileNames array and open each one, and copy each page into destdoc
Dim CurrFileName As String
Dim CurrDoc As Visio.Document
Dim CurrPage As Visio.Page, CurrDestPage As Visio.Page
Dim CheckNum As Long
Dim ArrIdx As Long
For ArrIdx = LBound(FileNames) To UBound(FileNames)
CurrFileName = CStr(FileNames(ArrIdx))
Set CurrDoc = Application.Documents.OpenEx(CurrFileName, visOpenRO)
For Each CurrPage In CurrDoc.Pages
Set CurrDestPage = DestDoc.Pages.Add()
With CurrDestPage
On Error Resume Next
Set CheckPage = DestDoc.Pages(CurrPage.Name)
If Not CheckPage Is Nothing Then
While Not CheckPage Is Nothing ' handle duplicate names by putting (#) after the original name
CheckNum = CheckNum + 1
Set CheckPage = Nothing
Set CheckPage = DestDoc.Pages(CurrPage.Name & "(" & CStr(CheckNum) & ")")
Wend
CurrDestPage.Name = CurrPage.Name & "(" & CStr(CheckNum) & ")"
Else
CurrDestPage.Name = CurrPage.Name
End If
On Error GoTo PROC_ERR
Set CheckPage = Nothing
CheckNum = 0
' copy the page contents over
CopyPage CurrPage, CurrDestPage
End With
DoEvents
Next CurrPage
DoEvents
Application.AlertResponse = 7
CurrDoc.Close
Next ArrIdx
For Each CheckPage In PagesToDelete
CheckPage.Delete 0
Next CheckPage
PROC_END:
Application.AlertResponse = 0
Exit Sub
PROC_ERR:
MsgBox Err.Number & vbCr & Err.Description
GoTo PROC_END
End Sub
Sub CopyPage(CopyPage As Visio.Page, DestPage As Visio.Page)
Dim TheSelection As Visio.Selection
Dim CurrShp As Visio.Shape
DoEvents
Visio.Application.ActiveWindow.DeselectAll
DestPage.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageHeight).Formula = CopyPage.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageHeight).ResultIU
DestPage.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageWidth).Formula = CopyPage.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageWidth).ResultIU
Set TheSelection = Visio.ActiveWindow.Selection
For Each CurrShp In CopyPage.Shapes
TheSelection.Select CurrShp, visSelect
DoEvents
Next
TheSelection.Copy visCopyPasteNoTranslate
DestPage.Paste visCopyPasteNoTranslate
TheSelection.DeselectAll
End Sub
答案2
我遇到了类似的问题,但也想复制页面的背景。因此,我在 CopyPage 过程中添加了以下行:
DestPage.Background = CopyPage.Background
并在 MergeDocuments 过程中在 CurrDoc.Pages 上添加了另一个循环:
For Each CurrPage In CurrDoc.Pages
Set CurrDestPage = DestDoc.Pages(CurrPage.Name)
SetBackground CurrPage, CurrDestPage
Next CurrPage
SetBackground 过程非常简单:
Sub SetBackground(CopyPage As Visio.Page, DestPage As Visio.Page)
If Not CopyPage.BackPage Is Nothing Then
DestPage.BackPage = CopyPage.BackPage.Name
End If
End Sub
这很有效。也许有人会觉得它有用。
答案3
感谢大家分享解决方案。
让我复制/粘贴 Jon 的解决方案和用户 26852 的补充的“合并”:-)
这是一个完整的宏,对我来说非常有效:
Private Sub TryMergeDocs()
Dim Docs() As Variant
Docs = Array("C:\Tmp\JunkVSD\Drawing1.vsd", "C:\Tmp\JunkVSD\Drawing2.vsd", "C:\Tmp\JunkVSD\Drawing3.vsd")
MergeDocuments Docs
End Sub
Sub MergeDocuments(FileNames() As Variant, Optional DestDoc As Visio.Document)
' merge into a new document if no document is provided
On Error GoTo PROC_ERR
If DestDoc Is Nothing Then
Set DestDoc = Application.Documents.Add("")
End If
Dim CheckPage As Visio.Page
Dim PagesToDelete As New Collection
For Each CheckPage In DestDoc.Pages
PagesToDelete.Add CheckPage
Next CheckPage
Set CheckPage = Nothing
' loop through the FileNames array and open each one, and copy each page into destdoc
Dim CurrFileName As String
Dim CurrDoc As Visio.Document
Dim CurrPage As Visio.Page, CurrDestPage As Visio.Page
Dim CheckNum As Long
Dim ArrIdx As Long
For ArrIdx = LBound(FileNames) To UBound(FileNames)
CurrFileName = CStr(FileNames(ArrIdx))
Set CurrDoc = Application.Documents.OpenEx(CurrFileName, visOpenRO)
For Each CurrPage In CurrDoc.Pages
Set CurrDestPage = DestDoc.Pages.Add()
With CurrDestPage
On Error Resume Next
Set CheckPage = DestDoc.Pages(CurrPage.Name)
If Not CheckPage Is Nothing Then
While Not CheckPage Is Nothing ' handle duplicate names by putting (#) after the original name
CheckNum = CheckNum + 1
Set CheckPage = Nothing
Set CheckPage = DestDoc.Pages(CurrPage.Name & "(" & CStr(CheckNum) & ")")
Wend
CurrDestPage.Name = CurrPage.Name & "(" & CStr(CheckNum) & ")"
Else
CurrDestPage.Name = CurrPage.Name
End If
On Error GoTo PROC_ERR
Set CheckPage = Nothing
CheckNum = 0
' copy the page contents over
CopyPage CurrPage, CurrDestPage
SetBackground CurrPage, CurrDestPage
End With
DoEvents
Next CurrPage
DoEvents
Application.AlertResponse = 7
CurrDoc.Close
Next ArrIdx
For Each CheckPage In PagesToDelete
CheckPage.Delete 0
Next CheckPage
PROC_END:
Application.AlertResponse = 0
Exit Sub
PROC_ERR:
MsgBox Err.Number & vbCr & Err.Description
GoTo PROC_END
End Sub
Sub CopyPage(CopyPage As Visio.Page, DestPage As Visio.Page)
Dim TheSelection As Visio.Selection
Dim CurrShp As Visio.Shape
DoEvents
Visio.Application.ActiveWindow.DeselectAll
DestPage.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageHeight).Formula = CopyPage.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageHeight).ResultIU
DestPage.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageWidth).Formula = CopyPage.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageWidth).ResultIU
DestPage.Background = CopyPage.Background
Set TheSelection = Visio.ActiveWindow.Selection
For Each CurrShp In CopyPage.Shapes
TheSelection.Select CurrShp, visSelect
DoEvents
Next
TheSelection.Copy visCopyPasteNoTranslate
DestPage.Paste visCopyPasteNoTranslate
TheSelection.DeselectAll
End Sub
Sub SetBackground(CopyPage As Visio.Page, DestPage As Visio.Page)
If Not CopyPage.BackPage Is Nothing Then
DestPage.BackPage = CopyPage.BackPage.Name
End If
End Sub
不过有一件事:我必须重新检查我页面上的图层上的“锁定”。我假设“图层属性”不会被宏传播。对我来说,重新锁定所有背景图层并不是什么大问题。但对于其他人来说,可能值得进一步了解如何复制/粘贴图层属性。
答案4
从以下位置下载 Visio 超级实用程序:
http://www.sandrila.co.uk/visio-utilities/
安装时在下载包中给出了 install_readme.txt,请参考安装。安装 Visio Super Utilities 后,使用以下步骤合并 Visio 文档
- 打开您想要合并的 2 个 Visio 文档。
- 转到插件 -> SuperUtils -> 文档 -> 将文档复制到其他文档
对每个源文档重复此操作。