Setting Property based on Connections

Started by Nepherim, December 07, 2017, 02:56:10 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Nepherim

I'm trying to store the shape ID associated with each end of a connector in User properties on the connector. The solution presented here, is basically what I want, and works.
https://social.technet.microsoft.com/Forums/ie/en-US/2c6b1fbd-ffc3-425b-b20c-0094a92f5d3e/shapesheet-function-to-query-gluee-from-gluer?forum=visiogeneral

However, when gluing the connector to the Shape, rather than a specific connection point, Visio enters what seems to be an infinite loop. My assumption here is that dropping the connector on the shape causes DEPENDSON to trigger, then Visio to find the most appropriate connection point and attached the connector to it, firing DEPENDSON again. It's not clear why that would cause a seeming endless loop though.

I've tried tracing, but other than seeing the same trigger code firing, I've been unable to determine *why*, and thus how to prevent the situation. Anyone come across this before?

wapperdude

Visio 2019 Pro

Nepherim

Thanks for the reply, but not sure I'm seeing the tie to my problem -- could you clarify?

The problem I'm having appears to be centered around triggering update of connector shape properties when a connector is connected to a shape. The code works when the connector is connected to a specific connection point, but fails in an apparent infinite loop when placed on a shape (where Visio selects the best connection point).

The code works by adding a User row on the connector with:
DEPENDSON(BeginX,BeginY,EndX,EndY)+CALLTHIS("FindGlue")

wapperdude

Ok.  Before going much further, which version of Visio?

Wapperdude
Visio 2019 Pro

Croc

#4
This handler contains an implicit circular reference.
Changing BeginX causes a cell change in the same shape
vsoShape.Cells("User.BeginGluee").Formula = """" & vsoShape.Connects (i) .ToSheet.Name & """"
This in turn leads to recalculating the formulas in the shape and updating BeginX.
The cycle is implicit, because it works through the connector engine.

You can try to break this cycle. For example, through Timer()

Dim Tim As Single
Public Sub FindGlue(vsoShape As Visio.Shape)
If Tim <> Timer() Then
If vsoShape.OneD ...
...
End If
Tim = Timer()
End If
End Sub

Nepherim


Nepherim

Quote from: Croc on December 09, 2017, 10:05:18 AM
Dim Tim As Single
Public Sub FindGlue(vsoShape As Visio.Shape)
If Tim <> Timer() Then
If vsoShape.OneD ...
...
End If
Tim = Timer()
End If
End Sub


Thanks for this. The solution works, although I had to allow a little leeway in terms of processing time (ie, Timer() - Tim < 10 then exit).

But -- it kind of suggests that the triggering solution being used is perhaps not the appropriate mechanism. Is there something a little more robust which could be used as a trigger when a connector is moved from a connection point?

wapperdude

#7
One solution would be manual triggering.  Even with dedicated schematic capture systems, auto triggering was problematical at times and generally annoying.  For example, doing a batch disconnect.  Personally, having a manual update mode was preferable.

Another solution might be just to wait some interval, e.g., 10 min., then run macro.  Also, ask upon close if updating is necessary.

Just some thoughts.  The reference I gave is a manual run, based upon V2007.  Newer versions have updated object model making it easier to get the connected to/from shapes.

Wapperdude
Visio 2019 Pro

Croc

There is a CellChanged event, but in this case it does not work better.
It's good to avoid changing the connector's shape in the event handler. Write data to some other place.

vojo

this is probably a dumb question, but why use BeginX....Endy in the Dependson
All those cells would tell you is if the shape moved or changed size.
(are you using the reference in the cell to detect if glued?)

If that is really what you want to trigger...why not use PinX, PinY, width, height. if you really want to detect location size changes

Why not use the Glue section (Begtrigger, endtrigger) since those cells HAVE to change for gluing.
Or make your own "trigger"

user.new = new value from something
user.old  = old value from something
user.trigger = if (user.new <> user.old, call <VBA> + setf(getref(user.old),user.new), )

If really some sort of measurement, then could put in some resolution threshold e.g.  If(ABS(user.new-user.old)>10mm),....
Or use the time functions to give you a bit of a time filter so it only checks once a second or whatever.

Nepherim

Quote from: vojo on December 11, 2017, 01:54:39 PM
this is probably a dumb question, but why use BeginX....Endy in the Dependson
Good point. I actually ended up using BegTrigger and EndTrigger, in addition to adding a 'update-everything' handler on document open.