Reputation: 2841
I have some button controls which fire off lengthy processing. Do I have to worry about the user pressing the button and firing off another execution while a first execution is active?
I found I could use the click events to disable the button, call the processing routine, and then enable the button. But this seems fraught with danger if the processing routine fails.
I could add on error stuff in the click routine to catch failures but would any on error calls in the processing routine cancel those out?
Upvotes: 1
Views: 299
Reputation: 2841
I decided to disable the button in its click handler, then re-enable it after calling the processing routine.
Private Sub CommandButton2_Click()
Dim s As Integer
s = CommandButton2.Enabled
If s Then
On Error GoTo Fail
CommandButton2.Enabled = False
GetData
Fail:
CommandButton2.Enabled = True
End If
End Sub
I also find this more pleasing than removing the default embedded formula =EMBED("Forms.CommandButton.1","") and attaching a macro.
Upvotes: 1
Reputation: 27488
I get the opposite result as enderland, with a button on a form or on a sheet (button from the Forms menu). I set a static variable that will increment each time the button is pressed, and if I press it while the code is running, it runs and increments again. So I'd say yes, you need to set a global variable to handle this:
Sub CommandButton1_Click()
Static Incrementer As Long
Dim i As Long
Incrementer = Incrementer + 1
For i = 1 To 1000
Debug.Print Incrementer
Next i
End Sub
Upvotes: 0
Reputation: 166885
From experience I've found it's safer to expect that you might see multiple parallel executions, and plan to avoid them. Try this with and without the marked line and clicking the button repeatedly:
Sub CommandButton1_Click()
Static InProgress As Boolean
If InProgress Then Exit Sub 'try commenting out...
InProgress = True
Debug.Print "starting...."
DoProcessing
Debug.Print "....Done"
InProgress = False
End Sub
Sub DoProcessing()
Dim x As Long, v
For x = 1 To 1000
ActiveSheet.Cells(x, 1).Copy ActiveSheet.Cells(x, 2)
DoEvents
Next x
End Sub
This specific behavior is caused by the DoEvents
call - without this you should not see parallel runs, as enderland noted.
Upvotes: 2
Reputation: 14185
Do I have to worry about the user pressing the button and firing off another execution while a first execution is active?
No - as long as there's no chance there's any code in your processing which calls DoEvents
.
Try assigning the following code to a button in your worksheet (you may need to adjust the iterators higher to get sufficient runtime) and clicking an additional button - or doing anything else in Excel for that matter.
Sub test()
For i = 1 To 100
For j = 1 To 100
Range("A1").Select
Next j
Next i
End Sub
An added bonus is it helps illustrate how .select
causes slower operations in working with Excel...
I found I could use the click events to disable the button, call the processing routine, and then enable the button. But this seems fraught with danger if the processing routine fails.
It is probably a good idea to include some sort of error handling regardless of simply reenabling buttons for any meaningful operations unless you are the sole user.
I could add on error stuff in the click routine to catch failures but would any on error calls in the processing routine cancel those out?
You would have to properly account for errors and the different places. The answer to this is "it depends on your implementation."
Upvotes: 0