Visio Guy

Visio Discussions => Programming & Code => Topic started by: miless2111s on March 14, 2022, 12:41:40 PM

Title: Making a flexible shape, driven by Excel
Post by: miless2111s on March 14, 2022, 12:41:40 PM
I want to be able to vary the shape displayed in Visio from a rectangle to Triangle to a star shape etc. I currently plan to do this by defining where I want each "corner" to be in the Shape Geometry in Excel and passing that information across. My plan is (was?) that I would have the maximum number of corners set up for the most complex shape and if I didn't need any then the spare ones would be "parked" at either the origin or last position.

This works well except when the shape has some rounding applied to it. At this point, the spare corners prevent the rounding so you end up with a lopsided shape :( It isn't so bad I park the spare ones on a line (say at height*0, width*0.5) but when the shape gets small enough these do start to cause uneven rounding.

Does anyone have any ideas on how to do this better?  Options I have considered (but am unsure how exactly to do):
* Have a user-triggered macro that either trims out the surplus corners OR puts them back in if needed
* A macro that runs every time the data is uploaded from Excel which defines the shape needed.  The disadvantage here would be that the updates would take longer as more code would be running
* A macro that runs if the shape designation field (a user data field) changes - can Visio do "if this changes then run macro" type triggers?  Does this impact the speed in the same way that such a macro slows down excel as it is always looking for a change?

Many thanks in advance for your help.
Title: Re: Making a flexible shape, driven by Excel
Post by: Surrogate on March 14, 2022, 01:13:11 PM
I can't imagine why you would want to do that?
WOW !
Quote from: miless2111s on March 14, 2022, 12:41:40 PM
I want to be able to vary the shape displayed in Visio from a rectangle to Triangle to a star shape etc. I currently plan to do this by defining where I want each "corner" to be in the Shape Geometry in Excel and passing that information across. My plan is (was?) that I would have the maximum number of corners set up for the most complex shape and if I didn't need any then the spare ones would be "parked" at either the origin or last position.
Rectangle/Triangle/Star in separate Geometry sections ?
Title: Re: Making a flexible shape, driven by Excel
Post by: Paul Herber on March 14, 2022, 01:41:26 PM
I can imagine a generic 'Shape' shape with a menu to select which one you want. Bear in mind though that the shape's name won't (and can't) change with the selection.
Title: Re: Making a flexible shape, driven by Excel
Post by: vojo on March 14, 2022, 01:49:19 PM
Several options
1)  pass vertex values to user cells ==> use user cells as part of geometries
         Geometry1.x2 = geometry1.x1 + user.x2 cell
2)  Geometries for square, another for triangle, another for circle...excel uses user cell to decide which to show and which to hide
         geometry3.noshow = not(user.showhide).
3)  use user cells to have complete geometry formulas
          geometry1.x2 = user.xxx2 cell

BTW,
if you want behavior to affected by some other shape, you can use LOCTOLOC or LOCTOPAR functions in geometries
If you want to also allow some UI support, then use some of the SETEXPR(<blah blah blah>) functions
Title: Re: Making a flexible shape, driven by Excel
Post by: Visio Guy on March 14, 2022, 03:49:42 PM
If you want to foil rounding, just double-up the vertexes and the rounding won't show. You can selectively turn rounding on and off for shapes this way. Just double-up the vertices where you don't want rounding.

Also, be sure to take a look at More Shapes > Visio Extras > Drawing Tool Shapes. There you'll find the "Multigon edge" and "Multigon center" shapes. Right click to change from triangle to octagon!

Title: Re: Making a flexible shape, driven by Excel
Post by: Yacine on March 15, 2022, 08:29:18 AM
Quote from: miless2111s on March 14, 2022, 12:41:40 PM
... My plan is (was?) that I would have the maximum ...


