Run macro if button is not clicked in certain amount of time - vba

I have 3 spreadsheets that I am auto-opening every morning using the task scheduler. Upon opening, I have used VBA to automatically update, save, and then close each file.
The code to do this works perfectly, but causes some hassle if I want to open the spreadsheets to edit them (I have to open them specially to not run the macro and therefore automatically close). I want to be able to open the spreadsheets normally for editing without them closing automatically.
A possible solution is to have a MsgBox pop up. If the MsgBox is not acknowledged within 15 seconds (or so), then the file automatically closes. If the MsgBox is acknowledged, then the file does not close.
Does anyone know how to do this?

First
Create a sub routine with name (Close) with following code
Unload UserForm1
Second : call that routine after 15 seconds
Private Sub UserForm_Initialize()
tmeKill = Time + TimeValue("00:00:15")
Application.OnTime tmeKill, "Close"
End Sub

Related

Automatic refresh a file at specific time

I have a question about refreshing data in excel. How can I refresh an excel file, that is on the server (PLSQL query) at a specific time with the computer turned off?
Sub MyCode2()
code()
End Sub
Sub Workbook_Open()
Application.OnTime TimeValue("01:00:00"), Procedure:="MyCode2"
End Sub
I tried this and "Call", but it doesn't work.
If the system is turned off, you cannot open Excel or run a macro
Have you looked into PowerAutomate? That can do a lot of the same things as a macro (like refresh things) but on the cloud meaning no need for a PC to be on

Run Excel Macro at Certain Time

I'm trying to set up my code to run a macro daily at 4am. As a testcase I wanted to check if it would run a test macro. I set it to run at 4:40pm, but it does not run at that time period (don't get a msgbox). I would really appreciate some advice on how to get it working so I can proceed with the actual running of the 4am macro.
Code:
Sub RunDailyProcess()
Application.OnTime TimeValue("16:40:00"), "TestMacro"
End Sub
Sub TestMacro()
MsgBox "it works!"
End Sub
Thanks!
It can be done one of two ways.
One would be through windows task scheduler. Where you will set up a task to run Excel.exe yourfile.xlsm. Then bind your macro to the workbook "WorkBook_Open" event, with a check on current time.
Go to Task Scheduler, on the right click on "Create Basic Task...". Give the task a name and click next. Select a trigger (Daily in the case you mentioned here) and click next. Set the time and recurrence period and click next. In the Action, select "Start a program" and click next. In the Program/script text box browse for your Excel file and click next (leave the other text boxes empty). Click on Finish. I just tried this on my PC now, and it works.
See Starting excel file with task scheduler
See Task scheduler + VB script to auto open excel
Or
Use the code:
Private Sub Workbook_Open()
Application.OnTime TimeValue("04:40:00"), "MyMacro"
End Sub
Sub MyMacro()
Dim rtn As Integer
rtn = MsgBox("Good to Go!", vbOKOnly + vbInformation, "GTG")
End Sub
Things to keep in mind if you use the code:
You will need to make sure that excel remains open for the Application.OnTime to work, Excel will not be frozen/tied up. Putting it in the workbook open event, or something like that, to automatically have it run.
Either way:
Ensure your macro setting is enabled at all times because this will ensure that every time your workbook opens, the macro runs without any notification or confirmation.
To do this:
Excel Options > Trust Center > Trust Center Settings (Button) > Macro Settings > Enable All macros > OK

VBA user form closing causes excel to hang

