Visio Guy

Visio Discussions => Programming & Code => Topic started by: matthew on November 23, 2020, 02:44:08 PM

Title: How to specify point (N, E, S, W) on a shape to glue to?
Post by: matthew on November 23, 2020, 02:44:08 PM
Hi,
My code 'glues' a 1-D connector to a 2-D shape then glues the other end of the connector to another object.  It all works fine except I'd rather it connected to the shapes points that correspond to N, E, S and W. 
Is there a way of specifying this?  At the moment it connects to whatever seems the most convenient for it.
I'm using:
shpid = vsoShape1.ID   'the connector
shpidtwo = vsoShape2.ID   'the circle
UndoScopeID10 = Application.BeginUndoScope("Size Object")
Set vsoCell1 = Application.ActiveWindow.Page.Shapes.ItemFromID(shpid).CellsU("EndX")
Set vsoCell2 = Application.ActiveWindow.Page.Shapes.ItemFromID(shpidtwo).CellsSRC(1, 1, 0)
vsoCell1.GlueTo vsoCell2

many thanks
Matthew
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: Surrogate on November 23, 2020, 03:36:35 PM
Quote from: matthew on November 23, 2020, 02:44:08 PM
Set vsoCell2 = Application.ActiveWindow.Page.Shapes.ItemFromID(shpidtwo).CellsSRC(1, 1, 0)
Hi, matthew !
Enumeration of Section Connection Points have ID = 7 (VisSectionIndices enumeration (https://docs.microsoft.com/en-us/office/vba/api/visio.vissectionindices))
(https://i.ibb.co/MBzbBLY/cp.png) (https://ibb.co/Hhc0hQW)
In this section rows started from 0 (read more about VisRowIndices enumeration (https://docs.microsoft.com/en-us/office/vba/api/visio.visrowindices)).
Read more about Shape.CellsSRC property (https://docs.microsoft.com/en-us/office/vba/api/visio.shape.cellssrc)
Sub tst_code()

shpid = vsoshape1.ID   'the connector
shpidtwo = vsoshape2.ID   'the circle
Set vsoCell1 = Application.ActiveWindow.Page.Shapes.ItemFromID(shpid).CellsU("EndX")
Set vsoCellN = Application.ActiveWindow.Page.Shapes.ItemFromID(shpidtwo).CellsSRC(visSectionConnectionPts, 0, 0)   'N connection point
Set vsoCellE = Application.ActiveWindow.Page.Shapes.ItemFromID(shpidtwo).CellsSRC(visSectionConnectionPts, 1, 0)   'E connection point
Set vsoCellS = Application.ActiveWindow.Page.Shapes.ItemFromID(shpidtwo).CellsSRC(visSectionConnectionPts, 2, 0)   'S connection point
Set vsoCellW = Application.ActiveWindow.Page.Shapes.ItemFromID(shpidtwo).CellsSRC(visSectionConnectionPts, 3, 0)   'W connection point

vsoCell1.GlueTo vsoCellN
End Sub
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: Surrogate on November 23, 2020, 03:40:44 PM
Also you can use syntax like
Set vsoCellS = Application.ActiveWindow.Page.Shapes.ItemFromID(shpidtwo).Cells("Connections.S")
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: matthew on November 23, 2020, 05:46:11 PM
Hi when I try this e.g.
Set vsoCellN = Application.ActiveWindow.Page.Shapes.ItemFromID(shpidtwo).CellsSRC(visSectionConnectionPts, 0, 0)   'N connection point
I get an error that says 'Referenced cell Sheet.12780!ConnectionX3 does not exist'; it is the same for 0, 1, 2 or 3.
It is the correct shape id.
any idea where I am going wrong?
thanks
Matthew
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: Surrogate on November 23, 2020, 08:06:25 PM
Quote from: matthew on November 23, 2020, 05:46:11 PMI get an error that says 'Referenced cell Sheet.12780!ConnectionX3 does not exist'; it is the same for 0, 1, 2 or 3.
It is the correct shape id.
Is this shape with correct ID have these cells ?
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: matthew on November 23, 2020, 08:58:14 PM
Hi,
I'm a newbie so I'm sorry for the dumb questions.
Had a look at the shape data but can't see anything that I think would correspond to the cells.   
I guess that is the problem (apart from me), I drew a circle from the tools menu and have been using that, should I have taken a circle from the stencil?
Please excuse my ignorance.
kind regards
Matthew
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: Surrogate on November 23, 2020, 09:18:18 PM
Matthew, dont worry ! All of us was newbies some years ago  :)

you can see these cells only in ShapeSheet window. It available only if Developer tab enabled.
http://www.visguy.com/2015/06/19/how-to-show-the-developer-ribbon-tab-and-why/
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: matthew on November 23, 2020, 09:31:21 PM
thanks for the kind words and your patience, been looking through the shapesheet but don't actually know what I'm looking for, can't see anything that would make me think there are these connection points,  is there a specific data field I should be looking for that would tell me if these cells were there and so let me connect to them?  If the cells aren't there I guess I will have to replace the shapes with ones that did have them, but where would I find a shape that did? 
thanks again
Matthew
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: Surrogate on November 24, 2020, 07:58:05 AM
0. Activate Developer tab at ribbon (if you didn it before)
1. Open ShapeSheet window
https://youtu.be/dpmBQgkd0vc (https://youtu.be/dpmBQgkd0vc)
2. Search Connection points section, scroll this window
3. If you cant find there this section you must add it, with right click at any place of this window
4. Select option Add section in dropdown context menu
5. Select Connection points
6. Add connection points N, E, S and W
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: Surrogate on November 24, 2020, 08:42:25 AM
Also you can do it with code
Dim vsoshape1 As Shape, vsoshape2 As Shape, rw As Row, rn As Integer
Set vsoshape1 = ActivePage.Shapes.ItemFromID(1)
Set vsoshape2 = ActivePage.Shapes.ItemFromID(5) ' for example i add named connection points to shape with ID = 5
shpid = vsoshape1.ID   'the connector
shpidtwo = vsoshape2.ID   'the circle
' check is Connection point section exist for this shape, if NOT just add it
If Not vsoshape2.SectionExists(visSectionConnectionPts, visExistsAnywhere) Then vsoshape2.AddSection (visSectionConnectionPts)
' check is Connections.N cell exist for this shape, if NOT just add it
If Not vsoshape2.CellExists("Connections.N", visExistsAnywhere) Then
rn = vsoshape2.AddNamedRow(visSectionConnectionPts, "N", 0)
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctX).FormulaForceU = "Width/2"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctY).FormulaForceU = "Height"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctDirX).FormulaForceU = "0 mm"
   vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctDirY).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctType).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctAutoGen).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, 6).FormulaForceU = ""
