Replace Shape not working C#

Started by Memnok, September 11, 2023, 08:53:19 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Memnok

Hi,

So after my last topic I've worked on cleaning up some documents, and I've run into a problem. Where certain shapes won't let me replace them with a master, this is a shape that does not have a master. It's grouped in another shape with more shapes on the same group level. None of the shapes are protected in any way and none of them belong to a locked layer, but still I can't replace it. If I completely ungroup the shape it works normally. This shape is not different from all the other shapes in the document, so I might replace 20-30 shapes on a page but 2-5 will fail to replace.

I do a bunch of stuff to sort out the shapes but the main process is finding a shape with "Terminal" in it's name and replacing it with the "Terminal" master shape if it does not have a master.
To do this I use Shape.ReplaceShape(Master, Replace Flags) and this is the line that fails. For the flags I use "1" and I've tried with the other options but none have yielded better results, and I don't see why the flags would be a problem when it works on the majority of the shapes.
https://learn.microsoft.com/en-us/office/vba/api/visio.shape.replaceshape

This issue persists when the shape is copied to a new document so I will attach a sample here. In this sample I am trying to replace "Terminal.4171" with a copy of the "Terminal" master shape.
Any idea of what is preventing this would be appreciated.

Yacine

Works fine here. Can you show your code and specially the line that fails and what error it gives?
Yacine

Nikolay

As far as I remember, "ReplaceShape" only supports replacing top-level shapes. It does not support replacing shapes inside of groups (the button is disabled when you select a shape inside of a group)

Memnok

#3
Quote from: Yacine on September 11, 2023, 09:40:36 AM
Works fine here. Can you show your code and specially the line that fails and what error it gives?

Hi,

The code that fails is literally only one line. There's also some code related to hooking up connectors that were connected to the previous shape, but none of that is used until after the shape is replaced. The master shape is sourced at the beginning of the function and is the same object for all the shapes being replaced.
The exception I'm getting is "Shape protection, container, and/or layer properties prevent complete execution of this command.""

           
try
{
    newShape = shapeToReplace.ReplaceShape(masterShape, 1);
}
catch
{
    newShape = null;
    return "Not replaced;" + shapeToReplace.Name + "." + shapeToReplace.ID + ";" + subshapePage + Environment.NewLine;
}


Quote from: Nikolay on September 11, 2023, 10:35:51 AM
As far as I remember, "ReplaceShape" only supports replacing top-level shapes. It does not support replacing shapes inside of groups (the button is disabled when you select a shape inside of a group)
Yes in the UI you can't do that, but you can still do it programmatically. I replace 16 shapes that are grouped on one page but 4 of them throw this error.

Memnok

Quote from: Nikolay on September 11, 2023, 10:35:51 AM
As far as I remember, "ReplaceShape" only supports replacing top-level shapes. It does not support replacing shapes inside of groups (the button is disabled when you select a shape inside of a group)

I've done some more testing and it seems you're partially correct Nikolay (At least for my document). The problem appears if I try to replace a subshape that does not have a master shape.
But any shape, that has a master can be replaced with this command.

But I wonder how Yacine made it work in his case.

Yacine

Quote from: Memnok on September 11, 2023, 11:43:50 AM
But I wonder how Yacine made it work in his case.

I replaced at top level only.
Replacing at a sub-level does not work.

Workaroud: cut the shape and memorize its position, insert at top level, replace by other shape, cut and insert in group at memorized position.
Yacine

Memnok

Quote from: Yacine on September 11, 2023, 01:11:12 PM
Quote from: Memnok on September 11, 2023, 11:43:50 AM
But I wonder how Yacine made it work in his case.

I replaced at top level only.
Replacing at a sub-level does not work.

Workaroud: cut the shape and memorize its position, insert at top level, replace by other shape, cut and insert in group at memorized position.

Yes, that was my conclusion as well.

Nikolay

There may be a bit better option (so that you don't need to memorize position) - "Open Group", replace, close group. I mean, manually.

Yacine

Quote from: Nikolay on September 11, 2023, 02:23:08 PM
There may be a bit better option (so that you don't need to memorize position) - "Open Group", replace, close group. I mean, manually.
I tried it before sending my previous post. That doesn't work. That's why I proposed the more complicated way.
Yacine

Nikolay

By "manually" I meant - you open the group, delete the old shape and drop the new one instead :D
Also tried, "replace shape" is disabled when you are in an open group.

Yacine

#10
Basically yes, but the replace operation has some properties that don't come with a manually replacement.
It keeps a lot of the properties of the original shape - position, angle, props, etc.
The only property that we cannot keep is the position since we're cutting out and pasting on the top level. Hence the need to memorizing it.


To keep in mind, we are also destroying the connections. So it would make sense to lock all the connectors in the group before cutting the shape out - to prevent unwanted re-routing.
Yacine