显示多行值的用户窗体
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
我创建了一个用户表单,使用户能够在文本框中输入最多 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