'VBA Copy row from one 2D array and add it to another 2D array

I have a large database (~7000 rows x 25 columns) that i have assigned to an array. Based on user inputs, I am trying to search the database to find items that match the input and copy the entire row to a new array to create a new database to filter with the next question. The arrays are DBRange and DBT and are defined as public variants. I've tried copying the data from DBRange to a new sheet, but that is incredibly slow and I'm trying to speed things up with keeping things within arrays if possible.

DBRange = wsd.Range("A1").CurrentRegion 'Sets DBRange to the entirety of the Database


Cervical = 0

If CervicalStartOB.Value = True Then
Cervical = 1
SpineSection.Hide

For i = LBound(DBRange, 1) To UBound(DBRange, 1) 'starts for loop starting with the 1st row in the array to the last row
    If DBRange(i, 13) = "X" Then  'determines if the value in row i column 13 has an X
    ReDim Preserve DBT(count, UBound(DBRange, 2))
    DBT(count, UBound(DBRange, 2)) = Application.WorksheetFunction.Index(DBRange, i, 0)
    count = count + 1 
    
    End If
  Next i


Solution 1:[1]

Get Range Criteria Rows

Option Explicit


Sub GetRangeCriteriaRowsTESTKeepHeaders()
    
    Const sCriteriaString As String = "X"
    Const sCol As Long = 13
    Const sfRow As Long = 2 ' First Data Row
    
    Dim wsd As Worksheet: Set wsd = ActiveSheet
    
    ' Reference the source range
    Dim srg As Range: Set srg = wsd.Range("A1").CurrentRegion
    
    ' Write the criteria rows to an array.
    ' If you want to keep headers, use the first row ('sfrow')
    ' as the parameter of the 'FirstRow' argument of the function.
    Dim DBT As Variant
    DBT = GetRangeCriteriaRows(srg, sCriteriaString, sCol, sfRow)
    If IsEmpty(DBT) Then Exit Sub

End Sub


Sub GetRangeCriteriaRowsTESTOnlyData()
    
    Const sCriteriaString As String = "X"
    Const sCol As Long = 13
    Const sfRow As Long = 2 ' First Data Row
    
    Dim wsd As Worksheet: Set wsd = ActiveSheet
    
    ' Reference the source range.
    Dim srg As Range: Set srg = wsd.Range("A1").CurrentRegion
    
    ' Reference the data range (no headers).
    Dim shrCount As Long: shrCount = sfRow - 1
    Dim sdrg As Range
    Set sdrg = srg.Resize(srg.Rows.Count - shrCount).Offset(shrCount)
    
    ' Write the criteria rows to an array.
    ' If the range has no headers, don't use the 'FirstRow' argument
    ' of the function.
    Dim DBT As Variant: DBT = GetRangeCriteriaRows(sdrg, sCriteriaString, sCol)
    If IsEmpty(DBT) Then Exit Sub

End Sub


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Returns the values of the rows of a range ('SourceRange'),
'               that meet a string criterion ('CriteriaString') in a column
'               ('CriteriaColumnIndex'), in a 2D one-based array.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function GetRangeCriteriaRows( _
    ByVal SourceRange As Range, _
    ByVal CriteriaString As String, _
    Optional ByVal CriteriaColumnIndex As Long = 1, _
    Optional ByVal FirstRow As Long = 1) _
As Variant
    Const ProcName As String = "GetRangeCriteriaRows"
    On Error GoTo ClearError

    ' Count the source rows and the source/destination columns.
    Dim srCount As Long: srCount = SourceRange.Rows.Count
    Dim cCount As Long: cCount = SourceRange.Columns.Count
    ' Count the source header rows.
    Dim shrCount As Long: shrCount = FirstRow - 1
    
    ' Define the source data range according to the first row.
    Dim sdrg As Range
    Set sdrg = SourceRange.Resize(srCount - shrCount).Offset(shrCount)
    
    ' Write the source range values to the source array.
    Dim sData As Variant: sData = SourceRange.Value
    
    ' Count the criteria rows in the source data criteria column range.
    Dim sdcrg As Range: Set sdcrg = sdrg.Columns(CriteriaColumnIndex)
    Dim drCount As Long
    drCount = Application.CountIf(sdcrg, CriteriaString) + shrCount
    
    ' Define the destination array.
    Dim dData As Variant: ReDim dData(1 To drCount, 1 To cCount)
    
    Dim sr As Long ' Current Source Row
    Dim c As Long ' Current Source/Destination Column
    Dim dr As Long ' Current Destination Row
    
    ' Write the header rows from the source array to the destination array.
    If FirstRow > 1 Then
        For sr = 1 To shrCount
            dr = dr + 1
            For c = 1 To cCount
                dData(dr, c) = sData(sr, c)
            Next c
        Next sr
    End If
    
    ' Write the criteria rows from the source array to the destination array.
    For sr = FirstRow To srCount
        If StrComp(CStr(sData(sr, CriteriaColumnIndex)), CriteriaString, _
                vbTextCompare) = 0 Then
            dr = dr + 1
            For c = 1 To cCount
                dData(dr, c) = sData(sr, c)
            Next c
        End If
    Next sr
    
    GetRangeCriteriaRows = dData
    
ProcExit:
    Exit Function
ClearError:
    Debug.Print "'" & ProcName & "' Run-time error '" _
        & Err.Number & "':" & vbLf & "    " & Err.Description
    Resume ProcExit
End Function

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1