[VBA] Intersection between two lines, using ILocateCommandEvent

Greetings, and Happy New Year!

I have some trouble with the ILocateCommandEvent procedure.

What I am trying to accomplish is:

I have two parallel lines, let's call them A1 and A2. These two lines are intersected (perpendicularly) by two other lines, let's call them B1 and B2. Using ILocateCommandEvent, I first point out either A1 or A2. Secondly, I point out one of the B-lines and finally drawing a circle at the point of intersection between the two lines. Chosing A1 and B1, the circle is successfully drawn at the point of intersection

The problem occurs when I try to repeat this procedure again, now with A2 and B2. Instead of drawing a circle around the intersection between A2 and B2, the circle is drawn at the intersection between A1 and B2. It is as if the selection of A2 is not "registered", whereas the change from B1 to B2 is successful, obviously.

Let's call the ILocateCommandEvent class module "FindIntersection_LCE"

The code is (containing pseudo-code for the sake of simplicity):

Implements ILocateCommandEvents

[Declaring necessary variables]

Private Sub ILocateCommandEvents_Accept(ByVal Element As Element, Point As Point3d, ByVal View As View)

If [Element is an A-line] then

Set firstElement = Element
Dim oLocator As New FindIntersection_LCE
CommandState.StartLocate oLocator

Else if [Element is a B-line] then

Set secondElement = Element

End If

End Sub


Private Sub ILocateCommandEvents_Cleanup()

End Sub


Private Sub ILocateCommandEvents_Dynamics(Point As Point3d, ByVal View As View, ByVal DrawMode As MsdDrawingMode)

End Sub


Private Sub ILocateCommandEvents_LocateFailed()

End Sub


Private Sub ILocateCommandEvents_LocateFilter(ByVal Element As Element, Point As Point3d, Accepted As Boolean)

End Sub


Private Sub ILocateCommandEvents_LocateReset()


End Sub


Private Sub ILocateCommandEvents_Start()

End Sub


So, the idea is to initiate the class element by pushing a tool button X. Then, first select the line A1. Then, the class module calls itself, allowing us to select another element, the line B1. When B1 is selected, the intersection is found and marked with a circle. The class module then terminates.

I now want to find the intersection between A2 and B2, so the class module is now initiated again by pushing the tool button X. And this is were problem occurs, as described above. When selecting A2 followed by B2, the circle is drawn at intersection between A1 and B2.

Do you have any idea why this is happening?

  • Hi soren,

    looking at your simplified code I would say that

    >>If [Element is an A-line] then<< is not meet at the second run.

    Try to do something like >>Set firstElement=Nothing<< when your Circle is drawn and check again?

    And do you know the debugger? A very useful tool especially if I dont know wants going on....

    Regards, Stefan.

  • "If [Element is an A-line] then" should indeed be fulfilled in when selecting A2 for the second intersection.

  • Well, since we can't see your code it's hard to provide a diagnosis.  My guess is that the ILocateCommandEvents class is hanging around and preserving the references to the lines.

    After DrawCircleAtIntersection, explicitly set firstLine and secondLine to Nothing.

    Regards, Jon Summers
    LA Solutions

  • I am aware of that, Jon - but I am working on something I cannot share explicitly. I have been wondering if this thing was a problem with the stack not being cleared.

    I saw your brilliant example of finding the intersection of two lines (either a real intersection or projected intersection), using ILocateCommandEvents.. it seems to work like a charm. What I want to do is a little more simple than what happens in your example. I can do it the first time, from then on it fails, as described.

    I will try to set the lines to Nothing, and see what happens.

    Thanks for the assistance so far :)

  • I have been wondering if this thing was a problem with the stack not being cleared

    I'm not sure what you mean by that.

    VBA Object References and Object Lifetimes

    VB/VBA uses reference-counted classes. A VBA class is a COM object, which is reference-counted. Objects tend to persist for longer that we anticipate, often leading to puzzling problems.

    Further reading …

    In the following example, the object reference is disgarded when it goes out of scope as the subroutine exits …

    Sub Example ()
      Dim o As Object
      Set o = CreateObjectSomehow
      ' use object
    Exit Sub

    In the next example, the object is inside a loop. I have found that the object persists after the first iteration of the loop, leading to logic errors in the code …

    Sub ExampleLoopWithProblem ()
       Do While (some condition is True)
         Dim o As Object
         Set o = CreateObject
         '  use object -- but something goes wrong!
    Exit Sub

    A cure for that is to set an object reference explicitly to Nothing...

    Sub ExampleLoopWithNoProblem ()
       Do While (True)
         Dim o As Object
         Set o = CreateObject
         '  use object as expected
         Set o = Nothing
    Exit Sub

    Regards, Jon Summers
    LA Solutions

  • What you explain is pretty much the same as what I've been suspecting; that the selection of the A1 element is not cleared when the the procedure is run the second time, selecting A2. For some reason it is not a problem with the B-element..

    I will look into it tomorrow, and try setting the elements to Nothing before terminating the functions. I will let you know if it solves my problem :)

  • I have now narrowed down the problem quite a bit.

    As described earlier, running the intersection procedure once, is no problem. I can choose an A-element followed by a B-element, and the intersection is marked by a circle.

    When running the intersection procedure again, I have now found out that I cannot select an A-element. No matter which of the A-elements I click, it is not being selected and therefore not stored - the old A-element selection, from the first run, is still saved in my A-element variable! Selecting a B-element is no problem. This explains why the intersection is being drawn at the first A-element.

    So the question is: Why can't I select an A-element in the second run? The only difference between A-elements and B-elements is which level they belong to. If I exit the entire intersection procedure, and just choose the Element Selection tool from the microstation toolbar, I can select whatever I want... so the problem is limited to selecting elements while running ILocateCommandEvent.

  • Soren,

    you have to provide a code snip for your class! anything else is stumbling in the dark.

    Here are some possible faults:

    1) Wrong init of your class:  CommandState.StartLocate New Blahblah

    2) Static Variables instead of Class Vars

    3) Wrong Iimplementation of ILocateCommandEvents_LocateFilter

    My suggestion would be to use the example in the help and redesign it until it fits your needs.

    Regards, Stefan.

    Answer Verified By: Søren Wrang 

  • The problem has now been solved. It turned out that I had made a few mistakes with some boolean variables controlling the sequence of element selection.. Thank you, nevertheless, for your effort.. Even though the cause of the problem turned out to be something else than expected, your feedback helped me analyse the problem better and improve my approach :) !

  • Debugging by Telepathy

    You have to provide a code snip for your class! Anything else is stumbling in the dark

    I agree. We can't see Soren's code. We can't step through that code in debug mode, but Soren can do that.

    I am working on something I cannot share explicitly

    You can't call a garage and ask them to fix your car without taking it to the garage. You can't call your doctor and ask "Send me some drugs to cure my illness, which I can't discuss with you!" We don't want your car, we don't want your illness, and nor to we want to use your code. You want us to diagnose it.

    If you still want someone to help you but can't disclose the code publicly, then hire a MicroStation VBA consultant.

    A solution to this impasse would be to create another VBA project that is not confidential yet includes the same logic as your problematic yet confidential code.

    Regards, Jon Summers
    LA Solutions