End If
' check is Connections.E cell exist for this shape, if NOT just add it
If Not vsoshape2.CellExists("Connections.E", visExistsAnywhere) Then
rn = vsoshape2.AddNamedRow(visSectionConnectionPts, "E", 0)
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctX).FormulaForceU = "Width*0"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctY).FormulaForceU = "Height/2"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctDirX).FormulaForceU = "0 mm"
   vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctDirY).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctType).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctAutoGen).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, 6).FormulaForceU = ""
End If
' check is Connections.S cell exist for this shape, if NOT just add it
If Not vsoshape2.CellExists("Connections.S", visExistsAnywhere) Then
rn = vsoshape2.AddNamedRow(visSectionConnectionPts, "S", 0)
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctX).FormulaForceU = "Width/2"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctY).FormulaForceU = "Height*0"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctDirX).FormulaForceU = "0 mm"
   vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctDirY).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctType).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctAutoGen).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, 6).FormulaForceU = ""
End If
' check is Connections.W cell exist for this shape, if NOT just add it
If Not vsoshape2.CellExists("Connections.W", visExistsAnywhere) Then
rn = vsoshape2.AddNamedRow(visSectionConnectionPts, "W", 0)
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctX).FormulaForceU = "Width"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctY).FormulaForceU = "Height/2"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctDirX).FormulaForceU = "0 mm"
   vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctDirY).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctType).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, visCnnctAutoGen).FormulaForceU = "0 mm"
    vsoshape2.CellsSRC(visSectionConnectionPts, rn, 6).FormulaForceU = ""
End If
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: matthew on November 24, 2020, 10:55:14 AM
great, thank you very much, I'll copy that into the code later today and run it, it'll save me so much time and tidy up the drawing, much appreciated
Matthew
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: Nikolay on November 24, 2020, 12:05:17 PM
I think some clarification may be needed here.

First, Visio cannot glue to "east/west/north/south" side.
There is no such feature as "glue to a side", as far as I know.  Visio can glue to a shape (center) or to a point. It cannot do a "walking glue" to a line (such as side)
But let others correct me if that's not the case.

There is a workaround, suggested by Surrogate.
You can add a connection point(s) to your shape, north, east, west, south as you please and glue to those instead.

But of course, first, these connection points should exist.
For a simple circle or rectangle of course these connection points don't exist until you add them.

And the glue won't be "walking", it will be fixed at that point (the connector will connect not to a side, but to a fixed point on that side).
Notice the difference (right top-right is "walking", and bottom-right is "fixed at point"):

(https://unmanagedvisio.com/upload/walking-vs-point.gif)

What the code is doing, is adding these connection points to your shape.
You can do it manually as well of course.
Title: Re: How to specify point (N, E, S, W) on a shape to glue to?
Post by: matthew on November 24, 2020, 05:35:25 PM
thanks to Surrogate and Nikolay for your help, I used Surrogate's code and everything is as I wanted it now, connection points have been added and the connectors join the shape at the connection point I specify, works great.
It has been a very useful learning experience for me, thank you again,
Matthew