I would warn from too complexe shapes. Always keep maintenance in mind.
Either (1) write a macro to build the maximum shape or (2) make it configure itself.
I'm using for over a decade a self built solution where I have base masters with several fixed list props. The lists contain the names of masters suitable for being inserted in the base shape.
A "callthis" will send the values to a macro which deletes the content of the base shape and re-inserts the sub-shapes chosen.
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 15, 2022, 10:36:33 AM
Quote from: Paul Herber on March 14, 2022, 01:41:26 PM
I can imagine a generic 'Shape' shape with a menu to select which one you want. Bear in mind though that the shape's name won't (and can't) change with the selection.
To be honest I need the shape name to stay the same so that it remains linked to the source data which tells Vision how big it should be and where on the page it sits.  Could the "shape" macro be triggered by changes in the data driving the shape or would you see this as a manual selection?  Would it be possible to select multiple shapes at once to change or would I need to change each one individually?
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 15, 2022, 10:39:42 AM
Quote from: Visio Guy on March 14, 2022, 03:49:42 PM
If you want to foil rounding, just double-up the vertexes and the rounding won't show. You can selectively turn rounding on and off for shapes this way. Just double-up the vertices where you don't want rounding.

Also, be sure to take a look at More Shapes > Visio Extras > Drawing Tool Shapes. There you'll find the "Multigon edge" and "Multigon center" shapes. Right-click to change from triangle to octagon!

Thanks for the tip about the Multigon shapes I will have a look at these.   The issue with rounding is that I want to allow it :)  Sometimes a rounded rectangle is far nicer than a sharp cornered one, the issue comes when I have a rectangle with all the "unused" corners piled up in the bottom left then this corner can't round which just looks odd.   Mind you your suggestion explains how to do the rectangles with two rounded and two sharp edges so thanks for that one! :)
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 15, 2022, 10:44:29 AM
Quote from: Surrogate on March 14, 2022, 01:13:11 PM
I can't imagine why you would want to do that?
WOW !
Quote from: miless2111s on March 14, 2022, 12:41:40 PM
I want to be able to vary the shape displayed in Visio from a rectangle to Triangle to a star shape etc. I currently plan to do this by defining where I want each "corner" to be in the Shape Geometry in Excel and passing that information across. My plan is (was?) that I would have the maximum number of corners set up for the most complex shape and if I didn't need any then the spare ones would be "parked" at either the origin or last position.
Rectangle/Triangle/Star in separate Geometry sections ?

This is how I have started to test it, this can't do a star yet but in this configuration, it changes a rectangle into a Chevron with the degree of indent controlled by Excel rather than being a function of the length which just looks silly.
https://imgur.com/iJqkVrs
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 15, 2022, 10:45:37 AM
Quote from: vojo on March 14, 2022, 01:49:19 PM
Several options
1)  pass vertex values to user cells ==> use user cells as part of geometries
         Geometry1.x2 = geometry1.x1 + user.x2 cell
2)  Geometries for square, another for triangle, another for circle...excel uses user cell to decide which to show and which to hide
         geometry3.noshow = not(user.showhide).
3)  use user cells to have complete geometry formulas
          geometry1.x2 = user.xxx2 cell

BTW,
if you want behavior to affected by some other shape, you can use LOCTOLOC or LOCTOPAR functions in geometries
If you want to also allow some UI support, then use some of the SETEXPR(<blah blah blah>) functions

how do you do 2 and 3?  I am not aware of having different Geometries...
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 15, 2022, 10:47:30 AM
Quote from: Yacine on March 15, 2022, 08:29:18 AM
Quote from: miless2111s on March 14, 2022, 12:41:40 PM
... My plan is (was?) that I would have the maximum ...


I would warn from too complexe shapes. Always keep maintenance in mind.
Either (1) write a macro to build the maximum shape or (2) make it configure itself.
I'm using for over a decade a self built solution where I have base masters with several fixed list props. The lists contain the names of masters suitable for being inserted in the base shape.
A "callthis" will send the values to a macro which deletes the content of the base shape and re-inserts the sub-shapes chosen.
If I have understood you correctly I think this was the basis of the idea that a macro would add / remove the vertexis needed for the requested shape.  Would you see this as triggered for each shape manually or something that could be triggered by the data being passed to the shape?
Title: Re: Making a flexible shape, driven by Excel
Post by: vojo on March 15, 2022, 12:50:39 PM
turn on developer mode  (is in file ==> options ==>at the bottom)
right click shape, open shapesheet
on the menu, you can add /delete sections and add / delete rows.

