Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations sizbut on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Abort code upon msgbox click.

Status
Not open for further replies.

RP1America

Technical User
Aug 17, 2009
221
US
I have a userform, where upon a click event, 246 Word documents are opened, bookmarks populated, saved, and closed in succession.

I would like to create a message box to come up at the beginning of this process that asks the user if they want to abort, since the entire process takes 5 - 7 minutes. I would like to give them the option of aborting if they realize half way through that they entered something incorrectly and need to start from scratch.

Currently I have this...

Code:
Private Sub cmdCreate_click()


'abort message box
If MsgBox("Abort File Creation?", vbMsgBoxSetForeground, "Abort?") = True Then GoTo FINISH:

'''''''additional code here that creates the docs

FINISH:

'close document if more Word documents are open, otherwise close Word application
If Documents.Count > 1 Then
   '  more than one doc open
   ActiveDocument.Close
Else  ' count = 1
   ActiveDocument.Close
   Application.Quit
End If


End Sub

I thought it might completely bypass the code that creates the docs if the OK (abort) were clicked.

However, currently when the message box comes up, the rest of the code halts and waits for the "OK" button to be pressed. Even then, it continues on creating the documents. What am I missing? I would like the rest of the code to run, UNTIL the button is pressed. Once pressed, everything stops.


Any ideas?

Thanks!
 


Hi,
the rest of the code halts and waits for the "OK" button to be pressed. Even then, it continues on creating the documents. What am I missing?
are you saying that

'''''''additional code here that creates the docs

runs while the message box is waiting for an answer?

Skip,

[glasses]Just traded in my old subtlety...
for a NUANCE![tongue]
 
These two sentences are inconsistent with each other. My bolding.

1. "I would like to create a message box to come up at the beginning of this process that asks the user if they want to abort, since the entire process takes 5 - 7 minutes."


2. "I would like to give them the option of aborting if they realize half way through that they entered something incorrectly and need to start from scratch."

One talks about the start of the process, the other halfway through.

You can do one, or the other. But not both.

You need to read up on Scope and focus...amd MsgBox.
I thought it might completely bypass the code that creates the docs if the OK (abort) were clicked.
No. Why would you think clicking OK would do anything, never mind abort. It is an OK button. It returns a number. Unless you write code that indicates what to do BECAUSE that number = X...nothing happens.

Code:
If MsgBox("Abort File Creation?", _
   vbMsgBoxSetForeground, "Abort?") = True Then
1. passes focus to the messagebox. NOTHING happens until it is closed.

2. when it does close, and there is only the OK button, it will always return False. Try this:
Code:
Sub Alwaysfalse()
If MsgBox("Abort File Creation?", _
      vbMsgBoxSetForeground, "Abort?") = True Then
   MsgBox "It is True."
Else
   MsgBox "It is False."
End If
End Sub
It will always display "It is False."

Oh, and my comment: "You can do one, or the other. But not both." is not totally accurate. You can not decide "halfway" through a set of instructions to abort those instructions. You can kill the entire thing, but that is it.

"A little piece of heaven
without that awkward dying part."

advertisment for Reese's Peanut Butter Cups (a chocolate/peanut butter confection)

Gerry
 
Just to be clear (perhaps I was not):


"I thought it might completely bypass the code that creates the docs if the OK (abort) were clicked."

No, because the MsgBox is never True, so it never jumps to FINISH.

Therefore, after the MsgBox closes, the next instructions:

'''''''additional code here that creates the docs

execute.

And when they are done, FINISH: executes.

BTW: Skip is being slightly sarcastic. He knows full well that the "additional code" does not run while the MsgBox is waiting for an answer.


"A little piece of heaven
without that awkward dying part."

advertisment for Reese's Peanut Butter Cups (a chocolate/peanut butter confection)

Gerry
 
If your additional code does not have an 'Exit Sub' before the 'FINISH' line, then it will continue to run through that code as well.
 
Another good point, although from what I gather from other posts, the code in FINISH is desired. The OP wants the instructions in FINISH to execute.

"A little piece of heaven
without that awkward dying part."

advertisment for Reese's Peanut Butter Cups (a chocolate/peanut butter confection)

Gerry
 
