显示多行值的用户窗体

Userform to display values from multiple rows

我创建了一个用户表单,使用户能够在文本框中输入最多 5 个唯一 ID 以及 6 条不同的信息(文本框和列表框的混合),所有 5 个 ID 输入都保持不变。

然后将此信息记录到工作表中,每个唯一 ID 都有自己的行,其余 6 条信息在每个对应行中重复。

对于记录的每一行 ID,都有一个唯一的参考编号。将自动生成,这意味着您将有一个 table,其中前两列如下所示:

Unique Reference Number Unique ID
001 2120
001 2130
001 8765
002 7688
002 7684
002 7682
002 7681
002 7666

我在用户窗体中添加了一个命令按钮和文本框,使用户能够搜索唯一的参考编号(例如 001),但我希望代码能够找到所有对应的行(最多 5 行)包含搜索参考编号的电子表格,然后在用于在用户表单中记录信息的相同 text/list 框中显示最多 5 行和 6 条信息。

当我当前搜索参考编号时,用户表单在第一个 ID 文本框中显示第一个 ID,并在相应的文本框中显示 6 条信息,没有任何问题。但它随后会在第二个 ID 文本框中显示所有后续行的 ID 号 - 这意味着它找到了正确的信息,但没有将其显示到用户表单中的正确文本框中。

本质上,我试图让代码循环遍历工作表中的第一列并找到所有匹配值(参考编号),然后检索并显示相应 ID 文本框中每一行的唯一 ID 信息在用户表单中。

Private Sub CommandButton1_Click()

    Dim x As Long
    Dim y As Long
    Dim found As Boolean 

    With Sheets("Example Spreadsheet")
        x = .Range("A" & .Rows.Count).End(xlUp).Row
        For y = 1 To x
            If .Cells(y, 1).Text = Search.Value Then
                If Not found Then 
                    found = True 
                    Me.ID1.Value = .Cells(y, 2)
                    Me.Branch.Value = .Cells(y, 3)
                    Me.AccountNo.Value = .Cells(y, 4)
                    Me.Name.Value = .Cells(y, 5)
                    Me.DateReceived.Value = .Cells(y, 6)
                    Me.DateClosed.Value = .Cells(y, 7)
                Else 
                    Me.ID2.Value = Me.ID2.Value & .Cells(y, 2)
                End If
            End If
        Next y
    End With

End Sub

该代码仅引用了文本框 ID1 和 ID2,但我试过合并其他 ID3-5 文本框,但无法使其正确显示信息。

在做涉及查找匹配项的事情时,我喜欢将两部分分开——首先找到所有匹配项,然后处理它们。让您的代码更简洁,您可以专注于主要任务,而不是在查找和处理之间切换上下文。 (下面未经测试的代码)

Private Sub CommandButton1_Click()
    Const MAX_HITS As Long = 5
    Dim x As Long, found As Collection, rw As Range

    'get all matches
    With Sheets("Example Spreadsheet")
        Set found = FindAll(.Range("A1:A" & .Cells(.Rows.Count, 1).End(xlUp).Row), Search.Value)
    End With
    
    If found.Count > 0 Then
        For x = 1 To found.Count
            If x = 1 Then
                Set rw = found(x).EntireRow 'the whole row for this matched cell
                Me.ID1.Value = rw.Cells(2).Value
                Me.Branch.Value = rw.Cells(3).Value
                Me.AccountNo.Value = rw.Cells(4).Value
                Me.Name.Value = rw.Cells(5).Value
                Me.DateReceived.Value = rw.Cells(6).Value
                Me.DateClosed.Value = rw.Cells(7).Value
            ElseIf x > MAX_HITS Then
                'make sure we didn't find too many...
                MsgBox "Too many matches (" & found.Count & ") for " & Search.Value
            Else
                Me.Controls("ID" & x).Value = found(x).Value 'refer to control by name
            End If
        Next x
    Else
        MsgBox "No hits for " & Search.Value
    End If
    
End Sub

'return all matching cells in a collection
Public Function FindAll(rng As Range, v) As Collection
    Dim rv As New Collection, f As Range
    Dim addr As String
 
    Set f = rng.Find(what:=v, after:=rng.Cells(rng.Cells.Count), _
        LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
        SearchDirection:=xlNext, MatchCase:=False)
    If Not f Is Nothing Then addr = f.Address()
    Do Until f Is Nothing
        rv.Add f
        Set f = rng.FindNext(after:=f)
        If f.Address() = addr Then Exit Do
    Loop
    Set FindAll = rv
End Function