Design-Drawing Home  
Drawing Program
ISSN 1441-5585

Search...

Home
Articles
Software Catalog
Book Store
About
Advertising
Newsletter

 

 

Floatin' In The New Year

(Hogmany Treats)

David A Edson

Greetin’s tae ye a’!!! I hope tha’ yer Holidey season was e’er sae grand! Weel noo tha’ the New Year is upon us I am sure that ye a’ are set to make yer resolutions. Mine is tae find e’en more brilliant tips an’ tricks to assist ye in yer development efforts with Visio and tae increase Visio usage worldwide.

Floatin’ Points…
To that end I have just finished readin’ a letter frae a lad who has been usin’ Visio an’ he writes…

"Connection points placed in a sub-element of a "grouped" shape are not visible to the user. Connection points placed at any level in a group should "show through" (some sort of automatic "inheritance" to the group level ShapeSheet??), and be both visible and usable to the user. Is this possible using Visio 5.x?"

Weel lads an’ lassies, consider this ma Hogmanay giftie tae ye!!! Even though Visio does not do this natively under Visio 5.x, the task can still be accomplished. I’ll walk you through the entire process and you will leave with the ability to add this little utility to your "kit" and use it at any time you need.

I have devised this wee VBA code module so that it is usable on any selected shape. The general concept is as follows:

First look for a selected shape. Is there one selected? If not, end, if there is, then continue.

Next check to see if the selected shape is a group shape. Is it a group? If not, end, if it is, then continue.

Next check to see how many sub-shapes the group contains.

For each sub shape:

Check to see if the sub shape has any connection points. Does it have any connection points? If not, go on to the next sub shape, if yes, then continue.

Next check how many connection points the sub shape contains.

For each connection point in the sub shape:

Map the connection point in the sub shape up to the same position on the sub shape’s parent shape, i.e., the group shape.

Go to the next row until all rows have been mapped.

Go to the next sub shape until all sub shapes have been checked.

Gracefully end.

Remember that each shape has it’s own Cartesian coordinate system. Unless every shape has its Pin at the lower-left-hand corner of the shape and all of the pins are coincidental and none of the shapes have been rotated or flipped, this could be a bit of a problem when dealing with multiple sub shapes in a group. Weel ne’er fear lads an’ lassies!!!! Visio has taken care of that. The ShapeSheet in and SmartShape symbol has a pair of functions to map the coordinates from one scoping level to the next. These are the LOC() and PNT() functions.

The LOC() Function
Syntax LOC(point)

Returns the x,y coordinates of point measured from the lower-left corner of the shape's selection rectangle. In Visio, a point is a single value that embodies a pair of x- and y-coordinates.

Example - LOC(PNT(Sheet.5!LocPinX, Sheet.5!LocPinY))

In this expression, PNT converts a set of coordinates in Sheet.5 to a point. (Sheet.5 is another shape on the same drawing page.) LOC then converts the point to a set of coordinates in relation to the lower-left corner of the selection rectangle of the current shape.

The 5 in Sheet.5 is the ID number for the shape, which is displayed in the Special dialog box.

The PNT() Function
Syntax PNT(x,y)

Returns the point represented by the coordinates x and y as a single value. Converting coordinates to points allows you to change a shape's geometry without having to manipulate x- and y-coordinates separately.

Example - PNT(PinX,PinY)

Returns the point represented by PinX and PinY.

Now Presume that the group shape’s ID is Sheet.4 and the first sub shape’s ID is Sheet.5. In order to map the Connections.X1 and Connections.Y1 of Sheet .5 up to Sheet .4, Sheet.4’s Connections.X1 and Connections.Y1 cells would contain the following formula:

=LOC(PNT(Sheet.5!Connections.X1,Sheet.5!Connections.Y1))

Remember that with each copy and/or drop Visio will take care of resolving the subsequent Sheet.n reference.

A’richt… on tae the code!!!
I’ll declare a new function in VBA by selecting Insert > Module from the pull-down menu in the VBA IDE ( the Visual Basic for Applications Integrated Development Environment) in Visio. I bring up the VBA IDE by pressing Alt+F11 at the same time.

In the new Module1 window I type in:

Public Sub Float_Conns () and then press the enter key.

VBA will finish the Subroutine construct by adding the End Sub on the next line.

Between these two lines we enter the following code…

Public Sub Float_Conns()
Dim shGrpShape As Visio.Shape ' The Group Shape
Dim shSubShape As Visio.Shape ' A Sub Shape of the Group
Dim ceSubShapeCellConnX As Visio.Cell ' ConnectionsX Cell in the Sub Shape
Dim ceSubShapeCellConnY As Visio.Cell ' Connections Y Cell in the Sub Shape
Dim ceGrpShapeCellConnX As Visio.Cell ' Connections X Cell in the Group Shape
Dim ceGrpShapeCellConnY As Visio.Cell ' Connections Y Cell in the Group Shape
Dim intSubShapeCounter As Integer ' Counter for Sub Shapes
Dim intShpNxtCounter As Integer ' Counter for Next Sub Shapes in the Group
Dim intRowCounter As Integer ' Row Counter
Dim intRetValFromAddRow As Integer ' Row Number Index Integer
Dim stRepString As String ' Storage for Formula String

