Home > OS >  Optimisation Required Please - Absolute Beginner
Optimisation Required Please - Absolute Beginner

Time:03-31

I've just started learning VBA/macros today. I've got a macro that works, it's just unusuably slow. Does anyone have any good ideas of how to speed it up/replace it with something better?

Essentially, I have up to 20 potential different end dates, and I want to self-populate a sequential list of dates from a set start date, to the latest end date. Hopefully I've made some sense, and the code below fills in any gaps.

Sub DateAutoFill()
    Dim StartD As Date, EndD As Date
    StartD = Worksheets("Calculator").Range("B55")
    If IsDate(Worksheets("Calculator").Range("AN60")) Then
        EndD = Worksheets("Calculator").Range("AN60")
    Else
        If IsDate(Worksheets("Calculator").Range("AL60")) Then
            EndD = Worksheets("Calculator").Range("AL60")
        Else
            If IsDate(Worksheets("Calculator").Range("AJ60")) Then
                EndD = Worksheets("Calculator").Range("AJ60")
            Else
                If IsDate(Worksheets("Calculator").Range("AH60")) Then
                    EndD = Worksheets("Calculator").Range("AH60")
                Else
                    If IsDate(Worksheets("Calculator").Range("AF60")) Then
                        EndD = Worksheets("Calculator").Range("AF60")
                    Else
                        If IsDate(Worksheets("Calculator").Range("AD60")) Then
                            EndD = Worksheets("Calculator").Range("AD60")
                        Else
                            If IsDate(Worksheets("Calculator").Range("AB60")) Then
                                EndD = Worksheets("Calculator").Range("AB60")
                            Else
                                If IsDate(Worksheets("Calculator").Range("Z60")) Then
                                    EndD = Worksheets("Calculator").Range("Z60")
                                Else
                                    If IsDate(Worksheets("Calculator").Range("X60")) Then
                                        EndD = Worksheets("Calculator").Range("X60")
                                    Else
                                        If IsDate(Worksheets("Calculator").Range("V60")) Then
                                            EndD = Worksheets("Calculator").Range("V60")
                                        Else
                                            If IsDate(Worksheets("Calculator").Range("T60")) Then
                                                EndD = Worksheets("Calculator").Range("T60")
                                            Else
                                                If IsDate(Worksheets("Calculator").Range("R60")) Then
                                                    EndD = Worksheets("Calculator").Range("R60")
                                                Else
                                                    If IsDate(Worksheets("Calculator").Range("P60")) Then
                                                        EndD = Worksheets("Calculator").Range("P60")
                                                    Else
                                                        If IsDate(Worksheets("Calculator").Range("N60")) Then
                                                            EndD = Worksheets("Calculator").Range("N60")
                                                        Else
                                                            If IsDate(Worksheets("Calculator").Range("L60")) Then
                                                                EndD = Worksheets("Calculator").Range("L60")
                                                            Else
                                                                If IsDate(Worksheets("Calculator").Range("J60")) Then
                                                                    EndD = Worksheets("Calculator").Range("J60")
                                                                Else
                                                                    If IsDate(Worksheets("Calculator").Range("H60")) Then
                                                                        EndD = Worksheets("Calculator").Range("H60")
                                                                    Else
                                                                        If IsDate(Worksheets("Calculator").Range("FD60")) Then
                                                                            EndD = Worksheets("Calculator").Range("F60")
                                                                        Else
                                                                            If IsDate(Worksheets("Calculator").Range("D60")) Then
                                                                                EndD = Worksheets("Calculator").Range("D60")
                                                                            Else
                                                                                If IsDate(Worksheets("Calculator").Range("B60")) Then
                                                                                    EndD = Worksheets("Calculator").Range("B60")
                                                                                Else
                                                                                    MsgBox "Enter Investment Period Section on Calculator Sheet"
                                                                                End If
                                                                            End If
                                                                        End If
                                                                    End If
                                                                End If
                                                            End If
                                                        End If
                                                    End If
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        End If
    End If
    For Row = 1 To EndD - StartD
        Cells(Row, 44) = StartD   Row - 1
    Next Row
End Sub

It worked! It just took so long it's not useable. I am hoping to get something that is equivalent to drag and drop, or a simple A1 1 formula, that can end at the oldest end date of up to 20 dates.

CodePudding user response:

(1) Don't repeat your worksheet-name over and over again, use a With clause instead.

(2) There is an ElseIf-statement in VBA, if you use that, it makes the code already more readable