Ah, I must have misunderstood the requirements from the thread title. The word 'Abort' tends to lead me to think of exiting the sub.

As was suggested in the other thread, I think part of the problem is that the code needs to be better broken up into discreet functions.
 
Oh yeah. But I am VERY curious as to what is actually in such an huge amount of code!

"A little piece of heaven
without that awkward dying part."

advertisment for Reese's Peanut Butter Cups (a chocolate/peanut butter confection)

Gerry
 
Actually you are correct. The subject title does indeed imply an abort. I believe the OP wishes to do so. The problem of course is that they can not do it. At least not as described.

Scope and focus.

"A little piece of heaven
without that awkward dying part."

advertisment for Reese's Peanut Butter Cups (a chocolate/peanut butter confection)

Gerry
 
What about this ?
Code:
If MsgBox("Abort File Creation?", vbYesNo, "Abort?") = vbYes Then Exit Sub

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Gerry and others:

Thank you for your input on this, and I apologize for being unclear.

My intentions have nothing to do with "halfway through"...that was simply looking from the user's POV. As in...I just clicked the button to make all of these files open, save and close...but I just realized that I entered an incorrect value and would now like to stop the process.

What I need is a msgbox to come up as soon as the click event happens that starts this 5 - 7 minute process. I would like this message box to be a 'way out' of having to let the entire process run if the user realizes they made a mistake - right after they run the click event, "halfway through" :) , or even 5 or 6 minutes in.

I need the process to run while this msgbox is open and displayed to the user, then only if the user presses OK on the abort msgbox would the entire process stop. Otherwise, if they never press it, the process completes and the msgbox closes.

I hope this makes more sense. Thanks for your patience and understanding!

 
Does vbApplicationModal have an opposite (of sorts)?

vbApplicationModal freezes the application until the message box is cleared.

I need the application (procedure) to continue running until either the user clicks the message box button or the procedure reaches its end.
 
>would the entire process stop

However, at this point some changes would already have been made, and the remainder not. Would you want to roll back the changes already made? You need to think through the repercussions of what you are suggesting.

Notwithstanding the above you can't really do what you are asking with a VB messagebox, since in VB they are Modal - which means that everything else in your application stops until the messagebox is closed. So you to achieve your basic requirement you need to not use a VB messagebox. One technique involves creating your own from that looks just like a messagebox, but which can be shown non-modally.
 
strongm said:
However, at this point some changes would already have been made, and the remainder not. Would you want to roll back the changes already made? You need to think through the repercussions of what you are suggesting.

Thanks for bringing this up! I have in fact considered it and believe that I have an easy 'out' for that. I can simply delete the 5 main folders (which are created within the procedure) that all of the documents are being saved into, therefore bringing things back to 'start'.

strongm said:
Notwithstanding the above you can't really do what you are asking with a VB messagebox, since in VB they are Modal - which means that everything else in your application stops until the messagebox is closed. So you to achieve your basic requirement you need to not use a VB messagebox. One technique involves creating your own from that looks just like a messagebox, but which can be shown non-modally.

