I have created a simple vba macro to iterate over 2 tabs in excel. Each tab will always be the same length. Currently, each tab is about 155,000 rows. I do not expect the tabs to ever be above 200,000 rows.
In the code below, the max number for any of the x's is 3,000. (200,000 * 3,000) = 600,000,000, which I believe a variant can handle.
The issue is that when I run the macro excel freezes. I assumed this was not too many rows for excel to handle, but maybe that is not true. When I reduce the number of rows, the macro completes as expected.
Is there a better solution for this code?
I am using 64-bit excel 2016 on a 64-bit machine.
FYI: I added the ROUND function because I thought all the extra decimals may have been causing the freeze.
Sub index_check()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.StatusBar = "Calculating indices"
Dim lastrow_Sheet1 As Double, lastrow_Sheet2 As Double
Dim deriv As String
Dim x1_indexcounter As Variant, x2_indexcounter As Variant, x3_indexcounter As Variant, x4_indexcounter As Variant, x5_indexcounter As Variant
Dim x1_derivcounter As Double, x2_derivcounter As Double, x3_derivcounter As Double, x4_derivcounter As Double, x5_derivcounter As Double
Dim rng_lostpolicies As Range, rng_foundindicies As Range, rng_mktData As Range
Dim mktData() As Double
Start = Now()
lastrow_Sheet1 = ThisWorkbook.Sheets("Sheet1").Range("A:A").Find("*", , , , , xlPrevious).Row
lastrow_Sheet2 = ThisWorkbook.Sheets("Sheet2").Range("A:A").Find("*", , , , , xlPrevious).Row
Set rng_lostpolicies = Application.Range("rng_lostpolicies")
Set rng_foundindicies = Application.Range("rng_foundindicies")
Set rng_mktData = Application.Range("rng_mktData")
ReDim mktData(rng_mktData.Cells.Count)
x1_indexcounter = 0
x2_indexcounter = 0
x3_indexcounter = 0
x4_indexcounter = 0
x5_indexcounter = 0
x1_derivcounter = 0
x2_derivcounter = 0
x3_derivcounter = 0
x4_derivcounter = 0
x5_derivcounter = 0
foundflag = "False"
m = 0
f = 0
For i = 1 To lastrow_Sheet1 - 1
deriv = Trim(ThisWorkbook.Sheets("Sheet1").Cells(i + 1, 1).Value)
For j = 1 To lastrow_Sheet2 - 1
If deriv = Trim(ThisWorkbook.Sheets("Sheet2").Cells(j + 1, 3)) Then
If Trim(ThisWorkbook.Sheets("Sheet2").Cells(j + 1, 12)) = "x1" Then
x1_indexcounter = Round(x1_indexcounter + ThisWorkbook.Sheets("Sheet1").Cells(i + 1, 2), 4)
x1_derivcounter = x1_derivcounter + 1
ElseIf Trim(ThisWorkbook.Sheets("Sheet2").Cells(j + 1, 12)) = "x2" Then
x2_indexcounter = Round(x2_indexcounter + ThisWorkbook.Sheets("Sheet1").Cells(i + 1, 2), 4)
x2_derivcounter = x2_derivcounter + 1
ElseIf Trim(ThisWorkbook.Sheets("Sheet2").Cells(j + 1, 12)) = "x3" Then
x3_indexcounter = Round(x3_indexcounter + ThisWorkbook.Sheets("Sheet1").Cells(i + 1, 2), 4)
x3_derivcounter = x3_derivcounter + 1
ElseIf Trim(ThisWorkbook.Sheets("Sheet2").Cells(j + 1, 12)) = "x4" Then
x4_indexcounter = Round(x4_indexcounter + ThisWorkbook.Sheets("Sheet1").Cells(i + 1, 2), 4)
x4_derivcounter = x4_derivcounter + 1
ElseIf Trim(ThisWorkbook.Sheets("Sheet2").Cells(j + 1, 12)) = "x5" Then
x5_indexcounter = Round(x5_indexcounter + ThisWorkbook.Sheets("Sheet1").Cells(i + 1, 2), 4)
x5_derivcounter = x5_derivcounter + 1
Else
MsgBox "There is a new index for derivative id " & deriv
f = f + 1
If f > 10000 Then ' 10000 is an arbitrary number.
MsgBox "There are more than 10000 policies with a new index. Fix macro and rerun. Exiting macro."
Exit Sub
Else
rng_foundindicies.Offset(f, 0) = deriv
End If
End If
foundflag = "True"
Exit For
End If
Next j
If foundflag = "False" Then
MsgBox "Could not find Derivative " & deriv & " in Sheet2 file, but it is in Sheet1 file."
m = m + 1
rng_lostpolicies.Offset(m, 0) = deriv
End If
Next i
mktData(1) = check(x1_indexcounter, x1_derivcounter)
mktData(2) = check(x4_indexcounter, x4_derivcounter)
mktData(3) = check(x2_indexcounter, x2_derivcounter)
mktData(4) = check(x3_indexcounter, x3_derivcounter)
mktData(5) = check(x5_indexcounter, x5_derivcounter)
For i = 1 To UBound(mktData)
rng_mktData.Cells(1, i).Offset(1, 0).Value = mktData(i)
Next i
MsgBox ("This check took " & Format(Now() - Start, "hh:mm:ss"))
Application.StatusBar = "Done"
End Sub
Public Function check(number1, number2)
If number2 = 0 Then
check = 0
Else
check = number1 / number2
End If
End Function