How to match up sub-shapes after shape.ReplaceShape

Started by rezingg, October 29, 2021, 06:58:09 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

rezingg

I use shape.ReplaceShape to upgrade existing symbols in my document with an updated master.
In order to transfer some properties I first make a copy of the symbol.
I would like to transfer text from the old shape to the new one, which works fine.
But if my shape is a group, then I run into the problem of matching up sub-shapes in the new shape (based on new master) with sub-shapes in the old symbol, the copy (so that I can transfer any texts).
Unfortunately the names of the sub-shapes are not retained, so I can't match them up by name.
I could simply iterate and go by order of the group items, but that seems a bit dangerous if there were any changes in the new master.
Is there some way to identify sub-shapes after a copy / shape.ReplaceShape operation?

Here is a snippet from my code, copying the shape to a temporary page (as a backup), then replace the shape with a new master

shp.Copy (visCopyPasteNormal)
tempPage.Paste
Set tempShape = tempPage.Shapes(1)
Set newShape = shp.ReplaceShape(vsoNewMaster, visReplaceShapeDefault) ' replace with new master

After this I would like to transfer text of the shape and any sub-shapes from the backup copy to the new shape. But the sub-shapes don't retain their names (both copy/paste and ReplaceShape change the sub-shape names)...
Any pointers what I could look at? Or am I approaching this the wrong way?
Help is much appreciated!

Edit:
by now I found that when I assign names to those sub-shapes (i.e. over-write the default xxx.nn names) then both copy/paste and ReplaceShape will keep the names. It looks like my approach has to be to name in the master any sub-shape that has a text that should be transferred. From there on any changes to the master can track and transfer texts.

wapperdude

Not used the replaceshape method, but I don't believe it was intended for grouped shapes.  Nonetheless, it might work as needed if the grouping were defined in such a way that each subshape derived its settings directly from the group level.  That is, if you push into the group and select a subshape to enter text, that would be lost.  But if you used a placeholder in the group to store that text and pushed it into the sub shape, that might work. 

Just a guess.  BTW, what shape?  Is there a necessity to replace it?
Visio 2019 Pro

Visisthebest

rezingg I guess that if you do a shape replace, the subshape names used in a Master (the Master that replaces the current shape) would be retained. I will test this as well.
Visio 2021 Professional

Visisthebest

Just going through the UI I cannot select any grouped shape masters I created, and use them to replace a shape. Only the non-grouped shapes can be selected.

Why this limitation is another question, and may be related to the subshape name issue.

Visio 2021 Professional

Surrogate

#4
Quote from: rezingg on October 29, 2021, 06:58:09 PM
I use shape.ReplaceShape to upgrade existing symbols in my document with an updated master.
ReplaceShape command replace whole shape, and dont care about sub-shapes.

In ShapeSheet of each shape you can find Change Shape Behavior Section. I dont understand how it work. I cant protect shape text even for non-grouped shape !
Quote from: Visisthebest on October 30, 2021, 08:24:26 AM
Just going through the UI I cannot select any grouped shape masters I created, and use them to replace a shape. Only the non-grouped shapes can be selected.
Just now I use Visio 2019 Professional, there i can replace each shape !
Two years ago when I use Visio 2016 Professional and Visio 2019 Standard, not all shapes could not replaced with this command. Because button was disabled for some shapes...
Visisthebest, which version do you use ? Visio 2021 Professional - Just check this info in your profile.

Visisthebest

In 2019 I can replace all shapes, unless protected against replacement, but I cannot select a group shape in a stencil to replace the shape with, only single (non-grouped) shapes I can use as a replacement.
Visio 2021 Professional

Surrogate

Quote from: Visisthebest on October 30, 2021, 10:56:08 AM
but I cannot select a group shape in a stencil to replace the shape with, only single (non-grouped) shapes I can use as a replacement.
wow, i dont know that this operation works even into stencil! I think this operation only for shapes on page

wapperdude

It will not work with stencils.  Stencils expect a Master, not a shape.  So, that disqualifies replaceshape for stencils.  Still not seeing the motivation to do this.  Knowing why would help explore options that might provide a better approach.

So, if you change a stencil Master, that impacts everyone who uses that stencil.  All of a sudden, newly dropped shapes will be different from previous shapes in the drawing.  Nevertheless, it's possible to open Master for editing.   Then, in edit window, either make changes needed or delete the shape, and replace by pasting the updated shape.  Save.  Likewise, it is possible to edit the Master in the Document Stencil, and that can flush upwards to all shapes that reference it.  This limits the scope to just the document.

With regards to grouped shapes, as I suspected, the replaceshape really honors just the toplevel shape of a group.  You can lock text, etc. upon replace in shapesheet, and preserve those features upon doing replacement.  But, whatever formating is present in the subshapes, including text, will be flushed thru upon replacement.  Bottom line, not convenient for grouped shapes.
Visio 2019 Pro

Visisthebest

Sorry for the misunderstanding I mean I use a Master from a stencil to replace a shape on the page, not replace a Master with another Master.

I cannot use Masters with subshapes to replace shapes on the page, this option doesn't show in the Visio UI.
Visio 2021 Professional

wapperdude

I believe this is only done via VBA (code)...  That's how I tried this.
Visio 2019 Pro

wapperdude

Visio 2019 Pro

rezingg

#11
Sorry for my lengthy silence.
I ended up writing my own replace. What I do is drop the new shape (based on provided master) right on top of the shape to be replaced, then copy over various properties. Then I descend down into any sub-shapes and transfer the text of any matched (by name) shapes. This requires, as I noted in my original post, that those shapes are named, and don't have the default names. Finally I also re-wire any connectors from the old shape to the new shape.

Here is the code to transfer the text from one shape to the other (it assumes the grouping and sub-shapes is structured the same):

' Transfer shape text and hierarchically descend down into groups, transferring texts of matching named sub-shapes.
' Make sure that any sub-shapes of master that carry text to be transferred are named. Automatically named shapes will not keep their name and hence can't be tracked to transfer text.
Public Sub transferCascadeText(shpFrom As Visio.Shape, shpTo As Visio.Shape)
    If (shpTo.Text <> shpFrom.Text) And (shpTo.CellsU("LockTextEdit") = 0) Then ' if text is not same and text edit is not protected, then transfer text
        shpTo.Text = shpFrom.Text
    End If
    ' descend into grouped shapes, if this is a group
    If shpFrom.Type = visTypeGroup And shpTo.Type = visTypeGroup Then
        ' match up shapes by name. Master must have sub-shapes that have text to transfer named
        Dim match As Boolean
        Dim subShpFrom As Visio.Shape
        Dim subShpTo As Visio.Shape
        For Each subShpFrom In shpFrom.Shapes
            match = True
            On Error GoTo noMatchFound
            Set subShpTo = shpTo.Shapes(subShpFrom.Name)
            On Error GoTo 0
            If match Then
                transferCascadeText subShpFrom, subShpTo
            End If
        Next subShpFrom
    End If
    Exit Sub
noMatchFound:
    match = False
    Resume Next
End Sub