Quantcast
Channel: Active questions tagged excel - Stack Overflow
Viewing all articles
Browse latest Browse all 88868

Consistently receiving user input through a long-running procedure (DoEvents or otherwise)

$
0
0

Cleanly cancelling a long API-Ridden procedure is hellish, and I'm attempting to work out the best way to navigate the hellishness.

I'm using excel 2016 (with manual calculations and no screen updates) - I may take some time to attempt to run the procedure on 2010 to see if any issues resolve in the coming days (I'm aware of the slowdowns).

Over time, my procedure LongProcedure has lost its ability to successfully use its cancel feature (presumably due to increasing complexity). It was initially inconsistent and required significant spam-clicking to cancel, and now it fails altogether

Here's the setup:
First, LongProcedure is in a class module LongClass with a public property checked against for early cancelling, allowing it to clean up.

Public Sub LongProcedure()
    ' [Set up some things] '
    For Each ' [Item In Some Large Collection (Est. 300 Items)] '' [Some Code (ETA 5 Seconds) Sprinkled with 3-4 DoEvents] '' [Export workbook (ETA 10 Seconds)] '
        If (cancelLongProcedure) Then Exit For
    Next
    ' [Clean up some things] '
    GeneratorForm.Reset ' Let the UserForm know we're finished
End Sub

Second, I have a UserForm shown from a macro, which instantiates the procedure class, and runs the procedure. It contains a run button, a status label, and a cancel button.

Private MyLong As LongClass

Public Sub ButtonRunLongProcedure_Click()
    Set myLong = New LongClass
    myLong.LongProcedure()
End Sub

So the issue overall is twofold.
The ExportAsFixedFormat call opens a "Publishing..." progress bar which freezes excel for around ten seconds - fine. In all of my efforts, I haven't found a single way to process user input while this is happening.
On top of this, the DoEvents calls seemingly no longer do anything to allow the cancel button to be clicked. The process inconsistently freezes excel, tabs into other open programs, and (when not freezing) updates the status label.

I've Tried:

  • Appending DoEvents to the SetStatusLabel method instead of sprinkling - while the form still often freezes, it otherwise updates the status label consistently (while still not allowing the cancel button)
  • Using winAPI Sleep in place of, and in addition to DoEvents with delays of 1, 5, 10, 50, and 250ms - The form simply stopped updating at all without doevents, and with both it froze more.
  • Using a Do While loop to run DoEvents constantly for one second (Froze)
  • Overriding QueryClose to cancel the form. This one helped significantly. For some reason, the close [x] button can be clicked far more consistently than the userform buttons - Still not as consistently as I'd like. The problem? during publishing, Excel stops responding, and as such, modern windows will end the process if you click the close button twice... without cleanup.
  • Using Application.OnTime to regularly call DoEvents. Didn't seem to improve the situation overall
  • Alt-Tabbing. No, really. for some reason, while alt-tabbing occasionally just makes the UserForm freeze harder, sometimes it makes it stop freezing and update.

This is an issue I'm willing to do significant refactor work for, including smashing up the idea of the long procedure into separate methods, performing setup initially, and cleanup on class termination. I'm looking for something that provides consistent results. - I'll accept anything from excel versions to excel settings to refactors to winAPI calls.

Thanks for any insight into this one.


Viewing all articles
Browse latest Browse all 88868


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>