I think help for all the cell functions can be accessed by help
Title: Re: Making a flexible shape, driven by Excel
Post by: wapperdude on March 15, 2022, 02:22:34 PM
See this post for multiple shapes in a single entity.  It does more than you need because of the connectors, but over the idea.  http://visguy.com/vgforum/index.php?topic=6897.msg28789#msg28789 (http://visguy.com/vgforum/index.php?topic=6897.msg28789#msg28789)

Note:  no "parking" needed.  Also, it doesn't use VisioGuys' no rounding technique.
Title: Re: Making a flexible shape, driven by Excel
Post by: Yacine on March 15, 2022, 03:57:50 PM
Quote from: miless2111s on March 15, 2022, 10:47:30 AM
If I have understood you correctly I think this was the basis of the idea that a macro would add / remove the vertexis needed for the requested shape.  Would you see this as triggered for each shape manually or something that could be triggered by the data being passed to the shape?

1) Sorry for having misunderstood your question,
2) Triggered by the data - dependson(prop.soandso) + callthis(...)


PS
I'll try these days to upload a forum version of my tool.
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 18, 2022, 10:57:57 AM
Quote from: Yacine on March 15, 2022, 03:57:50 PM

2) Triggered by the data - dependson(prop.soandso) + callthis(...)


Can I check my understanding of this as this is the first time I have come across this....  If I have a user-defined cell that contains a text string (say "5 pt star") and this stays the same no macro is triggered however if the text changes during an update the macro will be called?  If this understanding is true then it would mean that the performance impact of having a macro that changes the shape on demand would be very low as it wouldn't be running on hundreds of shapes each time I run an update (the diagram has some 1,200 shapes which are updated by Excel)
Title: Re: Making a flexible shape, driven by Excel
Post by: vojo on March 18, 2022, 02:31:45 PM
the "prop.soanso" is specific to this given shape.

So
- if the value in that cell comes from sort of global or page level cell...and that cell changes...then the macro trigger
   for example, if "soandso" is loaded with "5pts star" from some global cell...then ALL shapes would have macro trigger.
- if the value is specific to this shape, then only this shape macro would trigger.
   for example, if "soandso" for shape sheet.123  is changed....but all other shapes unchanged...on sheet.123 macro triggered
- if the value is specific to a group of shapes, then only these shapes' macros trigger
   for example if "soandso" for sheet.123, sheet.456, sheet.789....then only these 3 shapes  will have their macros triggered

So using excel VBA, you could stage which shapes get updated....stars at 11:00    circles at 12:00   squares at 1:00
Title: Re: Making a flexible shape, driven by Excel
Post by: wapperdude on March 19, 2022, 12:44:24 AM
To minimize confusion, I re-worked the single shape, multiple geometry file to eliminate unnecessary entries.  Plus, added a star shape.
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 21, 2022, 11:26:08 AM
Quote from: wapperdude on March 19, 2022, 12:44:24 AM
To minimize confusion, I re-worked the single shape, multiple geometry file to eliminate unnecessary entries.  Plus, added a star shape.
This looks interesting, I am just struggling to understand how it is working :)  More googling required I suspect :)   What are the ,0,1) in the Geometry1.noFill?  I understand the OR(User.shpGeo =1 etc but I am a little confused as to the 0 and 1 :)  This appears on all the Geometry tables...

modified to add:
I think I may have worked it out - is this to make it "False" so that the shape can fill?  If so why would you ever have it set to True, i.e. 1 or is this the mechanism to hide the unwanted Geometry table results?

Further edit - maybe I should go to spec savers? :)  I guess the show / no show is controlled bu the .NoShow setting?

