Visio Guy
Visio Discussions => ShapeSheet & Smart Shapes => Topic started by: perry59 on July 18, 2013, 03:37:00 PM

are there similar examples for what I want to do?
and that is this:
I want to create a very simple shape, just a tall narrow rectangle with some circles inside it (this will represent a "bus bar").
however, when dragging this shape onto the drawing I would like the user to be prompted how many terminals it should have (the circles) then it would elongate itself to accomodate that number of evenly spaced circles. Also, it should prompt if this is a full bus or a partial bus. The partial bus will have a jagged bottom to indicate a break.
I guess this would be a "smart" shape with some enhancements to the shape sheet.
are there any examples that might get me started?
thanks

Here was a thread recently about a ladder or fence shape where the number of rungs(?) or fence posts depended on the length of the shape. One possible solution was to use a Fillpattern to generate the circles.

Well, I'm part way there. I have a "bar" which grows in length depending on a value in custom properties.
I just don't know how to copy or array my circle object based on that value. Is it even possible? If that is not possible, could I draw all the circles into my grouped shape and hide a number of them based on the aformentioned value? How could this be done?
(did a search for "ladder" and "fence", didn't find anything)

Here's an article about line patterns. Fill patterns work similar to that:
http://www.visguy.com/2008/03/03/releasethepowerofvisiocustomlinepatterns/
The other method is your suggested one:
 Give Bar shape a userdefined cell: User.Circlenumber.
 Place a formula in that cell, that calculates the number of visible circles depending on the length of the shape or the value in your ShapeData property, that defines the length.
 Draw the maximum number of circles you need and group them to your bar shape.
 Give each a custom property or user defined cell with it's number/position, for example User.Number.
 Make another userdefined cell: User.Visible.
 Inside a formula ala =(Sheet.123!UserCirclenumber>=User.Number)
 where Sheet.123 is the name of the group shape / bar shape.
 That formula is true when the number of needed circles is equal or bigger than the number of the actual circle.
 In Shape geometry of circle shape,in NoShow cell place a formula =not(User.Visible) to hide the shape, when number of needed circles is lower then the shapes number.
 Place a formula in widthcell that places the circle on position one when invisible and on position n when visible, ala:
=10mm+If(User.Visible,(User.Number1)*5mm,0mm)
 Above formula places the first circle at 10mm and ever other circle 5mm after the previous one.

Thanks for the info Jumpy!
hope to get a chance to try that out this afternoon. Will report back on progress.

Its getting there!
The number of circles (terminals) increases or decreases when I change my "number of terminals" property, so thats cool. I just need to come of with a formula to evenly space them within the confines of the rectangle (bus) and it needs to be relative to the height of the bus in case the user stretches it. (that number is in the "Piny" cell) For that reason I did not use the last portion of jumpy's suggestion (I also saw no reason to move the circles into position on a change in the bus height, just making them visible seems to work fine, and why is it in the width cell?).
One thing that is giving me a hard time now is adjusting sizes, whats up with visio here? \
for example, my formula for the height of the bus is "terminal count +1", so if termina count is 1 then the bus size should be 2 (this is in inches BTW). But the bus is only 1 inch, and with each increase in the number of terminals, instead of growing by 1 inch, it grows by only a half inch. What the heck???

Visio shapes are typically based upon width and height units. So, shape sizes are multiples of these numbers. If the initial width and height are correct, then, incrementing the shape in terms of multiples of these numbers should produce the desired result. Note, these changes are typically done in the Geometry sections.
Another approach to building this shape is multiple geometry sections  one for each circle. Each geometry section would have the circle preplaced in the desired location but it's visibility would be toggled off. The rectangle would be an additional section, and it's dimensions controlled by the number of circles. Some Visio shapes use this technique.
Other precautions that you might want to consider to prevent your shape from getting tweaked:
1.) put a guard function around the width, height numbers.
2.) in the Protection section of the shape sheet, you might want to set the LockCalcWH cell to 1.
Wapperdude

Yes, I realizied that when my grouped shape was at its smallest formula size (terminal count +1) the shape was an inch too short. I physically drug the shape to the correct length and after that it increased/decreased length as expected :)
I am not familiar with geometry sections, are there some examples I could look at?
as far as protecting the shape, I want it and its contents to stay the same relative to one another, but I would like to be able to drag/resize the shape. Is this possible?

First: I'm sorry for the confusion with the formula in the width cell. It should have been the PinX cell.
The reason why I suggested placing the circles in a different place when invivible is, that otherwise (if the circles always stay at their position) they are outside of the boundaries of the shape, when the shape is small and the circles are invisible.
There are for example VBAfunctions out there, that could be confused by that.
As for protecting your shape:
You could for example only protect the width of your shape, so it can only resize in xdirection with your formulas, but you can leave the height without guard, so you can manually resize it.
If you don't protect PinX/Y, dragging is still possible.
If you get better with the shapesheet, you could for example allow the manual resizing of the width, too. With formulas in the shapesheet, you could adjust the shape after the dragging, so the width can only get values, that are multiples of a certain basevalue. And depending on the width you could than calculate your circles.

the position of the circles are determined by a formula, so as the shape gets smaller the circles get closer (and some disappear)
I also locked the aspect ratio of the group, so if you drag to make it taller, it gets wider as well, the circles also change size.

It seems to be working pretty good now except for one thing:
if the shape/group is dragresized it trashes the formula for height and width and replaces them with explicit numbers, so if you later change the number of terminals (through the custom property) the number of terminals change but the size of the overall shape does not!
This occurs even after I put "GUARD" on those formulas!
how can I allow user resizing without messing up my height formula?

There are 2 possible solutions to this:
First, best and more difficult: There's a family of shapesheet functiones the SetAtRef functions. Here is the basic one:
http://msdn.microsoft.com/dede/library/office/ff765523.aspx
They are difficult to understand, but are usefull in your situation here, but because they are difficult to use, it's to difficult for me to explain. But there were good examples in Graham Wideman's Visio Survival Kid book.
Another solution could be the following:
Make a new user defined cell, User.Control for example, place in there a formula:
=DEPENDSON(Prop.YourCustomPropCell)+SETF(GetRef(Width),"Your formula to calculate the width as String")
or
=DEPENDSON(Prop.YourCustomPropCell)+SETF(GetRef(Width),The calculated value using the formula)
In a similar way you can react to the manual resizing of the shape to allow only discrete values for the width and to change the custom property depending on the width. So the opposite way to the above one.
That could lead to a loopsituation that Visio normaly should be able to resolve. If not: That's why professionals (not me) would use the SETATREF functions.

Thanks for the info Jumpy.
I'll try those suggestions and see what happens. Do you know of any shapes I can download that demonstrate some of those functions that I could examine?

The shape is resizing as I wish, without the use of SETATREF (which I couldn't get to work right), the only problem is that if the user double clicks it to bring up the custom properties and changes the number of terminals the shape does not shrink or grow to accomodate that. Is there a way I can get the shape to recalculate its size (which are in user cells) when a custom property changes?

What is with a modificated version of the tip above:
=DEPENDSON(Prop.YourCustomPropCell)+SETF(GetRef(Width),The calculated value using the formula)
in a user defined cell.
Dependson fires the SETFfunction when the value of the property changes.
SETF sets the cell in GETREF() to the desired value or formula.

I did finally try the "dependson" formula after getting frustrated with the others. Should have tried that first because its doing what I want! had to tweak my with formula a bit, but working as good as I think I'll ever get it. Pretty cool stuff!
Thanks Jumpy :)