How to use static variable to exit function?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • deko

    How to use static variable to exit function?

    I have a function with a number of long loops. While the function is
    running, I want to be able to click a Stop button and exit the function as
    quickly as possible.

    The abbreviated code looks like this:

    [code in form frm1]
    Private Sub cmdStart_Click
    Call bas1.LongLoops( parameter1, parameter2, parameterN)
    End Sub

    [code in standard module bas1]
    Public Function LongLoops(param eter1, parameter2, parameterN)
    Do While i < 10000
    [code omitted]
    Loop
    Do While i < 20000
    [code omitted]
    Loop
    'etc, etc...
    End Function

    Should I use a static variable?

    [code in form frm1]
    Private Sub cmdStop_Click
    blnStop = True
    Call bas1.LongLoops( blnStop, parameter2, parameterN)
    End Sub

    [code in standard module bas1]
    Public Function LongLoops(blnSt op, parameter2, parameterN)
    Static blnExit as Boolean
    blnExit = blnStop
    Do While i < 10000
    If blnExit Then Exit Do
    [code omitted]
    Loop
    Do While i < 20000
    If blnExit Then Exit Do
    [code omitted]
    Loop
    'etc, etc...
    End Function

    Or should I just raise an error that causes the function to exit?

    [code in form frm1]
    Private Sub cmdStop_Click
    blnStop = True
    Call bas1.LongLoops( blnStop, parameter2, parameterN)
    End Sub

    [code in standard module bas1]
    Public Function LongLoops(blnSt op, parameter2, parameterN)
    If blnStop Then Err.Raise MYCUSTOMERROR
    Do While i < 10000
    [code omitted]
    Loop
    Do While i < 20000
    [code omitted]
    Loop
    'etc, etc...
    End Function

    If I raise an error with a second call to the function, will the process
    from the first call continue running?

    Other options?

    Thanks in advance.


  • Tom van Stiphout

    #2
    Re: How to use static variable to exit function?

    On Sat, 3 Sep 2005 16:08:49 -0700, "deko" <deko@nospam.co m> wrote:

    A quick-and-dirty solution would set a global variable to signal to
    LongLoops to stop. If the code in bas1 is ONLY called from frm1, it
    should be moved to the form, and a module-level global could be used.

    A more elegant solution would perhaps test a public property in frm1
    to check if the Stop button was clicked.

    Don't forget to put a DoEvents in the LongLoops code, so the cmdStop
    click would happen while it is executing. If you were using a "tight"
    loop, it would first execute and THEN the click would occur - a little
    too late.

    I think raising an error is the wrong thing to do. It's abusing an
    error handler feature for something it was not designed for.

    -Tom.


    [color=blue]
    >I have a function with a number of long loops. While the function is
    >running, I want to be able to click a Stop button and exit the function as
    >quickly as possible.
    >
    >The abbreviated code looks like this:
    >
    >[code in form frm1]
    >Private Sub cmdStart_Click
    > Call bas1.LongLoops( parameter1, parameter2, parameterN)
    >End Sub
    >
    >[code in standard module bas1]
    >Public Function LongLoops(param eter1, parameter2, parameterN)
    > Do While i < 10000
    > [code omitted]
    > Loop
    > Do While i < 20000
    > [code omitted]
    > Loop
    > 'etc, etc...
    >End Function
    >
    >Should I use a static variable?
    >
    >[code in form frm1]
    >Private Sub cmdStop_Click
    > blnStop = True
    > Call bas1.LongLoops( blnStop, parameter2, parameterN)
    >End Sub
    >
    >[code in standard module bas1]
    >Public Function LongLoops(blnSt op, parameter2, parameterN)
    > Static blnExit as Boolean
    > blnExit = blnStop
    > Do While i < 10000
    > If blnExit Then Exit Do
    > [code omitted]
    > Loop
    > Do While i < 20000
    > If blnExit Then Exit Do
    > [code omitted]
    > Loop
    > 'etc, etc...
    >End Function
    >
    >Or should I just raise an error that causes the function to exit?
    >
    >[code in form frm1]
    >Private Sub cmdStop_Click
    > blnStop = True
    > Call bas1.LongLoops( blnStop, parameter2, parameterN)
    >End Sub
    >
    >[code in standard module bas1]
    >Public Function LongLoops(blnSt op, parameter2, parameterN)
    > If blnStop Then Err.Raise MYCUSTOMERROR
    > Do While i < 10000
    > [code omitted]
    > Loop
    > Do While i < 20000
    > [code omitted]
    > Loop
    > 'etc, etc...
    >End Function
    >
    >If I raise an error with a second call to the function, will the process
    >from the first call continue running?
    >
    >Other options?
    >
    >Thanks in advance.
    >[/color]

    Comment

    • deko

      #3
      Re: How to use static variable to exit function?

      > A quick-and-dirty solution would set a global variable to signal to[color=blue]
      > LongLoops to stop.[/color]

      sounds interesting.
      [color=blue]
      > If the code in bas1 is ONLY called from frm1, it
      > should be moved to the form, and a module-level global could be used.[/color]

      It is, but there's so much code it needs to be segregated by purpose.
      [color=blue]
      > A more elegant solution would perhaps test a public property in frm1
      > to check if the Stop button was clicked.
      >
      > Don't forget to put a DoEvents in the LongLoops code, so the cmdStop
      > click would happen while it is executing. If you were using a "tight"
      > loop, it would first execute and THEN the click would occur - a little
      > too late.[/color]

      10-4
      [color=blue]
      > I think raising an error is the wrong thing to do. It's abusing an
      > error handler feature for something it was not designed for.[/color]

      perhaps...

      Here's what I've got working:

      [code in form frm1]
      Private Sub cmdStart_Click
      Call bas1.LongLoops( False, parameter2, parameterN)
      End Sub
      Private Sub cmdStop_Click
      Call bas1.LongLoops( True)
      End Sub

      [code in standard module bas1]
      Public Function LongLoops(blnSt op As Boolean, Optional parameter2, Optional
      parameterN)
      Static blnExit As Boolean
      blnExit = blnStop
      Do While i < 10000
      If blnExit Then Exit Do
      DoEvents
      [code omitted]
      Loop
      Do While i < 20000
      If blnExit Then Exit Do
      DoEvents
      [code omitted]
      Loop
      [code omited]
      End Function

      The problem (what I thought might be avoided by raising an error) is that I
      have to instantiate a bunch of objects to get into the loop (on the second
      call made from cmdStop).

      This does not work:

      [code in standard module bas1]
      Public Function LongLoops(blnSt op As Boolean, Optional parameter2, Optional
      parameterN)
      Static blnExit As Boolean
      blnExit = blnStop

      If Not blnStop Then

      Set obj1 = Object1
      Set obj2 = Object2
      Set objN = Object N
      Do While obj1 < obj2
      If blnExit Then Exit Do
      DoEvents
      Test objN
      [code omitted]
      Loop

      End If

      End Function

      The reason this does not work is because (as this new example indicates) the
      actual code uses objects rather than integers in the looping construct.

      So the objects have to be set to get into the loop. So the second call
      needs to get into the loop or blnExit does not change - which I find strange
      because I thought I didn't need to get into the loop since blnExit is
      Static. That is, I thought just getting into the function with the second
      call and changing the value of the Static variable (without getting into the
      loop) would cause the Static variable to change regardless of where it is
      being used.

      Perhaps this would be the case with a global variable? That would be better
      because I wouldn't have to instantiate all those objects (just to get into
      the loop so I can exit it). But perhaps I could use some Resume Next
      statements If blnStop = True or something...

      Anyway, thanks for the reply.


      Comment

      • Kevin Rollo

        #4
        Re: How to use static variable to exit function?

        The last time I played with this type of thing, I finished up having to
        "break-out" of the executing function. I did this in rather elegant style
        by throwing a message box every 20 loops asking if I wanted to continue or
        not. I'm just wondering if a refinement on that is to breakout to a
        function that tests the public variable.

        if TestLoop = 20 then
        If BreakOut() Then Exit Do
        ...

        Function Breakout() as boolean
        BreakOut = PublicStop
        End Function

        Then from your form ....
        Private Sub cmdStop_Click
        PublicStop = True
        Endsub

        The only thing I'm not sure of is whether the button on the form can alter
        the public while your LongLoops is executing. If not, well, elegance is
        worth pursuing!

        --
        Regards,
        Kevin

        "deko" <deko@nospam.co m> wrote in message
        news:Q8qdnZ2dnZ 0Y4qSMnZ2dnSJrh t6dnZ2dRVn-yp2dnZ0@comcast .com...[color=blue]
        > A quick-and-dirty solution would set a global variable to signal to
        > LongLoops to stop.[/color]

        sounds interesting.
        [color=blue]
        > If the code in bas1 is ONLY called from frm1, it
        > should be moved to the form, and a module-level global could be used.[/color]

        It is, but there's so much code it needs to be segregated by purpose.
        [color=blue]
        > A more elegant solution would perhaps test a public property in frm1
        > to check if the Stop button was clicked.
        >
        > Don't forget to put a DoEvents in the LongLoops code, so the cmdStop
        > click would happen while it is executing. If you were using a "tight"
        > loop, it would first execute and THEN the click would occur - a little
        > too late.[/color]

        10-4
        [color=blue]
        > I think raising an error is the wrong thing to do. It's abusing an
        > error handler feature for something it was not designed for.[/color]

        perhaps...

        Here's what I've got working:

        [code in form frm1]
        Private Sub cmdStart_Click
        Call bas1.LongLoops( False, parameter2, parameterN)
        End Sub
        Private Sub cmdStop_Click
        Call bas1.LongLoops( True)
        End Sub

        [code in standard module bas1]
        Public Function LongLoops(blnSt op As Boolean, Optional parameter2, Optional
        parameterN)
        Static blnExit As Boolean
        blnExit = blnStop
        Do While i < 10000
        If blnExit Then Exit Do
        DoEvents
        [code omitted]
        Loop
        Do While i < 20000
        If blnExit Then Exit Do
        DoEvents
        [code omitted]
        Loop
        [code omited]
        End Function

        The problem (what I thought might be avoided by raising an error) is that I
        have to instantiate a bunch of objects to get into the loop (on the second
        call made from cmdStop).

        This does not work:

        [code in standard module bas1]
        Public Function LongLoops(blnSt op As Boolean, Optional parameter2, Optional
        parameterN)
        Static blnExit As Boolean
        blnExit = blnStop

        If Not blnStop Then

        Set obj1 = Object1
        Set obj2 = Object2
        Set objN = Object N
        Do While obj1 < obj2
        If blnExit Then Exit Do
        DoEvents
        Test objN
        [code omitted]
        Loop

        End If

        End Function

        The reason this does not work is because (as this new example indicates) the
        actual code uses objects rather than integers in the looping construct.

        So the objects have to be set to get into the loop. So the second call
        needs to get into the loop or blnExit does not change - which I find strange
        because I thought I didn't need to get into the loop since blnExit is
        Static. That is, I thought just getting into the function with the second
        call and changing the value of the Static variable (without getting into the
        loop) would cause the Static variable to change regardless of where it is
        being used.

        Perhaps this would be the case with a global variable? That would be better
        because I wouldn't have to instantiate all those objects (just to get into
        the loop so I can exit it). But perhaps I could use some Resume Next
        statements If blnStop = True or something...

        Anyway, thanks for the reply.



        Comment

        • rkc

          #5
          Re: How to use static variable to exit function?

          deko wrote:[color=blue]
          > I have a function with a number of long loops. While the function is
          > running, I want to be able to click a Stop button and exit the function as
          > quickly as possible.[/color]
          [color=blue]
          > Other options?[/color]

          Wrap the whole shebang in a class. Everything is in one place, shielded
          from outside influence and re-usable.

          '<clsDekoLoop>
          Option Compare Database
          Option Explicit

          Private WithEvents btnStop As Access.CommandB utton
          Private exitLoop As Boolean
          Private mElapsedTime As String

          Public Property Get ElapsedTime() As String
          ElapsedTime = mElapsedTime
          End Property

          Public Sub Init(btn As Access.CommandB utton)
          Set btnStop = btn
          btnStop.OnClick = "[Event Procedure]"

          End Sub

          Private Sub btnStop_Click()
          exitLoop = True
          End Sub

          Public Sub RunLoop(outerLo op As Long, innerLoop As Long)
          Dim x As Long
          Dim y As Long
          Dim b As Single
          b = Timer

          For x = 1 To outerLoop
          DoEvents
          For y = 1 To innerLoop: Next
          If exitLoop Then Exit For
          Next


          mElapsedTime = "Outer Loop: " & x & vbCrLf & _
          "Elapsed time: " & Timer - b

          End Sub

          Private Sub Class_Terminate ()
          If Not btnStop Is Nothing Then Set btnStop = Nothing
          End Sub

          '</clsDekoLoop>

          '<frmTestDekoLo op>

          CommandButton: cmdStart
          Command Button: cmdStop

          Private Sub cmdStart_Click( )
          Call TestDekoLoop
          End Sub

          Sub TestDekoLoop()
          Dim dl As clsDekoLoop
          Set dl = New clsDekoLoop

          dl.Init Me.cmdStop

          dl.RunLoop 10000, 1000

          MsgBox dl.ElapsedTime

          Set dl = Nothing

          End Sub

          '</frmTestDekoLoop >

          Comment

          • deko

            #6
            Re: How to use static variable to exit function?

            > Wrap the whole shebang in a class. Everything is in one place, shielded[color=blue]
            > from outside influence and re-usable.[/color]

            I was exploring that idea yesterday, but got things working... other fish to
            fry now.

            Any error generated by LongLoops is passed back to cmdStop_Click. So with
            an 'OnError Resume Next' statement in the calling sub, the program flow
            continues into the loop (with blnExit set to True) and the loops exit.

            Private Sub cmdStop_Click
            OnError Resume Next 'mainly concerned with Error 91
            Call bas1.LongLoops( True)
            End Sub

            Public Function LongLoops(blnSt op As Boolean, Optional parameter2, Optional
            parameterN)

            Static blnExit As Boolean
            blnExit = blnStop
            Set obj1 = Object1
            Set obj2 = Object2
            Set objN = Object N
            Do While obj1 < obj2
            If blnExit Then Exit Do
            DoEvents
            Test objN
            [code omitted]
            Loop

            End Function

            I'm still wondering why I have to enter the loop with the second call - I
            thought a Static variable would change value everywhere in the function once
            it's passed to the function.


            Comment

            • rkc

              #7
              Re: How to use static variable to exit function?

              deko wrote:
              [color=blue]
              > So the objects have to be set to get into the loop. So the second call
              > needs to get into the loop or blnExit does not change - which I find strange
              > because I thought I didn't need to get into the loop since blnExit is
              > Static. That is, I thought just getting into the function with the second
              > call and changing the value of the Static variable (without getting into the
              > loop) would cause the Static variable to change regardless of where it is
              > being used.
              >
              > Perhaps this would be the case with a global variable? That would be better
              > because I wouldn't have to instantiate all those objects (just to get into
              > the loop so I can exit it). But perhaps I could use some Resume Next
              > statements If blnStop = True or something...[/color]

              I think the problem is that when you execute the procedure again while
              the first call is still running the second call has to run to completion
              before the first call can resume running. Frankly I am surprised the
              whole thing doesn't just blow up in your face. The second thing that
              isn't clear is what does it mean for one object to be less than another
              object. One object is equal to another object when they both reference
              the same instance.

              Any way if you intent on doing this your way, try checking blnExit
              immediatley after assigning it and exiting the function right then
              if true.

              blnExit = blnStop
              If blnExit Then Exit Function


              Comment

              • deko

                #8
                Re: How to use static variable to exit function?

                > blnExit = blnStop[color=blue]
                > If blnExit Then Exit Function[/color]

                I need the loops to complete because they call other functions (there are a
                few, and I don't know which one the code will be in when the user clicks the
                Stop button) - then the normal flow of the procedure will continue to the
                end.

                It's working fine. My only confusion was dealing with the Static Boolean
                variable.

                As for the objects being greater or less than each other, that example was
                just to keep things concise. The point is the loops require objects (one of
                which is a collection) to be instantiated.


                Comment

                Working...