Excel VBA: Confirmation on Pressing CommandButton - vba

Upon pressing my CommandButton, I would like to have a pop-up that asks "These changes cannot be undone. It is advised to save a copy before proceeding. Do you wish to proceed?"
And I want to have three options:
Yes - pop-up window is closed and CommandButton Macro is executed
No - This closes the pop-up window and changes nothing
Save - closes pop-up window and opens "Save As" (macro is not executed)
I don't really know where to start with this. Could you please give me a hand?
Thank you very much indeed.

You can use a message box, but that is somewhat limited. You can rephrase the question slightly to use the vbYesNoCancel buttons, since Save As is not an optional button on Message Box.
Then you can work with the result of the message box button-click:
Dim mbResult as Integer
mbResult = MsgBox("These changes cannot be undone. Would you like to save a copy before proceeding?", _
vbYesNoCancel)
Select Case mbResult
Case vbYes
'Modify as needed, this is a simple example with no error handling:
With ActiveWorkbook
If Not .Saved Then .SaveAs Application.GetSaveAsFilename()
End With
Case vbNo
' Do nothing and allow the macro to run
Case vbCancel
' Do NOT allow the macro to run
Exit Sub
End Select

I suggest you put code at the top of your macro to ask this question and respond to the answer.
This would look something like:
Sub YourMacro()
if MsgBox("These changes cannot be undone. It is advised to save a copy before proceeding. Do you wish to proceed?", vbYesNo + vbQuestion) = vbNo then
exit sub
end if
... the rest of your macro.
Note that this will not give the user the Save option. You can't do that with a standard MsgBox. If you want to do that, you will need to create your own userform, show that instead of the MsgBox and respond to what button in the Userform the user pushed. That is a lot more work for you than just using a MsgBox, but if you want your UI to be fancy, it may be worth it.

Related

Check if field is null or blank before closing form on Access using VBA

I've been playing around this with VBA code to check if the field is empty before closing the form. If the field is empty, I want it to display a Yes/No message box.
The issue that I'm having is that when I click No after the message appears (if the field is blank), it continues to close the form. Instead, when I click No, I want the focus to set on the field that needs to be addressed.
Here's my code:
Private Sub Close_Click()
If IsNull(cboTxtBx) Then
MsgBox("Do you want to continue?", vbYesNo, "X is Blank!")
If vbYes Then
DoCmd.Close
Else
cboTxtBx.SetFocus
End If
Else
DoCmd.Close
End If
End Sub
I've also replaced IsNull() with Len(cboTxtBx.value & "") = 0 and still have the same issue.
I've also removed the last DoCmd.Close statement but the form still closes once I hit No.
I'm sure the solution lies within the sequence of my code but I'm not proficient with VBA and I'm struggling to get this code to work.
One small note, cboTxtBx is a combo box. Not sure if that interrupts the code in any way.
After you answer the message box its result is interpreted nowhere, so the code goes on.
You would have to use it like this to really check the result of the message box:
If MsgBox("Do you want to continue?", vbYesNo, "X is Blank!") = vbYes Then
DoCmd.Close
Else
cboTxtBx.SetFocus
End If

Pause VBA Word macro, allow user to make a selection, and restart where it left off

I have a requirement for VBA script in Microsoft Word to pause so that the user can select text that will be copied to the clipboard so that it can exported to an Excel file. The user will make a number of selections and finally indicate he/she is done when the contents of the clipboard will be copied to a template Excel file.
I have the code working to copy each selection to the clipboard and then all rows to the Excel file. But I need assistence in figuring out how to pause the code to allow the user to make the selection and then restart the code to copy the selection to the clipboard. I am able to get the userform with toggle switch to switch states and labels when pressed. But have not figured out how to pause the VBA code to allow the user to navigate to the next section of the Word document for the next selection.
The Stakeoverflow question/answer below appears to address this requirement but I have not been able to get it to work. It appears that the code is incomplete.
Pause VBA macro, allow user to make a selection, and restart where it left off
Can someone provide example VBA code that accomplishes this?
Your assistence is much appreciated as I have been beating my head against the wall and it is starting to hurt!
There's no way in VBA to "pause" a macro. Code must run to completion... Unless there's a command for user input.
Input can be requested via the InputBox and MsgBox methods, but those block access to the document because they're modal. A UserForm, however, can be set to display as non-modal, meaning it stays on top, but doesn't block access to the document or the application features. Since you're already working with a UserForm, this can be implemented relatively easily.
In the small example below, the Continue button runs the code to perform an action on the user selection. When Done is clicked the entire code is exited and the form unloaded.
Code behind the user form
Option Explicit
Private Sub cmdContinue_Click()
Debug.Print Selection.Range.Text
End Sub
Private Sub cmdDone_Click()
Me.Hide
End Sub
Private Sub UserForm_Activate()
'Position the form near the top-left of the window
'So that the user can work with the document
Me.Top = Application.ActiveWindow.Top + 50
Me.Left = Application.ActiveWindow.Left + 50
End Sub
Code in a regular module
Option Explicit
Sub DisplayModeless()
Dim frm As frmModelessForInput
Set frm = New frmModelessForInput
frm.Show False 'Display as non-modal
Set frm = Nothing
End Sub

Closing msgbox from another file