I think I understand now. Yet if that is the case, then what is the ponit of vbApplicationModal? If there is no way to get around it, why is it an option to 'turn it on' bot not turn it off? (perhaps I don't understand the point of it)

Can a userform (designed to look like a msgbox) be brought to the foreground the same as a message box can?

I think I have an idea of where I need to go now. Thanks strongm!
 
Found this from a different forum. The following question was asked, and only one reply with "I don't think you can."

Anyone here know of a way?

I would like to have a commandbutton to stop/abort/end/break execution of a macro/code. Working similar to hitting the 'Esc' button while code is executing would be fine, but I would prefer not to have the pop-up box that asks if you want to continue/end/debug/help and just end. Any ideas?
 
I need the application (procedure) to continue running "

You may need that, but they are two entirely different things.

You must get this concept. A procedure is simply a set of instructions. Nothing more. These instructions MUST execute within an application, thus Visual Basic for Applications.

Even when you have a messagebox and everything "stops" until the messagebox procedure finishes, what stops is any other procedures. The application itself is still in memory (loaded). The application is still "running".

More properly, you need to grasp what is an instance (the Application), and what is a procedure (a set of instructions).
I need the process to run while this msgbox is open and displayed to the user, then only if the user presses OK on the abort msgbox would the entire process stop. Otherwise, if they never press it, the process completes and the msgbox closes.
This is not possible. What this implies is that TWO processes (procedures):

1. the file activity instructions
2. the messagebox

are happening at the same time!

Sorry, but it simply does not work that way. VBA is sequential. Instruction_A, then Instruction_B, then Instruction_C......

There is no way to execute Instruction_A and Instruction_C at the same time. One must finish before the next starts.

vbSystemModal (on a messagebox) on a Win32 system makes the messagebox on top of ALL applications. Switching to another application will keep the messagebox still visible, but NOT in focus. Clicking on it (but not the button) will bring it to focus, as well as the application that it came from.

vbApplicationModal (the default) on a messagebox makes the messagebox on top of THAT application.

Neither makes the messagebox independent of everything.

Otherwise, if they never press it, the process completes and the msgbox closes.
If they "never press it", what pray tell will close it? If all you have is an OK button, then WHAT closes it?

PHV was moving closer with:
Code:
If MsgBox("Abort File Creation?", vbYesNo, "Abort?") = vbYes Then Exit Sub
in that there is a Yes/No choice (rather than just OK).


However, it still does not do what you want. The messagebox would execute at the start, so the user could Abort (a Yes) at the start. Not anywhere else.

It is either yes, Abort - at the start, and stop, at the start - or No, in which case all the file instructions execute.

"A little piece of heaven
without that awkward dying part."

advertisment for Reese's Peanut Butter Cups (a chocolate/peanut butter confection)

Gerry
 
If you're wishing for your user to be able to cancel the document processing once it has begun, I'm pretty sure you can't do that with a MsgBox. In order to do that, I think the following code samples may be of some help. The first is a form with 1 label (lblPrompt) and 1 button (btnCancel)
Code:
Option Explicit

Private mCanceled As Boolean

Public Property Let Title(value As String)
    Me.Caption = value
End Property

Public Property Let Prompt(value As String)
    lblPrompt.Caption = value
    Me.Repaint
End Property

Public Property Get Canceled() As Boolean
    Canceled = mCanceled
End Property

Private Sub btnCancel_Click()
    mCanceled = True
End Sub

Private Sub UserForm_Activate()
    mCanceled = False
End Sub

Then in your document processing routine, you can check whether or not the user has clicked the Cancel button and exit the loop. Of course any processing within the current loop cycle would need to complete.
Code:
Option Explicit

Public Sub Main()
    Dim documentNumber As Integer
    
    frmCancel.Title = "Processing Word Documents"
    frmCancel.Show vbModeless
    Do While (Not frmCancel.Canceled And documentNumber < 12)
        DoEvents
        
        documentNumber = documentNumber + 1
        
        frmCancel.Prompt = "Processing document " & CStr(documentNumber)
        
        Application.Wait (Now + TimeSerial(0, 0, 3))
    Loop
    
    Unload frmCancel
    
    MsgBox CStr(documentNumber) & " document(s) processed."

End Sub
 
>one reply with "I don't think you can."

Well, we can ... but the code has to be constructed carefully to support this. For example add a module to your VBA project, and paste inthe following code:
Code:
[blue]Option Explicit

Public CancelRoutine As Boolean

Public Sub ExampleCode()
    Dim starttime As Date
    
    CancelRoutine = False
     
    starttime = Now
    
    Do
        DoEvents
    Loop Until DateDiff("s", starttime, Now) > 10 Or CancelRoutine ' Run for 10 seconds or until cancelled
    
    ' How did we terminate the code?
    MsgBox IIf(CancelRoutine, "Cancelled", "Timed out")
End Sub[/blue]

Now you need a user form with two command buttons, cmdCancel and cmdRunExample, and the following code:
Code:
[blue]Option Explicit

Private Sub cmdCancel_Click()
    CancelRoutine = True
End Sub

Private Sub cmdRunExample_Click()
    ExampleCode
End Sub[/blue]

Run the userform, and now youi can click cmdRunExample to kick off the example code. You can then either cancel it with cmdCancel or let it complete (which it will do in 10 seconds). It isn't elegant, but it demonstrates the principle.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top