I faced an interesting problem with my macro that parses log files (1GB).
Of course there are some settings as follows:
Application.ScreenUpdating = False
Application.DisplayStatusBar = True
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
Application.DisplayAlerts = False
Application.CutCopyMode = False
And also there is one general loop by log file lines with DoEvents within (to prevent excel screen from freezes).
The problem is the macro is very slow when my mouse pointer hovers over cells. Once the pointer moves away from the excel cells, the macro starts working 30 times faster! Any ideas why this happens and how to resolve the problem?
One proposed way is
application.visible=false
but it looks like excel crashes while the macro is running.
Something you can definitely add is:
Application.Cursor = xlWait
Then switch it back at the end
Application.Cursor = xlDefault
This will get rid of the cursor flickering
Related
This is the first time I couldn't find an answer to my problem on StackExchange. You guys are quite thorough. Anyway, we recently updated to Office 365/Excel 2016 from 2007, and now my VBA scripts won't run, except overnight. I researched and learned that I was a horrible person for using Select/Activate. I have seen the error of my ways, but now even simple code still doesn't want to run on a large sheet. My code, which clears the formatting from the current worksheet to make populating it with data faster:
Sub ClearFormattingAndValidation()
Dim referenceCell As Range
Dim rngToFormat As Range
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.EnableEvents = False
End With
Set referenceCell = Cells.Find("Some specific text", after:=ActiveCell, LookAt:=xlWhole)
Set rngToFormat = Range(referenceCell.Offset(2, 0), ActiveCell.SpecialCells(xlLastCell))
' rngToFormat.Select
With rngToFormat
.Validation.Delete 'near-instantaneous
.FormatConditions.Delete 'took 7-15 minutes on timed runs
End With
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
.EnableEvents = True
End With
End Sub
When I uncomment rngToFormat.Select, I get a total of 76,302 cells, to give you an idea of the size of the spreadsheet. There is a LOT of validation and conditional formatting. In 2007, even using Select/Selection, it ran in seconds. Now, I have no idea how long it takes. I gave up after 5 minutes. It does run successfully on a smaller version of the worksheet.
I would like to avoid removing the validation and conditional formatting if at all possible, but it IS a (time-consuming and costly) possibility for about half of it if that is the only way to speed it up.
Is there anything else that I can do to make the code run faster, or is there something that I'm doing wrong?
Edit: Code changed to reflect comments/suggestions as of 2/21. Similar results.
Your code runs instantly with Excel 2013.
Though the code can be written as below...
Sub ClearFormattingAndValidation()
Dim referenceCell As Range
Dim rngToFormat As Range
With Application
.Calculation = xlCalculationManual
.EnableEvents = False
.ScreenUpdating = False
End With
Set referenceCell = Cells.Find("Some specific text", after:=ActiveCell, LookAt:=xlWhole)
If Not referenceCell Is Nothing Then
Set rngToFormat = Range(referenceCell.Offset(2, 0), ActiveCell.SpecialCells(xlLastCell))
With rngToFormat
.FormatConditions.Delete
.Validation.Delete
End With
End If
With Application
.Calculation = xlCalculationAutomatic
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
With ActiveSheet
.EnableFormatConditionsCalculation = False
End With
This disables the conditional formatting that is causing the slowdown. It should be reenabled after the code is run.
thanks again, #sktneer. Your help pushed me in the right direction.
I have some VBA code as follows:
Sub copyData(fromRange as Range, toRange as Range)
Application.ScreenUpdating = False
<copy paste code here>
Application.ScreenUpdating = True
End Sub
Even though I am setting Application.ScreenUpdating to False, it remains at True. I have verified this using F8 and hovering over Application.ScreenUpdating (it shows True).
My copy paste code works. It switches worksheets but since ScreenUpdating remains at True, I can see the screen flicker.
Is there a way to set Application.ScreenUpdating to False?
P.S. I saw a similar question in this forum but there was no concrete resolution to it.
Any help will be greatly appreciated!
I've had the same issue for quite a while, and I figured out something: Application.screenUpdating only stays FALSE for how ever long a macro runs. When any macro running stops, it turns True. You can try this:
Sub testApplicationScreenUpdating()
Application.ScreenUpdating = False
Debug.Print "Application screen updating is:" & Application.ScreenUpdating
Application.ScreenUpdating = True
End Sub
if you just run this, it will return in the Immediate window: "Application screen updating is:False"
if you run it step by step, and hover over Applicaiton.ScreenUpdating with your mouse, it will show as "True", even if the Immediate window will show "False".
if you comment out the [Application.ScreenUpdating = True] at the end, and then run [Debug.Print "Application screen updating is:" & Application.ScreenUpdating] separately, it will return true, even if it was not switched to true.
Try this code and see the values for each in the Immediate Window Ctrl+G:
Sub copyData()
Dim r As Boolean
r = Application.ScreenUpdating = False
Debug.Print "'Application.ScreenUpdating' is set to " & r
r = Application.ScreenUpdating = True
Debug.Print "'Application.ScreenUpdating' is set to " & r
End Sub
I use Excel as part of Microsoft 365. I too fought with the screen flickering problem. Although my macro worked, the flickering was very annoying. I tried several approaches and stumbled upon this:
Minimize the second workbook before initiating the macro from the first workbook. For my situation, the screen no longer flickered. I also tried the following code to minimize the second workbook from within VBA. If the second workbook was already minimized, there was no effect. If the second workbook was not minimized, the screen flickered only once - to enable me to minimize the second workbook. Subsequent switching back and forth between workbooks did not introduce any screen flickering.
‘
Filename = "SecondWorkbookName.xlsx"
Windows(Filename).Activate
Application.WindowState = xlMinimized ' Minimize workbook to prevent flickering.
Application.ScreenUpdating = False
I'm having issues with a workbook not changing view to a newly unhidden/activated worksheet in-between toggling screen updating from off to on and back off again - it's not actually refreshing the screen. (code below)
I have module that calls forms and subs from a main sub to carry out a number of tasks - within each of the subs (except the main) I turn off screen updating in the beginning and turn it on at the end (example below). The workbook has a number of worksheets (mostly hidden) that are used for processing or as the final visible view - when opened, only one sheet is visible (used to launch the main sub).
While running, one of the subs unhides and activates the final worksheet, then deletes the starting worksheet - and toggles screen updating back on ("True"), and exits back to the main sub (which calls another sub again).
But it doesn't change view, the view stays on the deleted sheet while the subs all finish. (I can "trick" it into changing view to the newly active worksheet by inserting a "MsgBox" - but don't want to do that.)
This has been a hard one for me to search out answers (because looking up "Screenupdating" and anything else brings up a myriad of answers regarding "how to stop the screen from updating").
Sub createADS()
Dim oneForm As Object
Set MainWrkBk = ActiveWorkbook
cancel = False 'initialise
Call ADSheaderFormShow
Set MainWrkBk = ActiveWorkbook 're-Set MainWrkBk after doing "SaveAs" in previous form
Call ADSformGen
MainWrkBk.Worksheets("ADSform").Activate 'Doesn't change view
'MsgBox "Enter antenna information from RFDS"
'^^^ Tricks it into refreshing worksheet when active
Call ADSinputFormShow
Call ADSsetAntennas
Call ADSpullData
GoTo ExitHandler
ExitHandler:
For Each oneForm In UserForms
Unload oneForm
ThisWorkbook.Save
Next oneForm
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Private Sub ADSformGen()
Application.ScreenUpdating = False 'Returned to True after running sub
MainWrkBk.Worksheets("HidDbSh").Visible = True
MainWrkBk.Worksheets("HidDbSh").Cells(1, 1).Value = "Site Info"
MainWrkBk.Worksheets("HidSiteTemp").Range("a1").CurrentRegion.Copy _
Destination:=MainWrkBk.Worksheets("HidDbSh").Cells(2, 1)
Columns.AutoFit
Application.Calculation = xlCalculationAutomatic 'to reset all formula calcs before deleting source
MainWrkBk.Worksheets("HidDbSh").Visible = False
Application.DisplayAlerts = False
MainWrkBk.Worksheets("HidSiteTemp").Delete
Application.DisplayAlerts = True
MainWrkBk.Worksheets("HidADSform").Visible = True
MainWrkBk.Worksheets("HidADSform").Name = "ADSform"
With MainWrkBk.Worksheets("ADSform").UsedRange
.Copy
.PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
End With
Application.DisplayAlerts = False
MainWrkBk.Worksheets("BlankADSForm").Delete
Application.DisplayAlerts = True
MainWrkBk.Worksheets("ADSform").Activate
MainWrkBk.Worksheets("ADSform").Range("B2").Select
Application.ScreenUpdating = True
End Sub
If you want to ensure that the screen updates when you active the sheet, turn screen updating on before you active it. Otherwise, you risk the redraw event that the Activate call will generate getting swallowed:
'...
Application.ScreenUpdating = True
MainWrkBk.Worksheets("ADSform").Activate
MainWrkBk.Worksheets("ADSform").Range("B2").Select
End Sub
I'm using Application.Sheets("Sheet6").Delete to delete a sheet, and it causes a popup that asks if I'm sure. How do I automatically select delete?
Update your code to disable the display of alerts before you delete your sheet; Then enable the alerts after the delete code executes
Application.DisplayAlerts = False
Sheets("Sheet6").Delete
Application.DisplayAlerts = True
You can turn your display alerts off for Excel
Application.DisplayAlerts = False
Application.Sheets("Sheet6").Delete
Application.DisplayAlerts = True
Turn off the alerts before you do the delete. Then turn them back on like this:
Application.DisplayAlerts = False
Application.Sheets("Sheet6").Delete
Application.DisplayAlerts = True
I am trying to delete a worksheet when the user click's on an image (button) in Excel. However this makes excel crash and restart, forgetting any unsaved progress.
This is my sub:
Sub DeletePlan()
Application.Calculation = xlCalculationManual
Application.DisplayAlerts = False
Dim SheetNamesToCopy As String
SheetNamesToCopy = ActiveSheet.Name
' Check what addon sheets exists for the media, then add existing ones to string
If CheckSheet("periodeplan", True) = True Then
ThisWorkbook.SheetS(SheetNamesToCopy & " - periodeplan").Delete
End If
If CheckSheet("ukesplan", True) = True Then
ThisWorkbook.SheetS(SheetNamesToCopy & " - ukesplan").Delete
End If
If CheckSheet("Input", True) = True Then
ThisWorkbook.SheetS(SheetNamesToCopy & " - Input").Delete
End If
SheetS("Totalplan").Select
ThisWorkbook.SheetS(SheetNamesToCopy).Delete
Application.DisplayAlerts = True
Application.Calculation = xlCalculationAutomatic
End Sub
The application crashes most of the time. But not always... Any ideas what might be wrong?
(I have tested and confirmed that the delete function causes the crash, but its not always the same sheet).
Edit: This function is not deleting the last sheet in the workbook. There are 20 more sheets. Also i use Application.Calculation = xlCalculationAutomatic, because there are allot of formulas, and i do not want excel to calculate changes before all is connected sheets are deleted.
Any hint or answer is appreciated :)
The error occurs when the button that initiates the macro is located on one of the sheets that are to be deleted.
So the answer is: Do not create a button (or image linked to a macro) that deletes the sheet it is on.
If anybody can add to this answer with a reason for this error, please do so ;)
I just ran into this problem myself! I'm going to defer to more experienced designers on a way to refine this technique, but as a general concept, I do have a working solution:
If you allow the macro to run it's course and then delete the sheet, it doesn't crash. Something like this:
Sub Delete_This_Sheet()
Application.OnTime Now + TimeValue("00:00:02"), "Watergate"
Sheets("Sheet with a death sentence").Visible = False
End Sub
Sub Watergate() 'To make things go away
Application.DisplayAlerts = False
Sheets("Sheet with a death sentence").Delete
Application.DisplayAlerts = True
End Sub
Resurrecting this thread because I had the same issue and want to share the solution.
I had a very simple sub to delete worksheets:
Sub deletetraindoc()
Dim ws As Worksheet
Application.ScreenUpdating = False
For Each ws In ThisWorkbook.Sheets
'This if statement looks for any worksheet that contains the term "Form"
'Any worksheet that contains that string will be deleted
If InStr(ws.Name, "Form") > 0 Then
Application.DisplayAlerts = False 'Deactivates the standard deletion confirmation
ws.Activate
ws.Delete 'Deletes the worksheet
Application.DisplayAlerts = True 'Reactivates display alerts
End If
Next
Application.ScreenUpdating = True
End Sub
This inconsistently caused crashing until I added the line "ws.Activate" to activate each worksheet before deleting, which seems to have resolved the issue. I've run into this problem in many other situations performing actions on worksheets, but it usually would result in an object error instead of a complete crash.
I found that in Office 2013, you cannot place a button that overlaps a cell that that macro changes. Interesting enough, it doesn't occur if the change is numeric in nature, but if it is alphanumeric, it blows up excel when you attempt to delete that tab. Turns out, it blows it up when attempting to delete the tab manually (by mouse click) or by the macro attempting to do it. THUS, my lesson learned from this thread and applying it to my specific situation is to never place a development button over the cell it changes (in my case, it was simply a cell that gives the status of what that macro was doing). Excel 2013 does not like that situation while Excel 2010 simply didn't care.
I do believe you nare right and the only way around this is to ensure this macro is on the total plan sheet. Also you're doing a few unnecessary steps and the select a sheet should be to activate and select a cell.
Sub DeletePlan()
Application.Calculation = xlCalculationManual
Application.DisplayAlerts = False
Dim SheetNamesToCopy As String
SheetNamesToCopy = ActiveSheet.Name
'dont delete total plan
If sheetnames = "Totalplan" then exit sub
SheetS("Totalplan").Activate
Activesheet.Cells(1,1).select
'Turn off errors if sheet doesn't exist
On error resume next
ThisWorkbook.SheetS(SheetNamesToCopy & " - periodeplan").Delete
ThisWorkbook.SheetS(SheetNamesToCopy & " - ukesplan").Delete
ThisWorkbook.SheetS(SheetNamesToCopy & " - Input").Delete
ThisWorkbook.SheetS(SheetNamesToCopy).Delete
On error goto 0
Application.DisplayAlerts = True
Application.Calculation = xlCalculationAutomatic
End Sub
You can delete the active sheet from a button (or image) on the active sheet. You just have to work around it.
ActiveSheet.Move before:=Worksheets(1)
Worksheets(2).Activate
Worksheets(1).Delete
I had a similar, but not identical problem. I had a macro that deleted all the chart sheets with the following command, but although it operated correctly, Excel 2013 was doomed to fail as soon as I tried to save the file, and would "recover" by reverting to the previously saved situation, throwing away any subsequent work:
Oh, and it worked fine until I moved from, I think it was, Excel 2010 to 2013, changing to Windows 10 at the same time.
The command of doom was:
ThisWorkbook.Charts.Delete
Thanks to some inspiration from the answers above, I first inserted a save before the deletion action and then changed the delete as follows (it turned out the saves were not after all needed but I like to have them there, even if I comment them out):
Dim graphSheet As Chart
ActiveWorkbook.Save
For Each graphSheet in this Workbook.Charts
graphSheet.Delete
ActiveWorkbook.Save
Next graphSheet
I should also mention that there is a preceeding Application.DisplayAlerts = False before the for loop and of course the Application.DisplayAlerts = True after the Next... statement to cut out the unwanted
are you sure you want to do this type question?
Again, thanks to your contributors for the inspiration.
I wanted a button that would delete a sheet, as the workbook was protected and could 'export' results but couldn't delete unwanted results.
My simple workaround was to have the macro hide the sheet, but then to delete the last hidden sheet, so the files dont become huge with dozens of hidden sheets.
I created a range in a hidden sheet called "DeleteSheet", to store the name of the hidden sheet.
Sub Delete_Sheet()
ActiveWorkbook.Unprotect Password:="Patrick2017"
ActiveSheet.Unprotect Password:="Patrick2017"
On Error Resume Next
' (In event there is no hidden sheet or the sheet is already deleted, resume next)
'The below finds the name of the previously hidden sheet to delete, and stores it.
Dim DeleteSheet As String
DeleteSheet = Range("DeleteSheet")
'The below is to avoid the main sheet being deleted
If ActiveSheet.Name = "POAL Calculator" Then
Exit Sub
End If
' The below stores the current sheets name before hiding, for deleting next time the
' macro is run
Range("DeleteSheet") = ActiveSheet.Name
ActiveWindow.SelectedSheets.Visible = False
' The below deletes the sheet previously hidden
Application.DisplayAlerts = False
Sheets(DeleteSheet).Delete
ActiveWorkbook.Protect Password:="Patrick2017"
Application.DisplayAlerts = True
End Sub
How about moving the button code to a module?
I have had an issue with that in Excel 2016 whereby Option explicit didn't work if the code was in a module, but if the code is in a module, then you 'should' be able to delete the sheet where the button was.