Excel 在文本框中搜索并在列表框中过滤的用户表单

Excel Userform to search in textbox and filter in a listbox

你好,我正在寻求帮助,我在 Excel 用户表单中有一个文本框和一个列表框,除了一个小细节外,它工作完美:一旦结果出现在列表框中,它们就代表了搜索在所有列中。但是,当我在文本框中键入内容时,第一列是隐藏的,如何确保该列在搜索过程中保持可见? 提前致谢

代码如下:

Private Sub UserForm_Initialize()

End Sub

Private Sub TextBox1_Change()

With Sheets("Sheet1")

lr = .Range("A" & Rows.Count).End(xlUp).Row
ReDim arr(1 To lr - 1)
ReDim sn(1 To lr - 1, 1 To 13)
For i = 1 To UBound(arr)
    arr(i) = .Range("A" & i + 2) & " " & .Range("B" & i + 2) & " " & .Range("C" & i + 2) & " " & .Range("D" & i + 2) & " " & .Range("E" & i + 2) & " " & .Range("F" & i + 2)
    If InStr(1, arr(i), TextBox1) > 0 Then
        j = j + 1
        For X = 2 To 8
            sn(j, X - 1) = .Cells(i + 2, X)
        Next
    End If
Next
ListBox1.List = sn

End With

End Sub 

一致数组方法

您的原始代码在创建筛选列表框列表时显示了 arrayrange 循环的混合。为了通过仅循环遍历数组 *) 在这里更加一致,您可以按如下方式优化代码(例如,通过 Instr 使用相同的匹配检查):

Userform事件过程TextBox1_Change()

Private Sub TextBox1_Change()
  Const STARTROW = 3
  Dim i&, iCnt&, r&, c&                                                       ' array counters for "rows" and "columns"
  Dim sn, tmp                                                                 ' variant 2-dim 1-based arrays
  With Sheets("Sheet1")
      iCnt = .Range("A" & Rows.Count).End(xlUp).Row - STARTROW + 1            ' items counter
      ReDim sn(1 To iCnt, 1 To 13)                                            ' provide for filtered data array
      For i = 1 To iCnt
         'assign current data row to 2-dim 1-based temporary array
          tmp = .Range("A" & (i + 2) & ":F" & (i + 2))                        ' current data row (c.f. OP)
         'compare search string with concatenated data string from current row
          If InStr(1, concat(tmp), TextBox1.Text) > 0 Then                    ' check occurrence e.g. via Instr
              r = r + 1                                                       ' new rows counter
              For c = 1 To UBound(tmp, 2)                                     ' col counter
                  sn(r, c) = tmp(1, c)                                        ' collect found row data
              Next
          End If
      Next
      ListBox1.List = sn                                                      ' assign array to .List property
  End With

End Sub

上面的事件过程调用的辅助函数concat()

Private Function concat(ByVal arr, Optional ByVal delim$ = " ") As String
' Purpose: build string from 2-dim array row, delimited by 2nd argument
' Note:    concatenation via JOIN needs a "flat" 1-dim array via double transposition
  concat = Join(Application.Transpose(Application.Transpose(arr)), delim)
End Function

备注

*) 通过 VBA 遍历一个范围总是很耗时,所以用数组代替。

您可能还对以下演示如何使用列表框的解决方案感兴趣 Column property。通过解决这个问题可以帮助您删除列表框中多余的空白行。