I have written a VBA code that copies data from source sheets into destination sheets. The destination sheets are formatted as a table so that formulas can be calculated automatically to update a pivot graph.
I need to run the code daily. It works fine but a takes about 2 hours to run, some sheets have about 50,000 rows and about 3000 rows are added daily. My question is, is there a stack exchange site where I can find someone knowledgeable in VBA to review my code to make is run faster/more efficient? I've looked into ways of making VBA more efficient, but I'm not very familiar with it. Maybe I'm missing something.
EDIT: The code copies data from four different workbooks (each workbook has one sheet), into four different workbooks (three of the workbooks have one sheet, and one of the workbooks has two sheets). From each source sheet, it copies data starting from cell A9, selecting all cells with data below it and to its right (about 5 columns and 2000 - 6000 rows).
I've added the following to my code to make it run a bit faster but the I want to find other ways to make it run much faster:
Sub Auto_Open()
'Message box before running script
CarryOn = MsgBox("Do you want to update data?", vbYesNo, "Daily Traffic Report")
If CarryOn = vbYes Then
'Minimize workbook
ActiveWindow.WindowState = xlMinimized
'Switch to manual calculation of formulae
Application.Calculation = xlManual
ActiveWorkbook.PrecisionAsDisplayed = False
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
Dim x, y, o, p, u, j, k, s As Workbook
Dim win As Window
Dim LastRow As Long
Dim oFS As Object
Dim StrFile As String
Dim rot_cnt As Integer
rot_cnt = 1
Dim current As Date
Dim newest As Date
Dim right_file As String
Dim my_path As String
Dim file_name As String
'Source Files location
my_path = "C:\Users\xxxxx"
'Open latest source files
file_name = "filename*.xlsx"
StrFile = Dir(my_path & file_name)
Do While Len(StrFile) > 0
Set oFS = CreateObject("Scripting.FileSystemObject")
If rot_cnt = 1 Then
newest = oFS.GetFile(my_path & StrFile).DateCreated
End If
If rot_cnt >= 1 Then
current = oFS.GetFile(my_path & StrFile).DateCreated
End If
If DateSerial(Year(current), Month(current), Day(current)) >= _
DateSerial(Year(newest), Month(newest), Day(newest)) _
And Right(StrFile, 6) <> "*.xlsm" Then
newest = oFS.GetFile(my_path & StrFile).DateCreated
right_file = my_path & StrFile
End If
StrFile = Dir
Set oFS = Nothing
rot_cnt = rot_cnt + 1
Loop
Set x = Workbooks.Open(right_file)
file_name1 = "file_name1*.xlsx"
StrFile = Dir(my_path & file_name1)
Do While Len(StrFile) > 0
Set oFS = CreateObject("Scripting.FileSystemObject")
If rot_cnt = 1 Then
newest = oFS.GetFile(my_path & StrFile).DateCreated
End If
If rot_cnt >= 1 Then
current = oFS.GetFile(my_path & StrFile).DateCreated
End If
If DateSerial(Year(current), Month(current), Day(current)) >= _
DateSerial(Year(newest), Month(newest), Day(newest)) _
And Right(StrFile, 6) <> "*.xlsm" Then
newest = oFS.GetFile(my_path & StrFile).DateCreated
right_file = my_path & StrFile
End If
StrFile = Dir
Set oFS = Nothing
rot_cnt = rot_cnt + 1
Loop
Set o = Workbooks.Open(right_file)
file_name2 = "file_name2*.xlsx"
StrFile = Dir(my_path & file_name2)
Do While Len(StrFile) > 0
Set oFS = CreateObject("Scripting.FileSystemObject")
If rot_cnt = 1 Then
newest = oFS.GetFile(my_path & StrFile).DateCreated
End If
If rot_cnt >= 1 Then
current = oFS.GetFile(my_path & StrFile).DateCreated
End If
If DateSerial(Year(current), Month(current), Day(current)) >= _
DateSerial(Year(newest), Month(newest), Day(newest)) _
And Right(StrFile, 6) <> "*.xlsm" Then
newest = oFS.GetFile(my_path & StrFile).DateCreated
right_file = my_path & StrFile
End If
StrFile = Dir
Set oFS = Nothing
rot_cnt = rot_cnt + 1
Loop
Set p = Workbooks.Open(right_file)
file_name3 = "file_name3*.xlsx"
StrFile = Dir(my_path & file_name3)
Do While Len(StrFile) > 0
Set oFS = CreateObject("Scripting.FileSystemObject")
If rot_cnt = 1 Then
newest = oFS.GetFile(my_path & StrFile).DateCreated
End If
If rot_cnt >= 1 Then
current = oFS.GetFile(my_path & StrFile).DateCreated
End If
If DateSerial(Year(current), Month(current), Day(current)) >= _
DateSerial(Year(newest), Month(newest), Day(newest)) _
And Right(StrFile, 6) <> "*.xlsm" Then
newest = oFS.GetFile(my_path & StrFile).DateCreated
right_file = my_path & StrFile
End If
StrFile = Dir
Set oFS = Nothing
rot_cnt = rot_cnt + 1
Loop
Set j = Workbooks.Open(right_file)
'Open destination files
Set y = Workbooks.Open(ThisWorkbook.Path & "\f1.xlsx")
Set u = Workbooks.Open(ThisWorkbook.Path & "\f2.xlsx")
Set k = Workbooks.Open(ThisWorkbook.Path & "\f3.xlsx")
Set s = Workbooks.Open(ThisWorkbook.Path & "\f4.xlsx")
'Wait for 03s
Application.Wait (Now + TimeValue("0:00:03"))
'Minimize all excel files
For Each win In Windows
If win.Visible Then win.WindowState = xlMinimized
Next win
'Wait for 03s
Application.Wait (Now + TimeValue("0:00:03"))
'Copy data from source files into destination files
'2G Voice
x.Sheets("Sheet1").Range(x.Sheets("Sheet1").Range("A9"), x.Sheets("Sheet1").Range("A9").End(xlDown).End(xlToRight)).Copy
y.Sheets("xxxxx").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial
'2G Data
o.Sheets("Sheet1").Range(o.Sheets("Sheet1").Range("A9"), o.Sheets("Sheet1").Range("A9").End(xlDown).End(xlToRight)).Copy
y.Sheets("xxxxxx").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial
'3G Voice and Data
p.Sheets("Sheet1").Range(p.Sheets("Sheet1").Range("A9"), p.Sheets("Sheet1").Range("A9").End(xlDown).End(xlToRight)).Copy
u.Sheets("xxxx").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial
'4G Data
j.Sheets("Sheet1").Range(j.Sheets("Sheet1").Range("A9"), j.Sheets("Sheet1").Range("A9").End(xlDown).End(xlToRight)).Copy
k.Sheets("xxxxx").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial
'Total Traffic
x.Sheets("Sheet1").Range(x.Sheets("Sheet1").Range("A9"), x.Sheets("Sheet1").Range("A9").End(xlDown).End(xlToRight)).Copy
s.Sheets("xxxxxx").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial
'Disable alerts before closing/saving workbooks
Application.DisplayAlerts = False
x.Close
o.Close
p.Close
j.Close
'Save destination files
y.Save
u.Save
k.Save
s.Save
'Close destination files
y.Close
u.Close
k.Close
s.Close
'Refresh and Save current workbook
ThisWorkbook.RefreshAll
ThisWorkbook.Save
'Disable display alerts
Application.DisplayAlerts = True
'Switch to automatic calculation of formulae
Application.Calculation = xlAutomatic
ActiveWorkbook.PrecisionAsDisplayed = True
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
SendMail = MsgBox("Report complete. Send as attachement?", vbYesNo)
If SendMail = vbYes Then
'Mail last saved version of report
Call Mail_workbook_Outlook
Else
MsgBox ("Report Complete")
End If
End If
End Sub
FileSystemObject
at the top of every single loop. You only need to create that object once, at the top of your code and then reuse it for the rest of the routine. You'll likely see a performance increase just by doing this alone. \$\endgroup\$