I'm having an issue here with a macro causing excel to hang. I've tried several options and searched endlessly. I have 3 forms, but separate. Here's my steps in it:
Userform pops up
Item from listbox is double clicked in the form.
That opens another workbook and runs code on each sheet.
(This is done in another function and works perfectly and takes about 15 seconds ending with the focus on the new workbook.)
Closes the userform. (This causes it to hang from 7 seconds to 90 seconds depending on the other workbooks size.)
Code below (please excuse the improper format, I had to use my phone... can't login via computer.)
Private sub lb_blah_DblClick (Byval Cancel as MSForms.ReturnBoolean)
Me.lbl_blah2.caption = "opening aND running"
'Open and edit xls - Works fine.
LoadAndFormat me.lb_blah.value
Me.lbl_blah2.caption = "Ran through format."
Me.repaint
'90 seconds with 29 sheets
'Me.hide
'Application.enableevents = false '70 seconds
Unload me '90 seconds - 29 sheets
End Sub
I restarted my computer, and that seemed to fix it. I'm sorry.

Application.Quit in UserForm attempts to run rest of macro before exiting

My question is: using VBA in Excel 2013 how can I gracefully close an entire instance of Excel when the user decides they don't want to fill out a UserForm and clicks quit or cancel?
Currently, if the user clicks quit or cancel, I check to see if my instance is the only one open. If it is not, I can use ThisWorkbook.Close and I think I will be okay. However, if it is, I do not want the application to still be present, so I used Application.Quit. This, though, tries to finish running the macro, throws errors (originally "type mismatch" because I unload the form), and only closes after I click "Debug" or "End" (which it does so fast for either I cannot actually debug). I'm ignoring the first case for now and just trying to exit the entire application. It's a very long macro with a lot of subroutines and functions, so for debugging and posting here, I have shortened it. The type mismatch error no longer occurs, but I believe that was a consequence of the actual error: code running after the command to close the application is called.
First, here's the code that starts everything:
Private Sub CommandButton1_Click()
Call form_variables
frm_REQUEST.Show
Call a_REQUEST_main
End Sub
The subroutine
form_variables
is a subroutine that creates public variables so I can store the data from the UserForm.
frm_REQUEST.Show
initializes (including calling a function that finds another workbook, extracts a list, does some formatting, closes the workbook and enters the list into the userforms drop down box) and shows the form, and finally
a_REQUEST_main
uses the public variables (where UserForm data is stored) and does its thing (but shouldn't do anything if the UserForm is closed).
The code that is executed when .Show is called is:
Private Sub UserForm_Initialize()
' Get job numbers from other workbook
Dim job_selection_list As Variant
job_selection_list = get_job_list()
With frm_REQUEST.Job_Number_ComboBox
.List = job_selection_list
End With
' set focus on Job Numbers
JN_combobox.SetFocus
End Sub
Private Sub cancel_button_Click()
Set job_selection_list = Nothing
Unload Me
Application.Quit
End Sub
Private Sub submit_button_Click()
' Values from userform saved as global (?) variables so other subroutines can access.
End Sub
I stepped through the program and saw that, once Application.Quit is called in the UserForm, the macro, in the main subroutine, steps to
Call a_REQUEST_main
but it should really just close everything out. I tried doing "save" commands, and changing the order of things, and read about objects needing to be set to nothing (hence the setting of the job_selection_list which is created when the drop down list is initialized), but I cannot seem to get this to work, or find anything online. Can anyone provide some guidance or let me know of a better way to close an excel instance? Help me Stack-Overflow Kenobi, you're my only hope!
Thanks.
Just add a variable to account for when the user closes the form
in the form
'hold flag if users cancels form
Public btnCancel As Boolean
Private Sub CommandButton1_Click()
Unload Me
btnCancel = True
End Sub
'set the flag each time the form active
Private Sub UserForm_Activate()
btnCancel = False
End Sub
then in your code
Call form_variables
frm_REQUEST.Show
If frm_REQUEST.btnCancel Then
Application.Quit
Else
Call a_REQUEST_main
End If
Put Application.Quit in the form's Terminate event handler instead of in the button's Click event handler.
The reason is that clearly the procedure will keep running even if the form has unloaded. So use the events to your advantage.
Putting it in the Click event will unload the form, but the procedure will keep running which of course may raise errors or other undesired effects.
Note: You may be prompted to save/discard changes (if any) to the workbook.

Can I display something while a macro is running?

I have a macro that takes roughly five seconds to execute and I'm using the code Application.ScreenUpdating = False so it looks like Word has locked up when it's running.
I use a message box at the end to tell them it's complete, but I'd like to display an image during its execution that tells the user the macro is running (primarily so they don't get worried, but also because it's nicer to look at).
There might be an easier way to go about this, but I decided to create an image, create a very basic user form, and simply set my image as its background. Then, I have that user form pop up as soon as the code starts to run.
The problem I'm having is that unless I close it, the rest of the code won't execute. It just hangs until I do something. Is there a way I can get the user form to be displayed without stopping the rest of the process? If not, is there another approach I can take to display an image while the macro is running?
You can show the userform as non-modal:
Userform1.Show False
'do more stuff (doesn't wait for form to close)
Userform1.Hide
I too have found that if you .show a userform at the beginning of the process, images contained within userform take a while to display and the result is less than smooth.
I have solved it by inserting a 1 second "wait" immediately after the userform.show instruction. In that split second, the image loads and displays successfully and the result is seamless.
Here the code. I have 2 macros: 1 to display and 1 to hide. I call the first macro at the beginning of the process just before freezing the screen and the second at the end of the process just before unfreezing the screen
Userform name is "myuserform"
Sub message_show()
userform.Show False
Application.Wait (Now + TimeValue("0:00:01"))
End Sub
Sub message_hide()
Application.Wait (Now + TimeValue("0:00:02"))
userform.Hide
End Sub