Assign restructured array to .List
property
Procedure doFillListBox
- Restructures the entire data set via the
Application.Index()
function as well as two help functions and
- assigns the restructured array to the indicated listbox via its
.List
property in one single code line, also known as Array
method; see section [1]
) (instead of adding listbox items one by one, aka as AddItem
method).
- layouting is done in section
[2]
:
Sub doFillListBox(lbTarget As MSForms.ListBox, rng As Range)
With lbTarget
' =============================
' [1] restructure listbox items
' -----------------------------
.List = Application.Index(rng.Value, getRowNums(rng), getColNums(rng))
' =============================
' [2] layout listbox
' -----------------------------
.ColumnCount = rng.Columns.Count
.ColumnWidths = "100;100;100;100;100;100;60;60"
End With
End Sub
Related link: Some pecularities of the Application.Index function
Helper functions called by above procedure
Function getRowNums(rng As Range, _
Optional ByVal ColNo As Long = 8, _
Optional ByVal backgroundColor = 3) As Variant()
' Purpose: return "vertical" array with row numbers not marked in red background color (e.g.3)
' Note: column number default is the 8th column, default background color is red (3)
Dim n&
n = rng.Rows.Count
' [1] list uncolored row numbers within temporary array
ReDim tmp(1 To n) ' provide for maximum length
Dim i&, ii& ' row numbers in column H, items counter
For i = 1 To n ' iterate through column H cells
If rng.Cells(i, ColNo).Interior.ColorIndex <> backgroundColor Then ' check criteria
ii = ii + 1 ' increment new items counter
tmp(ii) = i ' enter "old" row number
End If
Next i
ReDim Preserve tmp(1 To ii) ' reduce to actually needed length
' [2] return "vertical" list of needed row numbers
getRowNums = Application.Transpose(tmp) ' transpose to 2-dim array
End Function
Function getColNums(rng As Range) As Variant()
' Purpose: return all column numbers in a "flat" array, e.g. via Array(1,2,3,4,5,6,7,8)
getColNums = Application.Transpose(Evaluate("row(1:" & rng.Columns.Count & ")"))
End Function
Example call
Assuming you want to use the click event of a command button control to populate a given ListBox
by referencing the data range e.g. via the sheet's CodeName
:
Private Sub CommandButton1_Click()
' Note: change control names and range reference following your needs
doFillListBox Me.ListBox1, Sheet1.Range("A3:H150") ' reference e.g. to CodeName Sheet1
End Sub
Note: The (Name)
property is the sheet's CodeName identifier in the VB Editor's Tool window as opposed to the user-modifiable "tab" Name
of the worksheet.