If I have understood this method correctly the approach is that there are any number of Geometry tables in action however the Fill and Show settings control which one is actually visible or can be interacted with?
Title: Re: Making a flexible shape, driven by Excel
Post by: Surrogate on March 21, 2022, 11:55:55 AM
Hope this article can helps: The Hidden World of Visio Shapes (http://www.visguy.com/2006/09/05/the-hidden-world-of-visio-shapes/)
Title: Re: Making a flexible shape, driven by Excel
Post by: wapperdude on March 21, 2022, 02:24:09 PM
The Show/NoShow determines which geometry section, i.e., shape type is shown.

The Fill/NoFill is a holdover from original shape.  There were connectors, with arrowheads, as part of the shape.   The arrow heads would also show up in the shape border.  Turns out, the fill/nofill also controls their presence.  When I simplified the shape, I didn't remove the setting nor did I reset the line style to no arrowheads.

One more thing about the fill/nofill, if you have multiple, visible geometry sections, you can get a difference fill effect.

As for learning...make a simple, two geometry section shape.  Then, play with the settings to see how they interact.  Also, in the Protection section, for the circle, square, say I lateral triangle, and star geometries, when they're selected, I protect (lock) the aspect ratio.  Finally, in the width / height cells, I use the SetAtRef() formula construction.  There is a topic in the User Category of the forum that has a mini-tutorial on this functionality: http://visguy.com/vgforum/index.php?topic=6383.msg26747#msg26747 (http://visguy.com/vgforum/index.php?topic=6383.msg26747#msg26747)

Hope this helps.
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 22, 2022, 08:49:30 AM
The multiple geometries idea is working really nicely, thank you.
The next challenge is the connection points :)  Now that I have multiple geometries with different vertices and a different number of points overall is it possible to point to the different geometry sections?

I can use an If statement, such as =if(Prop.row_1 = 1, Geometry1.X1, if(Prop.row_1 = 2, Geometry2.X1,if(Prop.row_1 = 3, Geometry3.X1, if(Prop.row_1 = 4, Geometry4.X1,width*0.5)))) however this could get a bit long if I have as many shape options as I think I will :)

I think I have solved this using the following calculation, which "should" include an error catcher for vertices that don't exist, however the Iferror doesn't appear to be triggered and for these "missing" items it appears to be returning width*0 which is odd.

=IF(ISERROR("Geometry"&Prop.Row_1&".X9"),Width*0.5,"Geometry"&Prop.Row_1&".X9")  - i am having to edit each connection point to X1-10 etc as I can't work out how to add a row() type expression in but it isn't too bad to do this :)

Am I doing something wrong or has Visio got a build-in error handle that returns width*o?

Title: Re: Making a flexible shape, driven by Excel
Post by: Surrogate on March 22, 2022, 09:05:35 AM
Quote from: miless2111s on March 22, 2022, 08:49:30 AM
The next challenge is the connection points :)  Now that I have multiple geometries with different vertices and a different number of points overall is it possible to point to the different geometry sections?
Do you mean connection points in the vertices of the shape?
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 22, 2022, 09:16:22 AM
Quote from: Surrogate on March 22, 2022, 09:05:35 AM
Quote from: miless2111s on March 22, 2022, 08:49:30 AM
The next challenge is the connection points :)  Now that I have multiple geometries with different vertices and a different number of points overall is it possible to point to the different geometry sections?
Do you mean connection points in the vertices of the shape?
Yes, the definition of the connection points in the "Connection Points" table in the ShapeSheet:
https://imgur.com/MuY1KxL
Title: Re: Making a flexible shape, driven by Excel
Post by: wapperdude on March 22, 2022, 03:04:30 PM
Unfortunately, Visio has neither the means to add a row nor disable connection points from within  the shapesheet.

One alternative would be to turn on gluing shape vertices.  This would minimize the number connection points needed.  It doesn't help with circles and ovals.   Those would need connection pts if you want specific locations.

Whatever gluing approach you adopt, all "unused" connection points can be "parked" somewhere, say (0,0).  The location must be specifically given. 

An alternative method uses a macro.  The macro could use "case" method; each case being a geometry type.  Then, for each case, 1st delete all rows, then add in just the rows with desired locations.  This would ultimately be cleaner.
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 22, 2022, 03:59:04 PM
I frustrating thing has happened a few times and I wonder if it is user error or just normal behaviour...

Whilst setting up various geometry tables for each of the shapes I have found that when I have finished setting up a shape and got it working the entries in the already established geometry tables change!  Recently I had a rectangle, oval, chevron and lozenge shape working and now I have finished working out how to have a start all the other vertices have changed their formula!  This is somewhat frustrating :)