(3) It seems that you are checking every second column, starting from AN (that's column number 40) back to B (2). You could use a loop to check for the end date.

Dim StartD As Date, EndD as Date
With Worksheets("Calculator")
    StartD = .Range("B55") 
    Dim col As Long
    For col = 40 to 2 step -2    ' Look at every 2nd col, starting at AN (=40)
       If IsDate(.Cells(60, col)) Then
           EndD = .Cells(60, col)
           Exit For
       End If
    Next
End With

If EndD = 0 Then 
   MsgBox ...
Else
   ...
End If

CodePudding user response:

There are a few ways to make the code ore readable.

If ElseIf Else

Sub DateAutoFill()
    Dim StartD As Date, EndD As Date
    
    With Worksheets("Calculator")
        StartD = .Range("B55")
        If IsDate(.Range("AN60")) Then
            EndD = .Range("AN60")
        ElseIf IsDate(.Range("AL60")) Then
            EndD = .Range("AL60")
        ElseIf IsDate(.Range("AJ60")) Then
            EndD = .Range("AJ60")
        ElseIf IsDate(.Range("AH60")) Then
            EndD = .Range("AH60")
        ElseIf IsDate(.Range("AF60")) Then
            EndD = .Range("AF60")
        ElseIf IsDate(.Range("AD60")) Then
            EndD = .Range("AD60")
        ElseIf IsDate(.Range("AB60")) Then
            EndD = .Range("AB60")
        ElseIf IsDate(.Range("Z60")) Then
            EndD = .Range("Z60")
        ElseIf IsDate(.Range("X60")) Then
            EndD = .Range("X60")
        ElseIf IsDate(.Range("V60")) Then
            EndD = .Range("V60")
        ElseIf IsDate(.Range("T60")) Then
            EndD = .Range("T60")
        ElseIf IsDate(.Range("R60")) Then
            EndD = .Range("R60")
        ElseIf IsDate(.Range("P60")) Then
            EndD = .Range("P60")
        ElseIf IsDate(.Range("N60")) Then
            EndD = .Range("N60")
        ElseIf IsDate(.Range("L60")) Then
            EndD = .Range("L60")
        ElseIf IsDate(.Range("J60")) Then
            EndD = .Range("J60")
        ElseIf IsDate(.Range("H60")) Then
            EndD = .Range("H60")
        ElseIf IsDate(.Range("FD60")) Then
            EndD = .Range("F60")
        ElseIf IsDate(.Range("D60")) Then
            EndD = .Range("D60")
        ElseIf IsDate(.Range("B60")) Then
            EndD = .Range("B60")
        Else
            MsgBox "Enter Investment Period Section on Calculator Sheet"
        End If
    End With
    
    For Row = 1 To EndD - StartD
        Cells(Row, 44) = StartD   Row - 1
    Next Row
End Sub

Select Case

Sub DateAutoFill()
    Dim StartD As Date, EndD As Date
        
    With Worksheets("Calculator")
        StartD = .Range("B55")
            
        Select Case True
            Case IsDate(.Range("AN60"))
                EndD = .Range("AN60")
            Case IsDate(.Range("AL60"))
                EndD = .Range("AL60")
            Case IsDate(.Range("AJ60"))
                EndD = .Range("AJ60")
            Case IsDate(.Range("AH60"))
                EndD = .Range("AH60")
            Case IsDate(.Range("AF60"))
                EndD = .Range("AF60")
            Case IsDate(.Range("AD60"))
                EndD = .Range("AD60")
            Case IsDate(.Range("AB60"))
                EndD = .Range("AB60")
            Case IsDate(.Range("Z60"))
                EndD = .Range("Z60")
            Case IsDate(.Range("X60"))
                EndD = .Range("X60")
            Case IsDate(.Range("V60"))
                EndD = .Range("V60")
            Case IsDate(.Range("T60"))
                EndD = .Range("T60")
            Case IsDate(.Range("R60"))
                EndD = .Range("R60")
            Case IsDate(.Range("P60"))
                EndD = .Range("P60")
            Case IsDate(.Range("N60"))
                EndD = .Range("N60")
            Case IsDate(.Range("L60"))
                EndD = .Range("L60")
            Case IsDate(.Range("J60"))
                EndD = .Range("J60")
            Case IsDate(.Range("H60"))
                EndD = .Range("H60")
            Case IsDate(.Range("FD60"))
                EndD = .Range("F60")
            Case IsDate(.Range("D60"))
                EndD = .Range("D60")
            Case IsDate(.Range("B60"))
                EndD = .Range("B60")
            Case Else
                MsgBox "Enter Investment Period Section on Calculator Sheet"
        End Select
    End With
        
    For Row = 1 To EndD - StartD
        Cells(Row, 44) = StartD   Row - 1
    Next Row
End Sub
  • Related