Visio Guy

Visio Discussions => Programming & Code => Topic started by: Visisthebest on January 29, 2022, 11:20:07 AM

Title: What is the most elegant/fastest way to get all Masters used in a page
Post by: Visisthebest on January 29, 2022, 11:20:07 AM
In a multi-page document where different (versions of) stencils are used on different pages, I would like to filter out just the set of Masters that are used on a single page.

Because the Page doesn't have a Masters collection itself:
https://docs.microsoft.com/en-us/office/vba/api/visio.page

and pages may contain 1000-2000 shapes, probably going through all the shapes to find all the masters is not very efficient.

What is the most elegant way to quickly retrieve all the Masters used on a single page? Thank you for sharing your insights!
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Yacine on January 29, 2022, 02:02:09 PM
Interesting question, I would have looped.
up to 2000 iterations should be fast enough for regular checks, only when it comes to repeating the operation over an over, a more efficient solution would make sense.
Looking forward to what this thread comes up.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Visisthebest on January 29, 2022, 02:04:59 PM
Yacine yes, because a user can drop another shape with another master on the page at any time, I simply have to recheck as the set of Masters on that page may have changed since last time. So that can become quite CPU-intensive, especially in an add-in that has to go 2000 times across the COM interop (which is slooooooooow).

Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Surrogate on January 29, 2022, 02:08:45 PM
Not elegant, but fastest way without code.
Quote from: David J Parker (https://mvp.microsoft.com/en-us/PublicProfile/21090?fullName=David%20John%20Parker) in article More secrets of the Visio Legend shape (https://bvisual.net/2017/02/09/more-secrets-of-the-visio-legend-shape/)was going to do a full post on the special Legend shape in Visio that can automatically count instances of masters on a page, then I found that my good friend Chris Roth, aka VisGuy, had done one some years ago ( see visguy.com/.../legend-shapes (http://www.visguy.com/2006/11/20/legend-shapes/)).
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Visisthebest on January 29, 2022, 02:27:17 PM
Very interesting possibility Surrogate thank you, to check out how they Legend shape does this, in Chris' article he mentions:

- The Legend shape helper add-on

Is there a special add-on running in the background for this? (Ideally this is just using the shapesheet no code, which would be even better just didn't realize it was possible!)
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: wapperdude on January 29, 2022, 03:41:32 PM
The looping process might be improved in a couple ways...
1) create an index, aka, a list of known masters for each page.
2) use an event that triggers when a shape is dropped.  Compare to existing list of known masters for page in question.

Note, it's been awhile (years), but this might be what legend shape does.  The legend is an actual shape and requires being added to each page.  Do you need some sort of reprort?  I'd presume so.  Not sure if Legend, as exists, accommodates that.  Just don't recall at the moment.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Yacine on January 29, 2022, 03:44:19 PM
Quote from: Visisthebest on January 29, 2022, 02:04:59 PM
... especially in an add-in that has to go 2000 times across the COM interop (which is slooooooooow).

my very first thoughts on this:
Check the bottle neck and transpose the heavy lifting operations to visio. several thousand loops are not a deal nowadays. Having different applications deal with individual checks may however take muuuuch longer.
Invistigate the possibilities of (1) "call MacroName" and (2) of "getresults"
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Yacine on January 29, 2022, 03:51:44 PM
@ Wayne,
I did also play with the idea, since Visio is already doing this with other "entities" like Connections (where it doesn't check for whether shapes are connected, but stores the data in a separate object, namely "connections").
The difficulty resides in catching "every" so little event that may happen to the collection - creation, editing, replacement, deletion, ... whatever!
     .... probably feasible, but definitely tedious!


PS: also, where to store the result? In the document's shapesheet? maybe.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Paul Herber on January 29, 2022, 04:02:25 PM
The Legend shape, not easy to find, does activate an addon, called "lgnd", you can find the activation in the Legend shape's Event Drop cell:
=RUNADDONWARGS("lgnd","/cmd=cmd1")
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Visisthebest on January 29, 2022, 04:18:51 PM
Thank you Yacine and Paul, yes maybe some highly optimized code. Good to know the legend uses an addon!
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: wapperdude on January 29, 2022, 04:36:32 PM
@Yacine, et all,
"Tedius":  isn't that what code is for???   :o.  ;D.

Yeah, catching right event might be a challenge.  Perhaps, the Indexing also includes some sort of master count per page.   Then, when doc closes, an update is performed.  Perhaps this is only time, rather than the immediate, event propelled technique???  Perhaps the events merely identifies a page to be re-indexed? His might minimize the amount of looping.

Also, what if a shape has no "master", then what?

WRT to storage...
1) Could be Doc shapesheet.
2) could be each page shapesheet. This might accommodate, restricted looping.  That is, if there's a " page changed" event, then that page is updated???
3) external, as a backup???, to database type thing?

Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Paul Herber on January 29, 2022, 04:46:24 PM
The Legend shape only counts certain types of shape, I'm not at all sure what the criterion is. Sorry, let me re-phrase that - I have absolutely no idea what the criterion is.

Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Paul Herber on January 29, 2022, 04:53:54 PM
Correction to the above - the Legend shape only counts shapes which contain the cell User.visLegendShape when the shape is dropped on the page or the shape is duplicated.
Grouping and ungrouping can confuse it though.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: wapperdude on January 29, 2022, 04:58:14 PM
Ah!  What about CONTAINERS!?!

