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.
Related
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
I have a macro that opens a userform to capture a start and end date. After clicking OK on the userform, a file dialog box opens to select an Excel Workbook to open.
Immediately after I run the below sub, I can't close the workbook that is opened by using the 'X' in the top-right corner. I also can't save the workbook by clicking the save icon.
However, if I click on another workbook or switch to a different sheet in the workbook that was opened, and then click back to the one opened by the sub everything works as it's supposed to.
Also, I replace the userform with two input boxes, to capture each of the two dates, I am able to close the workbook that is opened with no issue.
Maybe there's something funny with the userform code?
This is all that is in the userform.
Private Sub Ok_button_Click()
call module1.forecast
unload userform1
end Sub
And this is the main sub.
Sub forecast()
dim start_SFY as long
dim end_SFY as long
dim filesToOpen as object
dim wb as workbook
Application.ScreenUpdating= False
start_SFY = userform1.textbox1.value
end_SFY = userform1.textbox2.value
set filesToOpen = application.fileDialog(msoFileDialogOpen)
filesToOpen.show
set wb = application.workbooks.open(filesToOpen.selecteditems(1),false)
Application.ScreenUpdating= True
End Sub
Here's the sub showing userform1
Sub run_userform()
userform1.show
End Sub
Also, here is the Excel version:
Excel 2013 64-bit (15.04753.1003) Part of Microsoft Office 365 ProPlus
Can someone maybe try to replicate the issue that I'm having? I'm wondering if this is an issue related to my employer's version of Excel or something?
This sort of thing has never happened to me before.
Also, I can close the program with VBA. It's just when trying to click the 'X' that it won't close.
Update:
I was able to get the code, with no changes, to work fine at home on Excel 2016. I'm going to get a coworker to test on their system today.
When I was home, I didn't put a button to call the sub on a worksheet. I called it from the VBA editor. After some testing this morning, it seems that the button is the issue. If I call the sub from the VBA editor, I can close the opened workbook. However, if I use a command button (form control, not ActiveX as I get an error saying, "Cannot draw object" whenever I try to add any kind of ActiveX object to a worksheet) the opened workbook will not close.
I think I have found the problem
This issue seems to be with the 'form control command button'. ActiveX was disabled in the Trust Center. When I enabled it and created a command button, I was able to close the opened workbook. I then tried the command form button again, and could not close the opened workbook. I was also successfully able to close the opened workbook when I ran the sub from the sub listbox in the developer tab, and when I place the sub in the Excel Ribbon and ran it from there.
Any idea as to why the control form command button would cause this issue?
The root of the problem is the change to using multiple excel interfaces in 2013. Microsoft addresses the issue in the Solutions for SDI Issues section of this page.
A workbook cannot be closed by clicking the red "X" Close button when
that workbook is programmatically opened via a modal user form. To
work around this issue, it is suggested that you add the following
code to the user form Layout event procedure and then open the user
form as modeless
Private Sub UserForm_Layout()
Static fSetModal As Boolean
If fSetModal = False Then
fSetModal = True
Me.Hide
Me.Show 1
End If
End Sub
Another option is to open the workbook window, activate any other
window, and then reactivate the workbook window. You should now be
able to close the workbook using the Close button.
So these are the two options they present and one I came up with.
Option 1) You can switch your dialog to modeless using their code, or by setting the ShowModel property to false in your userform.
Option 2) As you discovered, manually switching between workbooks after opening via modal userform resyncs everything. Not a good solution for the users of my code, and I don't recommend relying on it.
Option 3) It's worth mentioning, if you don't open the file via the userform then there's no issue. So if last thing the userform needs to do is open the file, you can easily save the file path in a string, unload the troublesome userform and move the workbooks.open call after closing. Here's an example of what I mean
Public EDIT_FILE_DIRECTORY As String
Public Sub Main()
fileOpenerForm.Show
If EDIT_FILE_DIRECTORY <> "" Then
Call Workbooks.Open(EDIT_FILE_DIRECTORY)
End If
End Sub
And in the userform something along these lines, where the filename is created based on userform parameters and a listbox selection:
Private Sub OpenSelectedWorkbooks_Button_Click()
Dim workbookName As String
workbookName = selectionList.Item(Me.FileSelection_ListBox.ListIndex + 1)
EDIT_FILE_DIRECTORY = ROOT_DIR & GetSelectedSubfolder & "\" & workbookName
Unload Me
End Sub
Try fileOpenerForm Show 0 to open open it with Modal = False (Makes the macro run while the Userform is visible)
Do not forget to add fileOpenerForm.Hide later on.
Also Load fileOpenerForm and Unload fileOpenerForm may be useful
I have a workbook that crashes Excel on close when the close is triggered by an API timer.
Edit: The workbook in link below has nothing but the timer and exit modules and it has the same behavior so it's not an issue with the content.
https://www.dropbox.com/s/x0xdwgj5h34ctdk/Book1.xlsm?dl=0
A few seconds after the workbook closes Excel crashes. I have tried turning the timer off, unhiding all sheets, unloading forms...all the objects are set to Nothing.
All I am doing is Workbooks(ThisWorkbook.Name).Close SaveChanges:=True??!!
The same sub is called from a UserForm with no problem. The workbook closes without Excel crashing.
How to fix this?
Sub ApplicationExit()
' Call UnloadAllForms
' DoEvents
' Sleep 1000
' Call StopCloseTimer
'DoEvents
'If Application.Workbooks.Count = 1 Then
' Workbooks(ThisWorkbook.Name).Save
' Application.Quit
'Else
DoEvents
Workbooks(ThisWorkbook.Name).Close SaveChanges:=True
'End If
End Sub
The code triggered by the timer is;
Sub TimerCalled()
If CloseTimerValue = "" Then Call Reset_CloseTimerValue
DoEvents
If basTimers.CloseTimerValue <= Now() And Not Unlocked Then Call ApplicationExit
On Error Resume Next 'In case sheet is protected
ThisWorkbook.Sheets("JobIndex").Range("CloseCount").Value = Format(Now() - CloseTimerValue, "hh:m:s")
End Sub
The userform says;
CloseUp:
i = MsgBox("Close Project Register?", vbYesNo, MsgBoxTitle)
Select Case i
Case vbYes
Call ApplicationExit
Case vbNo
Workbooks(ThisWorkbook.Name).Save
End Select
Timer in excel vba is done by using the Application.OnTime command or windows timer, as you are using.
Notice that, to schedule the call for a function (using the upper-mentioned command), it's used APPLICATION, which means it tells EXCEL to execute the call, not your workbook. So, in your case, the workbook is closed, BUT the to-be-called procedure is still scheduled to go off at some time in the future. The error that you get is that the excel doesn't find the procedure and then throws an error.
The reason it crashes in your case is that you are using windows timer to do it. When you close your workbook, your instance of the lib32 is lost and when time comes, Windows can't reach in the memory and then crashes the whole application.
In both cases, it seems that your scheduled procedure is still running.
I suggest that you look into that and consider using application.ontime.
I have a workbook with many sheets, each sheet has varying number of equations that inter-link with each other. I have a workbook wide VBA timer that is supposed to run every 5 seconds.
When I am active on a sheet that doesn't have a lot of formulas on it, it seems to run exactly once every 5 seconds... However, if I then change the active sheet to a more "busy" sheet, the vba timer just doesn't go off... Or if it does go off it was like minutes later. It is not until I switch to a less busy sheet again and then the timer runs magically like normal without having to reset anything.
I do not have any special VBA code specifically on the busy sheets... and I can't see why the VBA timer code won't run consistently across all sheets? If the timer is to be affected, it should be affected across ALL sheets and not only certain ones.
Here is the VBA timer code:
Sub TimerTick()
On Error GoTo ErrorHandler
If toggletimer = True Then
RunMyCode
runWhen_ES = Now() + TimeValue("00:00:05")
Application.OnTime EarliestTime:=runWhen_ES, Procedure:="TimerTick", Schedule:=True
End If
ErrorHandler:
End Sub
The issue is Excel has a hard time running a macro and letting other processes run. Add this after you specify your wait condition:
DoEvents
Excel will release the resources and threading used for running the macro instead of churning on it the whole time the wait is going on. This should allow your spreadsheet to function normally between wait cycles.
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