'*****************************************************************************************************
'*****************************************************************************************************
'* AWE_ARRAY: Manipulate millions of lines of code within seconds not minutes. AWE_Array converts **
'* ranges to arrays, allows you to find and update the data in arrays by column name or **
'* row value. It can be used as a stand alone class or as the perfect companion to the **
'* AWE_Sheet class. **
'* SITE: www.AutomationWithExcel.com **
'* Author: Mike Libby **
'*****************************************************************************************************
'*****************************************************************************************************
Option Explicit
'====================================================================================================
'== PRIVATE VARIABLES ===============================================================================
'====================================================================================================
Private m_Worksheet As Worksheet
Private m_Range As Range
'--- Array Variables ---
Private m_HdrArr As Variant
Private m_RngArr As Variant
Private m_ColArr As Variant
Private m_VisRowArr As Variant
'====================================================================================================
'== INITIALIZE ======================================================================================
'====================================================================================================
'----------------------------------------------------------------------------------------------------
' Initialize - Initialize the AWE_Array
' Params:
' rng as Variant - A Worksheet range
' Optional HdrRowNb as Long - The header's row number. Default = 1
' Optional MaxRows - The number of rows to create the array with. Default = rng.rows.count.
' Examples: Dim AWESh as new AWE_Array: AWESh.Initialize SheetRange, 3, 1000000
' Note: Do not include the header row in the rng. Column header names will be retrieved so that
' you can reference them by name in subsequent calls.
'----------------------------------------------------------------------------------------------------
Public Function Initialize(rng As Range, Optional HdrRowNb As Long = 1, Optional MaxRows As Long = 0)
Set m_Worksheet = rng.Parent: Set m_Range = rng
Dim rArea As Range, rCol As Range, icol As Long, sColNms As String, sRng As Variant, rCols As Range
Dim ColMax As Long, RowMax As Long, iRow As Long, rRow As Range
'--- If MaxRows > 0 then resize the array to MaxRows ---
If MaxRows > 0 Then Set m_Range = m_Range.Resize(MaxRows + 1)
'--- Create m_HdrArr, Header Array ---
For Each sRng In Split(m_Range.Address, ",")
Set rCols = m_Worksheet.Range(sRng)
For Each rCol In rCols.Columns
If sColNms <> "" Then sColNms = sColNms & ";"
sColNms = sColNms & rCol.EntireColumn.Cells(HdrRowNb).Value
Next rCol
Next sRng
m_HdrArr = Split(sColNms, ";"): ReDim Preserve m_HdrArr(LBound(m_HdrArr) + 1 To UBound(m_HdrArr) + 1)
'--- Create m_ColArr, Data Array ---
ReDim m_ColArr(LBound(m_HdrArr) To UBound(m_HdrArr)): icol = 0
ReDim m_RngArr(LBound(m_HdrArr) To UBound(m_HdrArr))
For Each sRng In Split(m_Range.Address, ",")
Set rCols = m_Worksheet.Range(sRng)
For Each rCol In rCols.Columns
icol = icol + 1
m_ColArr(icol) = rCol.Value
Set m_RngArr(icol) = rCol
Next rCol
Next sRng
'--- Create m_VisRowArr, Visible Row Array ---
If IsFiltered Then
ReDim m_VisRowArr(LBound(m_ColArr(1)) To UBound(m_ColArr(1)))
For Each rRow In m_RngArr(1).SpecialCells(xlCellTypeVisible)
m_VisRowArr(rRow.row - HdrRowNb) = True
Next rRow
End If
End Function
'====================================================================================================
'== COLUMNS =========================================================================================
'====================================================================================================
'----------------------------------------------------------------------------------------------------
' ColNbr As Long - Search for and return a Column's number on the header row
' Params: ColNbrOrNameOrRange as Variant. A column number, name, or Range.
' Example: Dim iCol as Long: iCol = AWESh.ColNbr("Column Name").
' Note: a critical message displays if the column is not found and then processing stops.
'----------------------------------------------------------------------------------------------------
Public Function ColNbr(ColIdxOrNm As Variant) As Long
If IsNumeric(ColIdxOrNm) Then ColNbr = CLng(ColIdxOrNm) _
Else: ColNbr = SearchFor(CStr(ColIdxOrNm), m_HdrArr)
If ColNbr = -1 Then
'--- Fatal Error: display message and end processing if the ColIdxOrNm was not found ---
MsgBox "AWE_Array::ColNbr::m_HdrArr does not contain header: " & ColIdxOrNm, vbCritical
End
End If
End Function
'----------------------------------------------------------------------------------------------------
' FirstCol As Long - Return the header row's first column number
' Example: Dim iCol as Long: iCol = AWESh.FirstCol
'----------------------------------------------------------------------------------------------------
Public Property Get FirstCol() As Long: FirstCol = LBound(m_HdrArr): End Property
'----------------------------------------------------------------------------------------------------
' LastCol As Long - Return the header row's last column number
' Example: Dim iCol as Long: iCol = AWESh.LastCol
'----------------------------------------------------------------------------------------------------
Public Property Get LastCol() As Long: LastCol = UBound(m_HdrArr): End Property
'====================================================================================================
'== ROWS ============================================================================================
'====================================================================================================
'----------------------------------------------------------------------------------------------------
' FirstDataRow As Long - Return the first data row's (the row under the header row) number.
' Example: Dim iRow as Long: iRow = AWESh.FirstDataRow
'----------------------------------------------------------------------------------------------------
Public Property Get FirstDataRow() As Long: FirstDataRow = LBound(m_ColArr(1)): End Property
'----------------------------------------------------------------------------------------------------
' LastDataRow As Long - Return the last data row's number
' Example: Dim iRow as Long: iRow = AWESh.LastDataRow
'----------------------------------------------------------------------------------------------------
Public Property Get LastDataRow() As Long: LastDataRow = UBound(m_ColArr(1)): End Property
'----------------------------------------------------------------------------------------------------
' RowNbr As Long - Find and return the row number in a specifical column on the sheet
' Params: RowNbrOrSrchVal As Variant - A sheet's row number or value to find within the column.
' ColNbrOrName As Variant - A column number or name on the sheet.
' Optional SearchDirection As Long = xlNext - Search direction (xlNext or xlPrevious) to use.
' Example: Dim iRow as Long: iRow = AWESh.RowNb("SearchVal", "Column Name")
'----------------------------------------------------------------------------------------------------
Public Function RowNbr(RowIdxOrVal As Variant, ColIdxOrNm As Variant) As Long
Dim icol As Long: icol = ColNbr(ColIdxOrNm)
If IsNumeric(RowIdxOrVal) Then RowNbr = CLng(RowIdxOrVal) _
Else: RowNbr = SearchFor(CStr(RowIdxOrVal), m_ColArr(icol))
End Function
'====================================================================================================
'== CELL ============================================================================================
'====================================================================================================
'----------------------------------------------------------------------------------------------------
' Cell As Variant - Searches for and returns a cell's value.
' Params: RowNbrOrSrchVal As Variant - A sheet's row number or value to find within the column.
' ColNbrOrName As Variant - A column number or name on the sheet.
' Optional SearchDirection As Long = xlNext - Search direction (xlNext or xlPrevious) to use.
' Example: Dim var As Variant: set var = AWESh.Cell ("Search Value", "Column Name")
'----------------------------------------------------------------------------------------------------
Public Property Get Cell(RowNbrOrSrchVal As Variant, ColIdxOrNm As Variant) As Variant
Dim icol As Long, iRow As Long
If IsNumeric(ColIdxOrNm) Then icol = CLng(ColIdxOrNm) Else icol = ColNbr(ColIdxOrNm)
If IsNumeric(RowNbrOrSrchVal) Then iRow = CLng(RowNbrOrSrchVal) _
Else iRow = RowNbr(RowNbrOrSrchVal, icol)
If iRow = -1 Then Cell = Nothing Else Cell = m_ColArr(icol)(iRow, 1)
End Property
'----------------------------------------------------------------------------------------------------
' Cell - Searches for and sets a cell's value.
' Params: RowNbrOrSrchVal As Variant - A sheet's row number or value to find within the column.
' ColNbrOrName As Variant - A column number or name on the sheet.
' Optional SearchDirection As Long = xlNext - Search direction (xlNext or xlPrevious) to use.
' Example: Dim var As Variant: set var = AWESh.Cell ("Search Value", "Column Name")
' Note, Prompts user on whether to continue if the the SrchVal is not found in the column.
'----------------------------------------------------------------------------------------------------
Public Property Let Cell(RowNbrOrSrchVal As Variant, ColIdxOrNm As Variant, Value As Variant)
Dim icol As Long: icol = ColNbr(ColIdxOrNm)
Dim iRow As Long: iRow = RowNbr(RowNbrOrSrchVal, icol)
If iRow = -1 Then
If MsgBox("AWE_Array::Cell::" & ColIdxOrNm & " does not contain RowNbrOrSrchVal: " _
& RowNbrOrSrchVal & ", Continue?", vbCritical, vbYesNo) = vbNo Then End
End If
If iRow <> -1 Then m_ColArr(icol)(iRow, 1) = Value
End Property
'====================================================================================================
'== SEARCHFOR =======================================================================================
'====================================================================================================
'----------------------------------------------------------------------------------------------------
' SearchFor as long - Returns the array occurance where the search string was found; otherwise, -1
' Params: SrchStr as String - Value to search for
' Arr as Variant - An array of values
' Example: Dim filter as Boolean: filter = AWESh.IsFiltered
'----------------------------------------------------------------------------------------------------
Public Function SearchFor(SrchStr As String, Arr As Variant) As Long
On Error Resume Next
SearchFor = -1: SearchFor = Application.Match(SrchStr, Arr, 0)
End Function
'====================================================================================================
'== FILTER ==========================================================================================
'====================================================================================================
'----------------------------------------------------------------------------------------------------
' IsFiltered As Boolean - Returns True if there is a filter on the sheet; otherwise, False.
' Example: Dim bFiltered as Boolean: bFiltered = AWESh.IsFiltered
'----------------------------------------------------------------------------------------------------
Public Property Get IsFiltered() As Boolean
If m_Worksheet.FilterMode = True Then
If m_Worksheet.AutoFilter.Range.Areas.Count > 0 Then
IsFiltered = True
End If
End If
End Property
'---------------------------------------------------------------------------------------------------------------------
' IsRowVisible - Returns True if a role is visible; otherwise, False.
' Example: Dim rng As Range: set rng = AWESh.HeaderRange
'---------------------------------------------------------------------------------------------------------------------
Public Property Get IsRowVisible(iRow As Long) As Boolean
IsRowVisible = m_VisRowArr(iRow)
End Property
'====================================================================================================
'== WRITE ARRAY =====================================================================================
'====================================================================================================
'----------------------------------------------------------------------------------------------------
' WriteArray - Write the array back to the range that was intially set in the Initialize Function.
' Example: AWESh.WriteArray ()
'----------------------------------------------------------------------------------------------------
Public Function WriteArray()
Dim icol As Long: icol = 0
If IsFiltered Then
MsgBox "Critical Error: Clear Filters before calling AWE_Array::WriteArray", vbCritical: End
End If
For icol = LBound(m_ColArr) To UBound(m_ColArr)
m_RngArr(icol).Value = m_ColArr(icol)
Next icol
End Function
Add comment
Comments