Each page could have one, full page encompassing container.  There are some shape sheet container related functions.  Well, OK, only half serious about this.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Yacine on January 29, 2022, 05:33:05 PM
To consider upcoming solutions one might set up a reasonable big document to compare the times.
Say 10k shapes? More? A mix of simple and master related shapes.
Check the enclosed file.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Paul Herber on January 29, 2022, 05:42:16 PM
Of course, I have such a feature in my Visio Utilities!
https://www.paulherber.co.uk/visio-utilities/ (https://www.paulherber.co.uk/visio-utilities/)
ribbon
SuperUtils -> Page -> Count Shapes on Page
or
SuperUtils -> Document -> Count Shapes in Document

Time to count ~ 10000 shapes - about 0.5s
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Yacine on January 29, 2022, 05:56:08 PM
@Paul, does your routine loop over the shapes or does it use another clever way?
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Paul Herber on January 29, 2022, 05:59:07 PM
Iteration.
Loops.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: wapperdude on January 30, 2022, 01:24:51 AM
For those unfamiliar with the legendary Legend shape, see attached.

Initially, a shape may be "registered" by merely dragging it onto the Legend, and agree to "terms".  Then move it off the Legend.  Subsequently, duplication will increment the count, deleting will reeduce the count.  If the shape is completely deleted, it is de-registered and removed from the Legend.  Perhaps not the handiest "tool" in the ol' shed.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Surrogate on January 30, 2022, 06:39:49 AM
Quote from: Surrogate on January 29, 2022, 02:08:45 PMfastest way without code.
Not totally without code, but without iteration all shapes at page!
This code iterate Legend shape's sub-shapes at active page and create its output.
Sub ttt()
Dim lgnd As Shape, SUBSH_COUNT As Integer, n2 As Integer, n3 As Integer
Set lgnd = ActivePage.Shapes("LEGEND")
SUBSH_COUNT = (lgnd.Shapes.Count - 4) / 3
For i = 1 To SUBSH_COUNT
n3 = 3 * i ' Inner shape number from 3rd column
n2 = 3 * i - 1 ' Inner shape number from 2nd column
Debug.Print lgnd.Shapes(n3).Text, lgnd.Shapes(n2).Text
Next
End Sub

QuoteRectangle     1
Square        1
Circle        3
Diamond       1
Drop          7
Chevron       1
Master.17     5
Pentagon      1
Cube          1
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Croc on January 30, 2022, 08:57:15 AM
I tried creating a list of masters on pages using Power Query. At first glance it works fine.
Excel gets this list from the Visio package file.
I am not an expert in Power Query, so the solution may seem ridiculous. Made it just for testing.
I am attaching the file with queries.
The name of the Visio file must be set on the Path sheet.
See the result after the refresh on the MastersOnPages sheet.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Croc on January 30, 2022, 08:58:48 AM
picture
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Yacine on January 30, 2022, 11:13:23 AM
@Croc, awesome!
Not that much for this particular task, but doing "surgery" on an office file with powerquery opens a whole world of possibilities.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: wapperdude on January 30, 2022, 03:08:03 PM
Oh no! :P. Now I have to discover Power Query.  :o. Help!  Boat is taking on water.   ;)
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Croc on January 30, 2022, 03:13:20 PM
Yes, it's a good tool. But unfortunately, in addition to knowledge of Visio, it also requires knowledge of the relationships between elements in the Visio package file. And these relationships may not be very simple.
In particular, for the list of masters, it was necessary to form requests to three different files, and then merge the results together.
By the way, a special utility can be useful for studying the components of a Visio drawing in package format. (At the end of the article https://visioport.ru/blog/index.php/32-visio-package-helper there is a link to its installer).
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: wapperdude on January 30, 2022, 03:38:10 PM
Package format... feels like Quantum Mechanics.  I'm more of a Classical based guy.  Long live Sir Isaac Newton!  Where'd that apple get off to?
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Visisthebest on January 30, 2022, 04:49:17 PM
Thanks everyone for all the ideas, probably will brute-force loop through all the shapes on a page as an initial solution then see if there are some simpler optimizations possible.

The legend shape is a fascinating option, and very useful by itself.

I am still grappling with the behavior of Master shapes a bit, I understand they are timestamped in the stencil. If I don't change a master, and the same stencil is used, will there never appear a second master of the same shape in the document stencil or are there some exceptions to this? If I can count on there only being one Master of a shape given these conditions (same stencil of the same date, Master never changed) that would be very useful to know as well.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Paul Herber on January 30, 2022, 06:09:16 PM
No timestamping (as far as I know), and Visio will always use the copy of the master if it is available. But, if there is any change made to the master, then adding a new instance from the stencil will create a new master, not use the modified one.
So, if you drop 3 Rectangle shapes from the Basic Shapes stencil on to the page, there will be one Master called Rectangle in the masters collection. If you now edit that master in any way then it is not the same shape that you originally dropped on the page. If you now drop a new Rectangle from the Basic Shapes stencil then it will create a new master called Rectangle.1 or similar.
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Visisthebest on January 31, 2022, 11:12:56 AM
Thank you Paul good to know, that is the behavior I expected.

For updating shapes (with other formulas in some cells), I am still considering whether to update the document stencil master or just change the shapes themselves. (Sometimes that means about 500 shape updates, but this doesn't happen regularly).

I wonder how much performance gain updating via the Master provides (so the shapes are updated via the master the inherit) when 500 shapes are updated (typically an update is to about 10 simple formulas per shape, and I bundle the updates cross the interop in one SetFormulas per shape).

The file being a bit larger is not really a concern but performance is if it is a big difference.

https://docs.microsoft.com/en-us/office/vba/api/visio.shape.setformulas
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: vojo on February 02, 2022, 02:25:59 AM
doc stencil?
Title: Re: What is the most elegant/fastest way to get all Masters used in a page
Post by: Visisthebest on February 02, 2022, 09:46:27 AM
Yes they are all in there vojo, the question is how do you filter out all the Masters that are used on one page (and only those Masters). Visio doesn't seem to offer specific functionality for this.