0

I am creating a Requirement Traceablity M matrix in the Excel sheet and below VB code is taking more time to execute and excel sheet is hanging for 5 minutes every time I enter something in a cell.


VBA code:

Function MultipleLookupNoRept(Lookupvalue As String, LookupRange As Range, ColumnNumber As Integer)

    Dim xDic As New Dictionary
    Dim xRows As Long
    Dim xStr As String
    Dim i As Long

    On Error Resume Next
    xRows = LookupRange.Rows.Count
    For i = 1 To xRows
        If LookupRange.Columns(1).Cells(i).Value = Lookupvalue Then
            xDic.Add LookupRange.Columns(ColumnNumber).Cells(i).Value, ""
        End If
    Next
    xStr = ""
    MultipleLookupNoRept = xStr
    If xDic.Count > 0 Then
        For i = 0 To xDic.Count - 1
            xStr = xStr & xDic.Keys(i) & ","
        Next
        MultipleLookupNoRept = Left(xStr, Len(xStr) - 1)
    End If 

End Function
  • There is no need to check if the value already exists in the dictionary, just do `xDic(LookupValue) = ""`. Also convert `LookupRange` to 2d array before loop `aRows = LookupRange.Value`, and process the array within loop instead of the range. – omegastripes Jul 04 '18 at 09:59
  • 1
    RTM is requirement traceability Matrix –  Jul 04 '18 at 10:08
  • If no-one manages to work the word REDEMPTION into their answer I will be sorely disappointed. – CLR Jul 04 '18 at 10:38

1 Answers1

1

↓Concatenate all the keys in a Dictionary ↓

Join(Dictionary.Key(), ",")
Function MultipleLookupNoRept(Lookupvalue As String, LookupRange As Range, ColumnNumber As Integer) As String

    Dim xDic As New Dictionary
    Dim xRows As Long
    Dim xStr As String
    Dim i As Long

    On Error Resume Next
    xRows = LookupRange.Rows.count
    For i = 1 To xRows
        If LookupRange.Columns(1).Cells(i).Value = Lookupvalue Then
            xDic.Add LookupRange.Columns(ColumnNumber).Cells(i).Value, ""
        End If
    Next

    If xDic.count > 0 Then
        MultipleLookupNoRept = Join(xDic.Keys(), ",")
    End If

End Function

Here is the ultra modified version of the code. The previous code should process 10K rows in 2-5 seconds.

Function MultipleLookupNoRept(Lookupvalue As String, LookupRange As Range, ColumnNumber As Integer) As String

    Dim addresses As Variant, values As Variant
    Dim r As Long

    With LookupRange.Parent
        With Intersect(LookupRange.Columns(1), .UsedRange)
            values = .Value
            addresses = .Columns(ColumnNumber).Value
        End With
    End With

    With CreateObject("System.Collections.ArrayList")
        For r = 1 To UBound(values)
            If values(r, 1) = Lookupvalue And r <= UBound(addresses) And addresses(r, 1) <> "" Then
                .Add addresses(r, 1)
            End If
        Next

        MultipleLookupNoRept = Join(.ToArray(), ",")
    End With

End Function
TinMan
  • 6,624
  • 2
  • 10
  • 20
  • Now it is getting hanged more than 5 mins.. It is not optimized. Still not working –  Jul 04 '18 at 10:04
  • @SHASHANKBalaganchi I appended another version of the function that trims the range to fit the data. The only way that it would take the previous answer that long to process is if `LookupRange` had +500K cells. – TinMan Jul 04 '18 at 10:35
  • Superb Code @TinMan. Very happy . The Ultra version is awesome and working perfectly. did not expect so fast –  Jul 04 '18 at 10:41
  • At your service!! Happy Coding :) – TinMan Jul 04 '18 at 10:41
  • Wondering if [FIND](https://msdn.microsoft.com/en-us/vba/excel-vba/articles/range-find-method-excel) would speed it up a bit more. – Darren Bartrup-Cook Jul 04 '18 at 10:49
  • Now it is working as soon as i tab out from the cell.. Not sure if more speed up is required. –  Jul 04 '18 at 10:51
  • Lol..I'm glad to hear it. – TinMan Jul 04 '18 at 10:59
  • @DarrenBartrup-Cook There is no need to further optimise this code, arrays are super fast. You might like this articel: [EXCEL VLOOKUP VS INDEX MATCH VS SQL VS VBA](https://analystcave.com/excel-vlookup-vs-index-match-vs-sql-performance/). – TinMan Jul 04 '18 at 11:16
  • @TinMan Yep, you're right. I wasn't thinking about the array side of it - just finding it on the sheet which will always be slower than an array. – Darren Bartrup-Cook Jul 04 '18 at 12:10