Format/Modify Connector After AutoConnect

Started by Rory, April 02, 2015, 04:00:19 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Rory

I am using the following code to connect two shapes together with a connector:

AppVisio.ActivePage.Shapes.ItemFromID(strParent).AutoConnect AppVisio.ActivePage.Shapes.ItemFromID(strChild), visAutoConnectDirNone

Immediately after that, I want to be able to set some properties of the connector (add text and change the font) as per the following:

Dim shpObj As Visio.Shape
Dim vsoCharacters1 As Visio.Characters
Set vsoCharacters1 = shpObj.Characters
vsoCharacters1.Text = rst.Fields("foo").Value & " = " & rst.Fields("bar").Value
vsoCharacters1.CharProps(visCharacterSize) = 6#
vsoCharacters1.CharProps(visCharacterStyle) = 2#


The problem I am having is how to get shpObj set to the just-created Connector shape. I hoped it would be the active selection since it was just added, but that didn't work. It is probably the last ID in the shapes collection, so I should be able to iterate through the shape IDs and find the maximum. However, I was hoping there was a way to just get a reference in one line, since I am adding and modifying a lot of connectors.

I'm using Visio 2013 and automating via VBA from Access 2013.

Thanks!

Nikolay

#1
Yep, this is really strange and annoying how the AutoConnect method was designed not to return the connector it creates!

A direct workaround is like this (C#).
Nothing elegant, damn straightforward - searches all connectors and returns the one which connects fromShape with toShape..
Maybe somebody has a better idea though.


Visio.Shape AutoConnect(Visio.Shape fromShape, Visio.Shape toShape)
{
    fromShape.AutoConnect(toShape, Visio.VisAutoConnectDir.visAutoConnectDirNone);

    return (
        from Visio.Connect c1 in fromShape.FromConnects
        from Visio.Connect c2 in c1.FromSheet.Connects
        where c2.ToSheet.ID == toShape.ID
        select c2.FromSheet)
        .FirstOrDefault();
}


In VBA that would be:

Function DoAutoConnect(fromShape As Shape, toShape As Shape) As Shape

    fromShape.AutoConnect toShape, visAutoConnectDirNone

    For Each c1 In fromShape.FromConnects
        For Each c2 In c1.FromSheet.Connects
            If c2.ToSheet.ID = toShape.ID Then
                Set DoAutoConnect = c2.FromSheet
            End If
        Next
    Next

End Function


Another alternative is not to use .AutoConnect, but create connectors the "old-fashioned way" using "GlueTo"
https://msdn.microsoft.com/en-us/library/aa722522.aspx
http://www.visguy.com/2006/09/13/create-visio-flowcharts-programmatically/

Yacine

I had a similar problem, but with the offset operation.
http://visguy.com/vgforum/index.php?topic=5984.msg24149#msg24149
I took me some time to realize it, but Paul's answer was the best one.
It's simple and straight forward.
Yacine

Nikolay

Looks just great! I did not quite get how the "next" id is produced (the problem with "gaps" that you mentioned in that topic)?
I.e. I thought that if you say have 3 shapes on the page, and add then add one more, it's ID will not necessarily be "4", or am I missing something?
For example, check the attached diagram - it has exactly one  shape (with id=4)... But if you add one more, it's ID will be "5", not "2"..

How does Visio create a new shape ID? It keeps track of current MaxID? Or?

But for generating a new diagram, this approach looks fine!

Yacine

#4
Right, and I would also not trust the ID number.
The trick is to not rely on the ID but on the order of the activepage shapes collection (for each shp in activepage.shapes)
In the attached drawing I managed (somehow?) to reset the ID allocation. Shape with ID 1 was created after 4.
Iterating through the shapes, shows the order in which they were created.
Yacine

Rory

Since I am creating a diagram from scratch and adding simple shapes, the IDs are incrementing by one with each new shape. I found that one line of code:

Set shpObj = AppVisio.ActivePage.Shapes.ItemFromID(AppVisio.ActivePage.Shapes.Count)

does appear to work. However, in a case where a shape is deleted this won't work, and I think it might not even work when a shape with subshapes is present (I'd have to test that to confirm), so it's a little dangerous.

It is indeed frustrating that there is no return value for AutoConnect, or at the very least some "LastID" property for a Visio page/document.

I'll switch it over to the handy function that Nikolay wrote, since that will work in all cases. Thanks for sharing it with us!