Macro to improve Optimisation

howard

Well-known Member
Joined
Jun 26, 2006
Messages
6,603
Office Version
  1. 2021
Platform
  1. Windows
I have the following code that performs the calculations correctly. Each section starts where "PE" is in row A to first Non-Blank before "Total" for each section

Once the last Text "Total" is found in Col A then macro to end and no more calculations beyond this point. I also have text "Variance" in Col A so calculation not to go beyond this

It is extremely slow as lt appears to be continuing with the loop

It would be appreciated if someone could amend my code. It computes the formulas for each section 100%

Code:
 Private Sub ComboBox1_Change()
    Dim peRow As Long, totalRow As Long, endRow As Long
    Dim currentRow As Long, varianceRow As Long
    Dim foundPE As Range, foundTotal As Range, foundVariance As Range
    Dim ws As Worksheet
    Dim sheetName As String

    ' Disable events and screen updating for efficiency
    Application.EnableEvents = False
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    ' Set the active worksheet
    Set ws = ActiveSheet
    sheetName = ComboBox1.Value
    
    ' Find the last occurrence of "Variance" in column A to limit the range
    Set foundVariance = ws.Columns("A").Find(What:="Variance", LookAt:=xlWhole)
    If foundVariance Is Nothing Then GoTo Cleanup
    varianceRow = foundVariance.Row
    
    ' Start the search for "PE" from row 1
    currentRow = 1
    
    ' Loop through column A to find sections starting with "PE", but stop at "Variance"
    Do While currentRow < varianceRow
        ' Find the next "PE" in column A
        Set foundPE = ws.Columns("A").Find(What:="PE", After:=ws.Cells(currentRow, "A"), LookAt:=xlWhole)
        
        If foundPE Is Nothing Then Exit Do
        peRow = foundPE.Row
        
        ' Find the next "Total" after "PE"
        Set foundTotal = ws.Columns("A").Find(What:="Total", After:=ws.Cells(peRow, "A"), LookAt:=xlWhole)
        If foundTotal Is Nothing Or foundTotal.Row >= varianceRow Then Exit Do
        totalRow = foundTotal.Row
        
        ' Find the first non-blank row above "Total"
        endRow = totalRow - 1
        Do While ws.Cells(endRow, "A").Value = "" And endRow > peRow
            endRow = endRow - 1
        Loop
        
        ' Set formulas directly for the range
        For i = peRow To endRow
            ws.Cells(i, 2).Formula = "=SUM(Oct:" & sheetName & "!B" & i & ")"
            ws.Cells(i, 3).Formula = "=SUM(Oct:" & sheetName & "!C" & i & ")"
        Next i
        
        ' Move to the next section after "Total"
        currentRow = totalRow + 1
    Loop

Cleanup:
    ' Re-enable events and screen updating
    Application.EnableEvents = True
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
End Sub
 

Excel Facts

Remove leading & trailing spaces
Save as CSV to remove all leading and trailing spaces. It is faster than using TRIM().
The logic you need is effectively the same as you use when you use the Range.FindNext method.
A Find which does not involve using Replace eventually loops back on to itself, so you need to capture the first Find and exit the loop when the code loops back to that address.

See if this helps:
VBA Code:
Private Sub ComboBox1_Change()

    Dim peRow As Long, totalRow As Long, endRow As Long
    Dim currentRow As Long, varianceRow As Long
    Dim foundPE As Range, foundTotal As Range, foundVariance As Range
    Dim PEAddressFirst As String
    Dim ws As Worksheet
    Dim sheetName As String
    Dim i As Long

    ' Disable events and screen updating for efficiency
    Application.EnableEvents = False
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    ' Set the active worksheet
    Set ws = ActiveSheet
    sheetName = ComboBox1.Value
   
    ' Find the last occurrence of "Variance" in column A to limit the range
    Set foundVariance = ws.Columns("A").Find(What:="Variance", LookAt:=xlWhole)
    If foundVariance Is Nothing Then GoTo Cleanup
    varianceRow = foundVariance.Row
   
    ' Start the search for "PE" from row 1
    currentRow = 1
    
    Set foundPE = ws.Columns("A").Find(What:="PE", After:=ws.Cells(currentRow, "A"), LookAt:=xlWhole)
    If Not foundPE Is Nothing Then
        PEAddressFirst = foundPE.Address
        peRow = foundPE.Row
   
        ' Loop through column A to find sections starting with "PE", but stop at "Variance"
        Do           
            ' Find the next "Total" after "PE"
            Set foundTotal = ws.Columns("A").Find(What:="Total", After:=ws.Cells(peRow, "A"), LookAt:=xlWhole)
            If foundTotal Is Nothing Or foundTotal.Row >= varianceRow Then Exit Do
            totalRow = foundTotal.Row
           
            ' Find the first non-blank row above "Total"
            endRow = totalRow - 1
            Do While ws.Cells(endRow, "A").Value = "" And endRow > peRow
                endRow = endRow - 1
            Loop
           
            ' Set formulas directly for the range
            For i = peRow To endRow
                ws.Cells(i, 2).Formula = "=SUM(Oct:" & sheetName & "!B" & i & ")"
                ws.Cells(i, 3).Formula = "=SUM(Oct:" & sheetName & "!C" & i & ")"
            Next i
           
            ' Move to the next section after "Total"
            currentRow = totalRow + 1
           
            ' Find the next "PE" in column A
            Set foundPE = ws.Columns("A").Find(What:="PE", After:=ws.Cells(currentRow, "A"), LookAt:=xlWhole)
            peRow = foundPE.Row
        Loop While currentRow < varianceRow And foundPE.Address <> PEAddressFirst
   
    End If

Cleanup:
    ' Re-enable events and screen updating
    Application.EnableEvents = True
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
End Sub
 
Upvote 0
Solution
Many thanks for your explanation and revised code Alex

It works 100% and super fast
 
Upvote 0

Forum statistics

Threads
1,224,798
Messages
6,181,038
Members
453,013
Latest member
Shubashish_Nandy

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top