I'm using several excel files and each one is making some calculations using VBA. Now I'm working on one file which will run each file one after another and calculate them all with one click. Unfortunately at the end of calculation for each file there is Msgbox "Report updated" and my macro stops and is waiting to confirm "OK" manually before it will close first file and open next one.
I cannot remove this lines with msgboxes because some people will use just one file and they need to be informed that everything is finished.
And here is my question: How can I close this msgbox automatically?
Thanks in advance
I think it is impossible, because MsgBox is modal. But why your macro displays it at first? You may add conditional instruction that checks if the sheet on which it works is displayed. Something like:
If ActiveSheet.Name = wsProcessedSheet.Name Then MsgBox "Report updated"
So, the message will be displayed for normal user and not for your supermacro. Alternatively, you could disable the MsgBox only for your machine:
If Environ("username")<> "your user name" Then MsgBox "Report updated"
Thank you for interesting ideas.
I've just figured out different solution. Originally I had button which run macro Update()
Sub Update()
...calculations....
Msgbox "Report updated"
End Sub
Now I removed msgbox from this macro and created two macroslike below:
Sub ButtonClick()
Call Update
Msgbox "Report updated"
End Sub
Sub Update()
...calculations....
End Sub
And now button is running macro ButtonClick and in external file I can use macro Update() which didn't contain msgbox.
But I still wondering if there is any way to confirm msgbox alerts

Set focus on textbox after performing print command

Please help me case below:
When I write code for print command by vba then it run OK.
But after run print command then cursor don't focus on textbox.
what do I must use command to cursor focus on textbox?
Thank you so much.
If TextBox1.Text = "PRINT" Then
ActiveSheet.PrintOut
TextBox1.Value = ""
Call CData
ThisWorkbook.Save
ThisWorkbook.Activate
UserForm1.TextBox1.SetFocus
End If
Because I am writing macro for scan barcode on textbox, so I need to automatic process after perform print, it can continue receive scan barcode on textbox, no must click on textbox before scan barcode.
Check first if there is any error message and where your code is located (module, userform, worksheet or workbook code).
Are you sure that your If TextBox1.Text = "PRINT" condition is executed? Check this by inserting a beep command, some Debug.Print info for the immediate window or a Stop command allowing you to check code continuation manually by pressing F8.
You could try Windows(ThisWorkbook.name).Activate instead of only ThisWorkbook.Activate, especially if you are using more than one workbook and do some selection or activating.
If the TextBox situated on a page of a MultiPage control, you should activate this page first: e.g. Multipage1.Value = 0 (...) and then set focus via TextBox1.SetFocus.
Don't reference :-) UserForm1.TextBox1.SetFocus, but use Me.TextBox1.SetFocusor TextBox1.SetFocus :-) if this is code withIN your UserForm module.
You could also perform a Click() event on your TextBox, though that isn't best programming style: TextBox1_Click

Allow user to make entries on worksheet during run-time

All:
Thank you in advance, you all have been a tremendous resource!!!
I have a couple of spreadsheets where the sheet is protected, but users can still use filters. I'm processing most of the sheets automatically, but what I need to do, is present the user with the sheets that need to be filtered, then have them select a "Finish" type button or toolbar entry, which I already have.
What I need to be able to do, is to bring this sheet up, pause the macro, if possible, while they make their changes (could be up to 5 filters that they select before the sheet is ready.
Then, copy the visible cells only to a specific sheet and then resume the macro.
I don't think that Worksheet change event will do this.
I'm thinking more on the lines of maybe setting a flag on a spare sheet, firing up the next macro and then see if it can find the original macro and pick up where it is flagged?
I thought about a modeless userform that the user could click OK on and then call the next macro, but that does not work.
The calling code is:
UserForm3.Show
CopyToDisplay "AEP"
LastPos = LastPos + 1
Where AEP is the sheet name to copy the filtered rows from.
Userform displays, but clicking ok does nothing and of course, the macro keeps on going.
Any suggestions would be greatly appreciated!
Thanks,
Jeff
Jeff let's try this. Your current code:
UserForm3.Show
CopyToDisplay "AEP"
LastPos = LastPos + 1
When we display a UserForm, the default behavior is vbModal, which essentially freezes the application and the user cannot interact with anything but the UserForm, that is not what you want. What you need is a way to display the form, and then just wait for the user to signal that s/he is finished with the input.
So we need to modify a few things:
The UserForm needs to effectively "pause" while also allowing the user to interact with the worksheet. A vbModal form can't do this (it pauses, without interaction), and really neither can a vbModeless (it continues execution AND allows interaction).
Conundrum? No. we can simulate a pause with the vbModeless form, and preserve the user's ability to interact with the sheet. The best of both worlds!!
We will show the form with the optional vbModeless, this allows the user to interact with the rest of the Application /worksheets/etc. Since a modeless form continues code execution, we need to simulate a pause and we can do this with a Loop. The loop will run indefinitely, and only break once the UserForm is closed, at which point the rest of the code will continue to execute.
UserForm3.Show vbModeless
Do While UserForm3.Visible
DoEvents
Loop
LastPos = LastPos + 1
'You MAY need to reset some variables, if the Filter/Autofilter has affected these/etc.
Design-wise, give your form a single Label control and set its .Caption property (and the form's .Caption property) in some useful/instructive way. You could add a command button but that seems unnecessary, since all the button would do is invoke the Terminate event (which can always be done with the red "X")
For your issue with copying (apparent failure to paste), try changing this:
Sheets("AEP").Select
With ActiveSheet
.UsedRange.SpecialCells(xlCellTypeVisible).Copy _
Destination:=Sheets("Display").range("A" & LastPos)
.AutoFilterMode = False
Application.CutCopyMode = False
End With
To this:
With ActiveSheet
.UsedRange.SpecialCells(xlCellTypeVisible).Copy
Sheets("Display").range("A" & LastPos).PasteSpecial
.AutoFilterMode = False
Application.CutCopyMode = False
End With