9 Replies Latest reply on Jul 6, 2017 7:50 AM by Peter Brinkhuis

    Cancel Batch process

    Prabaharan Pichaiyan

      I have some macros to run in all the parts in the folder. While doing that, I need to cancel that with cancel button.I already have cancel button with my form, and i used "End "  code to unload the form. Is there any codes available for that.

       

      Thank you

        • Re: Cancel Batch process
          Andreas Killer

          I already have cancel button with my form, and i used "End " code to unload the form. Is there any codes available for that.

          You should never use END in your code, because it terminates anything and can cause unexpected results. Use UNLOAD to terminate your form.

           

          A simple sample, create a new form, add 2 command buttons and add the code below my name.

           

          The 1st button "runs a macro", in this sample an endless loop. The trick is to call DoEvents from time to time and "look" if the macro should be canceled.

           

          The 2nd button can now cancel the macro that runs "inside" the 1st button.

           

          Andreas.

           

           

          Option Explicit

           

          Dim Cancel As Boolean

           

          Private Sub CommandButton1_Click()
            CommandButton1.Caption = "Run"
            Cancel = False
            Do
              DoEvents
              If Cancel Then Exit Do
            Loop
            CommandButton1.Caption = "Done"
           
            'For testing purposes you can delete this line:
            Unload Me
          End Sub

           

          Private Sub CommandButton2_Click()
            Cancel = True
          End Sub

            • Re: Cancel Batch process
              Prabaharan Pichaiyan

              Perfect.

              Working Great

              Thanks a lot.

              • Re: Cancel Batch process
                Peter Brinkhuis

                The DoEvents line really does wonders for keeping your macro responsive. I just learned it's a nasty trick to avoid working with threads, so DoEvents should really be avoided when you are creating an add-in or a complex macro.

                  • Re: Cancel Batch process
                    Prabaharan Pichaiyan

                    Is There any other way to do that?

                     

                    Thanks

                      • Re: Cancel Batch process
                        Peter Brinkhuis

                        When you are creating CPU-intensive software, the best way would be to use multiple threads and split the workload. It's pretty complex to do that though, because in most programs the order of execution is important. When you have to know for certain that a certain command is executed (possibly in another thread), it becomes quite tedious.

                         

                        I myself haven't worked with multiple threads, but I've read enough to know I'd like to avoid them for now

                      • Re: Cancel Batch process
                        Andreas Killer

                        DoEvents should really be avoided when you are creating an add-in or a complex macro.

                        Sorry, but from my view a 100% no, that is nonsense.

                         

                        DoEvents just gives time slices to the system, that's all. VBA doesn't support multiple threads directly, but as my sample shows there is a way to run code asynchronously (but not in different CPU's) also in VBA. And there is absolutely no issue to do so!

                         

                        The other threads that are called from the system during DoEvents doesn't affect your thread, except your thread allows that (as my sample shows). Furthermore, you can never be sure that the "outside-world" of your thread doesn't change while your code runs, regardless if you call DoEvents or not! Today every machine is multi task / multi thread, also Solidworks!

                         

                        https://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents%28v=vs.110%29.aspx

                         

                        Andreas.

                          • Re: Cancel Batch process
                            Peter Brinkhuis

                            I do have to admit that my knowledge on this topic is rather limited, so thanks for chipping in. I got most of my knowledge from these two pages. The second one quotes the warning from the MSDN page as well.

                             

                            Is DoEvents Evil?

                            c# - Use of Application.DoEvents() - Stack Overflow

                              • Re: Cancel Batch process
                                Andreas Killer

                                I got most of my knowledge from these two pages. The second one quotes the warning from the MSDN page as well.

                                 

                                Is DoEvents Evil?

                                c# - Use of Application.DoEvents() - Stack Overflow

                                At first, the other threads are all about .NET applications, not AddIns nor VBA. In a .NET application there is almost no need to use DoEvents, that is correct and yes, it can cause issues...

                                 

                                Anyway, I'll grab a part of a paragraph from there:

                                 

                                The user could for example close the main window while the loop that calls DoEvents() is running. That works, user interface is gone. But your code didn't stop, it is still executing the loop. That's bad. Very, very bad.

                                 

                                "Main window" means the application window itself, in our case Solidworks, not our form window. Even if, why is that bad? If you know it is possible, you can catch it and close the application. BTW, it is also possible to close Solidworks during the startup!

                                 

                                Furthermore there is no other way in VBA to accomplish some things as to call DoEvents. I'll show you an example, especially to contradict the above statement:

                                 

                                - Open the VBA editor
                                (I recommend to use Excel, not Solidworks, because it is more robust as Solidworks and the last example crashs the application!)

                                - Add a Userform

                                - Add 2 command buttons

                                - Add this code (which is a simple Yes/No message box):

                                 

                                Option Explicit

                                 

                                Public Result As Boolean

                                 

                                Private Sub CommandButton1_Click()

                                  Result = True

                                  Me.Hide

                                End Sub

                                 

                                Private Sub CommandButton2_Click()

                                  Result = False

                                  Me.Hide

                                End Sub

                                 

                                - Add a regular module
                                - Add this sub

                                 

                                Sub MainA()

                                  Dim Answer As Boolean

                                  'Init

                                  Load UserForm1

                                  'Run

                                  With UserForm1

                                    .Show vbModal

                                    Answer = .Result

                                  End With

                                  'Clean up

                                  Unload UserForm1

                                  'Show

                                  MsgBox "Answer " & Answer

                                End Sub

                                 

                                - Run it, as you see no issues. Alright, let us assume we want to show the form modeless, because we like to e.g. add code to pick some points in Solidworks.

                                -Add this code:

                                 

                                Sub MainB()

                                  Dim Answer As Boolean

                                  'Init

                                  Load UserForm1

                                  'Run

                                  With UserForm1

                                    .Show vbModeless

                                    Answer = .Result

                                  End With

                                  'Clean up

                                  Unload UserForm1

                                  'Show

                                  MsgBox "Answer " & Answer

                                End Sub

                                 

                                -Run it. As you see the form isn't shown anymore! That did not work. The solution (or should I say "my solution"?) is this:

                                 

                                Sub MainC()

                                  Dim Answer As Boolean

                                  'Init

                                  Load UserForm1

                                  'Run

                                  With UserForm1

                                    .Show vbModeless

                                    'We get an error if the User close the form with X

                                    On Error GoTo ExitPoint

                                    'Wait till on screen

                                    Do While Not .Visible

                                      DoEvents

                                    Loop

                                    'Wait while on screen

                                    Do While .Visible

                                      DoEvents

                                    Loop

                                    'Get the result

                                    Answer = .Result

                                  End With

                                  'Clean up

                                  Unload UserForm1

                                ExitPoint:

                                  'Show

                                  MsgBox "Answer " & Answer

                                End Sub

                                 

                                - Run it, as you see it works, no issues.

                                 

                                Now comment out the DoEvents, run the sub again and try to use/close the form... My apologies if you now have to repair your office.

                                 

                                If you have a better idea of how to display a non-modal form without DoEvents, I am listening. ;-)

                                 

                                Andreas.