If Visio.ActiveWindow.Selection.Count > 0 Then
' If something has actually been selected
Set shGrpShape = Visio.ActiveWindow.Selection.Item(1)
' get a reference to the one shape that needs to get the connection points
If shGrpShape.Type = visTypeGroup Then
' if that shape is in fact a group
intSubShapeCounter = shGrpShape.Shapes.Count
' find out how many sub shapes there are
If intSubShapeCounter > 0 Then
' if there is at least one sub shape in the group
For intShpNxtCounter = 1 To intSubShapeCounter
' begin spinning through each sub shape
Set shSubShape = shGrpShape.Shapes.Item(intShpNxtCounter)
' get a reference to the 'n'th sub shape in the group
If shSubShape.SectionExists(visSectionConnectionPts, 0) < 0 Then
' if the sub shape does indeed have connection points on it
For intRowCounter = visRowExport To shSubShape.RowCount(visSectionConnectionPts) + visRowExport - 1
' for each connection point on the sub shape
Set ceSubShapeCellConnX = shSubShape.CellsSRC(visSectionConnectionPts, intRowCounter, visX)
' get the sub shape's Connections X cell reference
Set ceSubShapeCellConnY = shSubShape.CellsSRC(visSectionConnectionPts, intRowCounter, visY)
' get the sub shape's Connections Y cell reference
intRetValFromAddRow = shGrpShape.AddRow(visSectionConnectionPts, visRowConnectionPts, visTagCnnctPt)
' use the AddRow method of the group shape to add a Connections row to the group shape
' note that this method first looks to determine if the section exists,
' if it does not it creates the section
'then creates the new row, if it already exists, it simply creates the new row

Set ceGrpShapeCellConnX = shGrpShape.CellsSRC(visSectionConnectionPts, intRetValFromAddRow, visX)
' get a reference to the group shape's new connection X row
stRefString = "=LOC(PNT(" & shSubShape.Name & Chr(33) & ceSubShapeCellConnX.Name & "," & shSubShape.Name & Chr(33) & ceSubShapeCellConnY.Name & "))"
' build a formula to transform the subshape's Connection X row formula
' into it's parent's (the group's)
' coordinates and reference it in the group's cell
ceGrpShapeCellConnX.Formula = stRefString
' stuff the formula to the group shape's Connection X cell
Set ceGrpShapeCellConnY = shGrpShape.CellsSRC(visSectionConnectionPts, intRetValFromAddRow, visY)
' get a reference to the group shape's new connection Y row
stRefString = "=LOC(PNT(" & shSubShape.Name & Chr(33) & ceSubShapeCellConnX.Name & "," & shSubShape.Name & Chr(33) & ceSubShapeCellConnY.Name & "))"
' build a formula to transform the subshape's Connection Y row formula
' into it's parent's (the group's)
' coordinates and reference it in the group's cell
ceGrpShapeCellConnY.Formula = stRefString
' stuff the formula to the group shape's Connection X cell
Next intRowCounter
' go to the next sub shape row if possible
Else
End If
Next intShpNxtCounter
' go to the next sub shape if possible
Else
End If
Else
End If
End If
End Sub

You will note here that I have made use of the Visio constant symbols for various require arguments.

visSectionConnectionPts, visRowConnectionPts, visTagCnnctPt, visX, visY, visRowExport

You can look these up in your Visio documentation. I would tell you that it is a good idea to use the constants, but that would be such an understatement that I can only tell you ALWAYS use the Visio constants!!! De yersel’ a favour an’ trust me on this, aye?

So… the general usage is as follows:

Select a Group Shape where the connection points have become buried down within.

In Visio select Tools > Macros > Module1 > Float_Conns

Watch the points appear!

Remember that Connection Points seemingly disappear for generally 1 of two reasons:

  1. You had Connection Points on a shape and then made that shape a part of a group shape.
  2. You drug several shapes with Connection Points at the same to a Stencil and with a drop from that stencil the points disappeared because the shapes were grouped on drop. Visio does this automatically.

Weel thar ye are lads an’ lassies!!!! This shauld be quite a help tae ye in yer wark, aye? Mind’, this is not a totally polished solution. You should think about writin’ recursive functions to handle shapes with Connection Points nested at any depth, not just one level down. This same strategy could be applied to Custom Properties as weel folk!

Enjoy!!!

"Haste ye back."

Dave "The Auld Scotsman" Edson

Dave's Hot Download
A Visio drawing with the shape defined, programmed and ready to rock and roll... or highland fling... as the case may be...
float-c.zip

An’ noo fer somethin’ completely different…

 

 
  Rate this article...
Hmm  OK  Good  Yes! Brilliant
Your a friend about this article.

Copyright © 1998-2007 DBM & others | Disclaimer | Privacy | Re-publication | Trademarks | Webmaster | Home