Excel freezes when running macro on large files (hiding bold rows and transposing to new sheet) - hide

I am wondering if anyone can help me with this macro. It works on smaller files, but on bigger files, Excel goes to not responding mode. I am not even sure if it is actually running in the background or really not responding. Maybe it can be streamlined more?
Basically I have a workbook with many many sheets (over 1000 sheets) where only column A is populated, and I wanted to hide the non-bold rows, and transpose the visible bold rows of each sheet into a new row one after another, into a new sheet call 'Table of Contents'.
Also, I am not sure if 'UsedRange' to hide bold rows would be okay to use here, there's less than 50 rows, but when the macro runs, it looks like it's trying to hide way pass that, maybe because there are some blank rows.
I want Application.ScreenUpdating to be true because I would like to see that it is doing the job.
I am fairly new to vba so I would really appreciate if someone can help me with this!
Thank you so much!!!
Below is the code:
Sub AW_CopyTransposeBoldText()
Dim sFname As Variant Dim i As Long
'OPENS DIALOG WINDOW sFname = Application.GetOpenFilename(FileFilter:="Microsoft Excel Workbooks (.xls;.xlsx;.xlsm),.xls;.xlsx;.xlsm", Title:="SELECT YOUR FILES =)", MultiSelect:=True)
If IsArray(sFname) Then
For i = LBound(sFname) To UBound(sFname)
Workbooks.Open Filename:=sFname(i)
Next i
Else: MsgBox "No files selected!", vbExclamation, "Sorry!"
End If
Dim c As Range Dim ws As Worksheet, wb As Workbook
For Each wb In Workbooks 'LOOPS THROUGH ALL OPEN WORKBOOKS wb.Activate
ActiveWorkbook.Sheets.Add(Before:=Worksheets(1)).Name = "Table of Contents" 'ADD WORKSHEET AND HEADERS
Cells(1, 1) = "Page Number"
Cells(1, 2) = "Address 1"
Cells(1, 3) = "Address 2"
Cells(1, 4) = "Address 3"
For i = 2 To Sheets.Count 'LOOPS THROUGH ALL WORKSHEETS 1 TO LAST SHEET
Worksheets(i).Activate
Application.ScreenUpdating = True
For Each ws In Worksheets 'LOOPS THROUGH ALL WORKSHEETS AGAIN?
ActiveSheet.DisplayPageBreaks = False
For r = 1 To ActiveSheet.UsedRange.Rows.Count
Cells(r, 1).EntireRow.Hidden = Cells(r, 1).Font.Bold = False
Next r
Next ws
Range("A1:IV" & Range("A65536").End(xlUp).Row).SpecialCells(xlCellTypeVisible).Copy
'Change number to the destination sheet number you want to import to (starts with 1)
ActiveWorkbook.Worksheets("Table of Contents").Activate
'Do not change the following column. It's not the same column as above
Range("B" & Rows.Count).End(xlUp).Offset(1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=True, Transpose:=True
Application.CutCopyMode = False
Next i 'NEXT WORKSHEET LOOP
Next wb 'NEXT WORKBOOK LOOP
MsgBox "DONE!!"
End Sub

You could try the following method to increase the performance of your VBA.
Solution:-
Task 1: Increase your virtual memory
Open the control panel > on the right hand top corner >Select view by "small icons"
Select System> Advanced System Settings> Under Advanced> Performance> click Settings
Click Advanced > Virtual memory> Change
Uncheck the "Automatically manage paging file size for all drives"
Click on C drive> Click custom size > Set Initial size as your RAM size Ex: If you have 6 Gig of RAM then it will be 1024*6=6144
On the Maximum Size> Double your RAM Size. In this case it will be 12288 . See below screen shot
7.Click "Set" Button > Click > OK. Then Reboot your machine to see the changes
Task 2: Changing your Excel Settings
Click File > Options> Advanced> Under Editing options> Uncheck the "Allow editing directly in cells" and "Automatically Flash Fill"
Click File > Options> Advanced> Under Display options > Click Disable Hardware graphics acceleration
This will increase almost 67 % of improvements in Excel
Tip: Always use Paste special values when you paste something on Excel

Related

VBA transferring data between workbooks error due to space in sheet name

I've been working on this VBA code:
(Step 1) select a particular workbook (e.g. Workbook2)
(Step 2) it auto copies a range of data from a sheet (Raw Data) in Workbook2
(Step 3) it auto pastes the data into Workbook1 under the sheet "Accounting Data".
The sheet I want copied has the same name in all the selected workbooks (whether its Workbook2,3,4 etc.) its always named "Raw Data".
Everything works beautifully except that the code will not run if the sheet is named "Raw Data". It only works without a space "RawData". I can't seem to figure it out. Help would be appreciated.
Thanks.
Sub Get_Data_From_File()
Dim FileToOpen As Variant
Dim OpenBook As Workbook
Application.ScreenUpdating = False
FileToOpen = Application.GetOpenFilename(Title:="Browse for your File & Import Range", FileFilter:="Excel Files (*.xls*),*xls*")
If FileToOpen <> False Then
Set OpenBook = Application.Workbooks.Open(FileToOpen)
OpenBook.Worksheets("Raw Data").Range("A1:E20").Copy
ThisWorkbook.Worksheets("Accounting Reports").Range("A10").PasteSpecial xlPasteValues
OpenBook.Close False
End If
Application.ScreenUpdating = True
End Sub
Too long for a comment...
It's possible your "Raw Data" sheet doesn't have a space in its name but something else which maybe looks like a space.
Try running this with the workbook open and that sheet active:
Dim i As Long, s As String
s = Activesheet.Name
For i = 1 to Len(s)
Debug.Print Mid(s,i,1), Asc(Mid(s,i,1))
Next i
Does the "space" character show up as 32, or some other code? At a guess it might be 160 (non-breaking space).

Loop through a workbook daily and copy sheets to another workbook based on tab name

I have a workbook that I run daily and this creates multiple tabs called system 1, system 2, system 3 etc.. I then manually copy each tab to a file called the same as the tab name ie system 1.xlxs after the data from previous days .. the source data starts in Cell B2 and goes to Column J and could be any length the destination data starts in Column F to N.
The destination files are stored in folders called Month & Year ie Z:/Results/June 20/
I worked out how to update the tabs by looping but just can't get my head around opening the files and copying the data at the bottom
Public Ws As Worksheet
Sub Loop_Thru_shts()
Application.ScreenUpdating = False
For Each Ws In ActiveWorkbook.Worksheets
Ws.Activate
If ActiveSheet.Name = "Macro" Or ActiveSheet.Name = "RC Common" Or ActiveSheet.Name = "RC Data" Then
'nothing
Else
On Error Resume Next
ActiveSheet.ShowAllData
ActiveSheet.Range("$A$1:$J$1500").AutoFilter Field:=1, Criteria1:="Y"
End If
Next Ws
Application.ScreenUpdating = True
Worksheets("RC Data").Activate
End Sub
Thanks in advance for any help

excel vba hardening a fragile function

I've created a spreadsheet for tracking student data for my wife. There are 2 versions, the master and the teacher version. The only difference is that the teacher version has a couple of tabs and buttons hidden.
At the end of every day she gathers the teacher versions and merges their data into the master version using a macro attached to a button. On a regular basis it causes Excel to crash. It seems like trying to merge a workbook that is on a usb stick is a surefire way to make it crash, but there are other circumstances that I haven't identified yet.
She isn't technical enough to step through the code until it blows and I can't be there when she is doing it.
Previous attempts to harden the code involved getting rid of any instance of Activesheet or Activeworkbook, and always using a direct reference to the worksheet (ie Sheet1, but renamed to something meaningful - "merge" in the example below).
The function below, LoadTeacherData, is called once for each workbook to merge. All it does is copy the existing records on the teacher's data tab, copy them to the master merge tab and then delete them from the source. When it crashes it is immediately after selecting the file to load, I think.
Sub LoadTeacherData()
Dim wb_td As Workbook
Dim td As Worksheet
Dim newdata As Range
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Filters.Clear
.Filters.Add "Excel files", "*.xlsm"
If .Show = -1 Then
file_name = .SelectedItems(1)
Else
Exit Sub
End If
End With
Application.ScreenUpdating = False
Set wb_td = Workbooks.Open(Filename:=file_name, UpdateLinks:=False, ReadOnly:=False)
If wb_td Is Nothing Then
MsgBox "Unable to open file, check path", vbOKOnly
Exit Sub
End If
file_name = wb_td.Name
Set td = wb_td.Worksheets("data")
row = LastRow(td, "C")
col = LastCol(td, 1)
Set newdata = td.Range("a2", td.Cells(row, col))
newdata.Copy Destination:=Merge.Cells(LastRow(Merge, "C") + 1, 1)
newdata.Clear
MsgBox (row - 1 & " records merged")
wb_td.Close
ThisWorkbook.Activate
ThisWorkbook.Save
Application.ScreenUpdating = True
End Sub
Function LastRow(ByRef ws As Worksheet, ByVal colname As String)
LastRow = ws.Range(colname & ws.Rows.Count).End(xlUp).row
End Function
Function LastCol(ByRef ws As Worksheet, ByVal rownum As Long)
LastCol = ws.Cells(rownum, ws.Columns.Count).End(xlToLeft).Column
End Function
My suspicion is that it has something to do with permissions when opening the file. Her excel version is configured so that she has to enable content every time when opening a file.
You may be dealing with a corrupted file. Look at the workbooks.open method. There are a few options under corruptload that may help. Try this one and experiment to see if any of the others work better in your situation.
Set wb_td = Workbooks.Open(Filename:=file_name, UpdateLinks:=False, ReadOnly:=False, corruptload:=xlRepairFile)

Print Preview issues after running large amount of VBA

I have an Excel workbook in which almost everything is automated. It opens other workbooks, copies data from them, closes them and then loops through the data several times to generate reports that we print and use. Almost every time after running all the VBA and then trying to print, print preview gets stuck either finding the printer or loading page sizes as seen in the picture. Closing Excel and reopening the document restores print preview to normal functionality. The only thing related to printing that the VBA does is change the print area. I have not had this issue with any other documents that run VBA. Is this just a bug or possibly something in the code?
This is the code that causes print preview to fail to load in some way. If I skip this section then it works as intended... I would like to have this code function in some way as it's still needed.
Set wb1 = Workbooks.Open(FileName)
Set wb2 = ThisWorkbook
For i = LBound(sArray) To UBound(sArray) 'Loops through array, copies available data from last report
ShtName = sArray(i, 0)
On Error Resume Next
wb1.Sheets(ShtName).Activate
If Err.Number = 0 Then
wb1.Sheets(ShtName).Activate
Columns("A:U").Copy
wb2.Sheets(ShtName).Activate
Columns("BE:BV").Select
Selection.PasteSpecial xlPasteValues
Application.CutCopyMode = False
lastrow = Cells(Rows.Count, "BE").End(xlUp).Row
Range("BA2:BC2").Select
Selection.AutoFill Destination:=Range(Cells(2, "BA"), Cells(lastrow, "BC")), Type:=xlFillDefault
End If
On Error GoTo 0
DoEvents
Next i
wb1.Close False
Sheet2.Activate
I've tried commenting out "On Error Resume Next", "On Error Goto 0", "If...", "End If", and "DoEvents". Print Preview still fails with those removed and just doing the copy and paste from the previous sheet.
It seems that removing all instances of DoEvents has fixed the issue...
Print Preview works correctly and Excel does not crash when exiting the workbook anymore.
I believe you're looking for some type of refresh action that can re-sync the preview display with the data on the sheet. You might want to try this at the end:
ActiveSheet.EnableCalculation = False
ActiveSheet.EnableCalculation = True
If that doesn't work, see if manually saving fixes the issue. You can try calling Application.Save at the end.
"Print preview occurs automatically when you choose File --> Print. Another option is to use the Page Layout view (the icon on the right side of the status bar). To get the old-style print preview, you need to use VBA. The following statement displays a print preview of the active sheet: ActiveSheet.PrintPreview "
Quoted from Microsoft Excel 2013 Power Programming with VBA by John Walkenbach, pages 956-957.
That being said, I tested your issue above by recording a relatively complex macro that creates a new sheet, performs 25 automatic actions, and shows a print preview, then closes the print preview when I click OK on a MsgBox. I iterated the program to do this 1000 times. I never had an issue with the PrintPreview.
Its kind of a shot in the dark, but I tried cleaning up your code a little bit. See if that has any affect at all.
Sub Test()
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim isWS As Boolean
On Error GoTo sub_err
Set wb1 = Workbooks.Open(Filename)
Set wb2 = ThisWorkbook
For i = LBound(sArray) To UBound(sArray) 'Loops through array, copies available data from last report
ShtName = sArray(i, 0)
isWS = True
Set ws1 = wb1.Sheets(ShtName)
If isWS Then
Set ws2 = wb2.Sheets(ShtName)
ws1.Columns("A:U").Copy
ws2.Columns("BE:BV").PasteSpecial xlPasteValues
Application.CutCopyMode = False
lastrow = ws2.Cells(ws2.Rows.Count, "BE").End(xlUp).Row
ws2.Range("BA2:BC2").AutoFill Destination:=ws2.Range(ws2.Cells(2, "BA"), ws2.Cells(lastrow, "BC")), Type:=xlFillDefault
End If
DoEvents
Next i
wb1.Close False
ws2.Activate
sub_exit:
Exit Sub
sub_err:
If Err.Number = 9 Then
isWS = False
Resume Next
Else
MsgBox "Error: " & Err.Number & vbNewLine & Err.Description
Resume sub_exit
End If
End Sub
The big thing I did was split off your error handling, this way it only resumes next when you don't find the sheet in wb1 and all other errors (none error 9 errors) will still show your error message.
I also made sure all your Range(), Cells(), and Columns() were referencing the correct sheet (just incase excel is getting confused) and I assumed the active sheet was the correct sheet, but you may want to verify this in the code to make sure it's doing the correct thing in the correct sheet.
Now the copy code only runs if isWS = true, and it will always be true unless an error 9 code is thrown. The only thing I didn't know was if wb2 would always have a sheet name equal to ShtName but I'm guessing it will since it's inside your if err.number = 0
I'm not sure if this will change anything for you, but I'd be curious to hear your results other way.

Problems activating worksheet in excel 2013

My macro's were working perfect in excel 2010, but in 2013 I have a major problem with activating workbook in vba and than when certain sheet is selected + cell is selected I can fill in data, but when pressing enter or arrow key, the data is set to the first visible page of my file.
This happens when I activate another workbook, but also in the same workbook when I select a certain sheet, the data entered will go to the first sheet... what has changed from excel 2010 to 2013 that makes this happen??
this is the code I use:
Workbooks(MachineInspectieLijst & ".xlsm").Activate
Workbooks(MachineInspectieLijst & ".xlsm").Worksheets(MachineInspectieLijst).Range("V5").Select
When I fill in a value in V5 and enter, the value disappears and shows up on V5 in first page...mostly.
When I manually switch between the pages or workbooks, than it works... I founnd nowhere an answer.
hope somebody has the answer.
Do the process sequentially:
Sub hfjsdfh()
Workbooks(MachineInspectieLijst & ".xlsm").Activate
Worksheets(MachineInspectieLijst).Select
Range("V5").Select
End Sub
This is the actual sub, I tried your suggestion, but exactly the same...Indeed, it is like the second workbook is not really activated, but how to solve? has it to do with the userform who stays loaded? this one must stay loaded, as it contains lot of necessary information and is only unloaded at new start. Nevertheless, I tried to unload as test, but same problem. Can it be due to excel itself?
Private Sub CmdGetInspectionList_Click()
Dim thesentence As String
Dim WB As Workbook
Set WB = ThisWorkbook
Dim WB2 As Workbook
frmKlantSelectie.Hide
Application.EnableEvents = False
If Me.cboDocumentType.Value = "Sales Budget Quotation" Then
MachineInspectieLijst = "Machines_Sales"
WB.Worksheets("PreInspArticles").Range("J1") = "Sales"
Else
MachineInspectieLijst = Me.cboInspectieMachine.Value
End If
loginnaam = StrConv(WindowsUserName, vbUpperCase)
thesentence = "C:\Users\" & loginnaam & "\Dropbox\2_Doc_Service\DATA\Pre_Inspection_Checklist\" & MachineInspectieLijst & ".xlsm"
'checken ofdat de file wel bestaat in de directory
If Dir(thesentence) <> "" Then
MsgBox "Machine Check list exists! Press 'OK' and file will be shown!"
'Test to see if the file is open.
If IsFileOpen(thesentence) Then
Workbooks(MachineInspectieLijst & ".xlsm").Activate
Else
'Display a message stating the file is not in use.
Set WB2 = Workbooks.Open(thesentence)
End If
Else
MsgBox "No machine selected Or Check list not yet existing."
frmKlantSelectie.Show
Me.TxtInspectionList.SetFocus
Exit Sub
End If
WB2.Worksheets(1).Range("V5").Select
Application.EnableEvents = True
End Sub

Resources