我没有找到一个很好的方法来处理这个问题。我有一个方法将剪贴板粘贴到页面并返回任何新形状,方法是在粘贴之前和之后列出所有形状ID,然后返回新形状。
如果速度对我来说是个大问题,我通常会粘贴到一个空的隐藏页面,在该页面上执行任何操作,然后在目标页面上剪切并粘贴到位。如果你需要与其他形状粘合,这将不会真正起作用,但是当它有意义时我会使用这个逻辑。
形状的ID仅对其页面是唯一的,因此粘贴到Page-1的新形状将收到一个新ID,从而收到您正在接收的错误。虽然 Duplicate 方法返回对新形状的形状引用, Paste 不是这样你需要通过其他方式获得对它的引用 - 或者假设关于窗口选择(根据Surrogate的答案)或索引:
Duplicate
Paste
Dim shp As Visio.Shape Dim pag As Visio.Page Set pag = ActivePage 'or some alternative reference to Page-1 Set shp = pag.Shapes.ItemU(pag.Shapes.Count) Debug.Print shp.Index
更常见的工作流程是生成母版(在模板文档中)然后删除这些母版而不是在页面之间复制和粘贴,但您的场景可能需要不同的方法。
我将添加此链接作为处理索引和ID属性的有用参考:
[更新]
@Jon Fournier在下面的评论是完全正确的,以上确实做出了假设。例如,如果 DisplayLevel 源形状中的单元格小于最顶部的形状,然后它将粘贴到相应索引处的页面形状集合中,因此count将不会返回正确的形状ID。
DisplayLevel
另一种方法可能是倾听 ShapeAdded 页面(或页面)上的事件。以下是对此的略微改编 IsInScope 在docs中的示例,代码放置了ThisDocument。这允许您在处理ShapeAdded事件时可以检查的事件范围ID对中对代码进行顶部和尾部处理:
ShapeAdded
IsInScope
Private WithEvents vPags As Visio.Pages Private pastedScopeID As Long Public Sub TestCopyAndPaste() Dim vDoc As Visio.Document Set vDoc = Me 'assumes code is in ThisDocument class module, but change as required Dim srcPag As Visio.Page Set srcPag = vDoc.Pages.ItemU("Page-2") Dim targetPag As Visio.Page Set targetPag = vDoc.Pages.ItemU("Page-1") Dim srcShp As Visio.Shape Set srcShp = srcPag.Shapes.ItemFromID(12) Set vPags = vDoc.Pages pastedScopeID = Application.BeginUndoScope("Paste to page") srcShp.Copy targetPag.Paste Application.EndUndoScope pastedScopeID, True End Sub Private Sub vPags_ShapeAdded(ByVal shp As IVShape) If shp.Application.IsInScope(pastedScopeID) Then Debug.Print "Application.CurrentScope " & Application.CurrentScope Debug.Print "ShapeAdded - " & shp.NameID & " on page " & shp.ContainingPage.Name DoSomethingToPastedShape shp Else Debug.Print "Application.CurrentScope " & Application.CurrentScope End If End Sub Private Sub DoSomethingToPastedShape(ByVal shp As Visio.Shape) If Not shp Is Nothing Then shp.CellsU("FillForegnd").FormulaU = "=RGB(200, 30, 30)" End If End Sub
当然,您会收到错误“无效的工作表标识符”!因为在“Page-1”你可以有形状 的 ShapeID 强> ,您为“Page-2”放置的形状定义的。
您可以粘贴形状,并在此步骤后定义所选形状。
Application.ActiveDocument.Pages.ItemU("Page-1").Paste ' You can define this variable as shape which is selected Set Shape = Application.ActiveWindow.Selection.PrimaryItem
为什么你使用变量两次?