Is there something that I should be doing to avoid this (having them collapsed or something)?
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 22, 2022, 04:08:47 PM
Quote from: wapperdude on March 22, 2022, 03:04:30 PM
Unfortunately, Visio has neither the means to add a row nor disable connection points from within  the shapesheet.

One alternative would be to turn on gluing shape vertices.  This would minimize the number connection points needed.  It doesn't help with circles and ovals.   Those would need connection pts if you want specific locations.

Whatever gluing approach you adopt, all "unused" connection points can be "parked" somewhere, say (0,0).  The location must be specifically given. 

An alternative method uses a macro.  The macro could use "case" method; each case being a geometry type.  Then, for each case, 1st delete all rows, then add in just the rows with desired locations.  This would ultimately be cleaner.
how do I "trap" the situation where the referenced cell doesn't exist?  At the moment the If(iserror(....) doesn't appear to be triggering an error.

Interestingly when looking at my shape and tracking where the connection points are, for the items which don't have matching vertices I have connection points that appear to be "randomly" distributed through the inside of the shape however they are in consistent positions, rather than the width or height *0.5 which would be caused by the "!iserror" triggering.  Could they be remembering something or picking up some false signals?  They're not causing any concerns but I don't like untidy "features" which I don't understand :)
Title: Re: Making a flexible shape, driven by Excel
Post by: wapperdude on March 22, 2022, 06:10:10 PM
There is only so much that can be done from within the shapesheet.  Here's listing  available functions:  https://docs.microsoft.com/en-us/office/client-developer/visio/iserrna-function (https://docs.microsoft.com/en-us/office/client-developer/visio/iserrna-function).  Potentially, Iserrna were a might be useful.

As your shape has multiple geometries, and given that there's limited shape sheet functionality, it seems the best rout would be to add the max number of connection points and merely park the unused ones.  I don't really believe it's possible to legitimately reference a non-existent row.

Title: Re: Making a flexible shape, driven by Excel
Post by: vojo on March 22, 2022, 09:02:02 PM
if I remember correctly, the connection point row has X Y cells to show hide connection point
for example  0 - 4 = show with various orientations   5 - 9 = hide

I have used this approach to show hid connection points as far back as visio 2003

I have not used it in years, so maybe its another deprecated function (ignored if even presented).

A tedious / partial work around would be something like

Props.connshow = <1/0>
Connections.x1 = guard (if (props.connshow, <some valid geometry>, <some out of the way location>))

Attachment was done around 2005, and it used to show/hide connection points via actions and issnaptarget
it does not seem to work any more

maybe the logic spawns some thinking
Title: Re: Making a flexible shape, driven by Excel
Post by: wapperdude on March 22, 2022, 09:48:57 PM
Control points have that feature, connection points do not.  I was lamenting that lack of development earlier today.
Title: Re: Making a flexible shape, driven by Excel
Post by: miless2111s on March 29, 2022, 08:09:06 AM
Quote from: vojo on March 22, 2022, 09:02:02 PM
if I remember correctly, the connection point row has X Y cells to show hide connection point
for example  0 - 4 = show with various orientations   5 - 9 = hide

I have used this approach to show hid connection points as far back as visio 2003

I have not used it in years, so maybe its another deprecated function (ignored if even presented).

A tedious / partial work around would be something like

Props.connshow = <1/0>
Connections.x1 = guard (if (props.connshow, <some valid geometry>, <some out of the way location>))

Attachment was done around 2005, and it used to show/hide connection points via actions and issnaptarget
it does not seem to work any more

maybe the logic spawns some thinking
Good grief, when I see something like this shape I realise that I am dabbling in the edges of a deep pond!  Very impressive :)
I am a little confused by the connection point control though, when I display the Connections table I only see one connection however there are many more on the shape - am I looking in the wrong place?
Title: Re: Making a flexible shape, driven by Excel
Post by: vojo on March 29, 2022, 03:58:13 PM
I always use the shapesheet...there is a section wiht all the connections defined.

the spacing is based on the spacing of the base
The show/hide based on issnaptarget

This is a group of shapes (only way to have multiple colors).  I believe the connections are at group level
but may actually be in one of the child shapes.