Excel VBA - 如何取消选择列表框中先前选择的项目
Excel VBA - How To Deselect A Previosuly Selected Item In A Listbox
我的 Excel VBA 项目中有一个用户表单 (uf1_assess_sched),它有一个列表框 (uf1_listbox3)。
当用户 select 在此列表框中输入单个项目时,将打开第二个用户表单 (group_1),允许用户输入特定于她在 selection 上创建的信息第一个用户表单。如果用户希望放弃在 group_1 上的进一步输入,她可以通过单击名为 Exit 的命令按钮退出。
退出时,group_1被卸载,uf1_assess_sched走在最前面。这个想法是允许用户 select 来自 uf1)listbox3 的另一个项目。然而,她最初制作的 selection 仍然是 selected.
我如何去select这个以前制作的selection.
我试过:
With uf1_assess_sched
.uf1_listbox3.listindex = -1
End With
这是我在所有搜索中找到的最相关的内容。
根据帕特里克的建议,我对 Excel VBA 的理解有限,我是这样解释他的指示的。
With uf1_assess_sched
For i = 0 To .uf1_listbox3.ListCount - 1
If .uf1_listbox3.Selected(i) = True Then
.uf1_listbox3.Selected(i) = False
End If
Next i
End With
遗憾的是,这没有用。代码确实找到了真正的 selection,但该条目仍在列表框中 selected 并且还触发了 uf1_listbox3_Click 事件。
我希望我通过简单地编辑我的原始 post 以适当的方式提供反馈。我不确定如何将代码添加到评论中。 Whosebug 对我来说是一种新格式,所以尽我所能。
使用 Patrick 如此友好地提供的最新代码,我在遇到错误之前设法做到了这一点。我做了一些改编以反映用户表单和列表框名称。我在第二个用户表单 group_1.
中的代码中遇到 "Method or data member not found. " 错误
Private Sub exit1_Click()
Dim ui2 As VbMsgBoxResult
Dim lastrow As Long
Dim i As Long
If ws_vh.Range("E2") > 0 Then 'unsaved info
Me.Label34.Caption = " Saving unsaved rental data."
Me.Label34.BorderColor = RGB(50, 205, 50)
lastrow = ws_rd.Cells(ws_rd.Rows.Count, "A").End(xlUp).Row
ws_rd.Range("A3:FZ" & lastrow).Sort key1:=ws_rd.Range("A3"), order1:=xlAscending, Header:=xlNo
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Debug.Print Me.Name, "exit1_Click() called"
uf1_assess_sched.ListBox3_DeSelect '<--- Error with ".Listbox3_DeSelect"
Unload Me
'Unload group_1
'End
Exit Sub
End If
If ws_vh.Range("B2") > 0 Then 'Outstanding rentals?
ui2 = MsgBox("You still have " & ws_vh.Range("C2") & " rentals with critical missing rental information." & Chr(13) & Chr(13) _
& "Active (Sports) rentals: " & ws_vh.Range("B3") & Chr(13) & "Passive (Picnics) rentals: " & ws_vh.Range("B4") & Chr(13) & Chr(13) _
& "Are you sure you wish to exit?", vbInformation + vbYesNo, "OUTSTANDING RENTAL INFORMATION")
If ui2 = vbYes Then
If ws_vh.Range("N4") > 0 Then
Me.Label34.Caption = " Saving unsaved rental data."
Me.Label34.BorderColor = RGB(50, 205, 50)
lastrow = ws_rd.Cells(ws_rd.Rows.Count, "A").End(xlUp).Row
ws_rd.Range("A3:FZ" & lastrow).Sort key1:=ws_rd.Range("A3"), order1:=xlAscending, Header:=xlNo
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Workbooks("Sports15c.xlsm").Activate
mbEvents = False
Debug.Print Me.Name, "exit1_Click() called"
uf1_assess_sched.ListBox3_DeSelect '<--- Error with ".Listbox3_DeSelect"
Unload Me
Exit Sub
Else
Unload Me
End
End If
Else
Exit Sub
End If
End If
Unload group_1
End
End Sub
我确实将 subs ListBox1_DeSelect() 和 ListBoxDeSelect(oListBox As Object) 放在一个单独的模块中(也许这就是问题所在)。
这是代码...
Sub ListBox3_DeSelect()
ListBoxDeSelect Me.uf1_listbox3
End Sub
Private Sub ListBoxDeSelect(oListBox As Object)
Dim i As Long
If TypeName(oListBox) <> "ListBox" Then Exit Sub
bSkipEvent = True
With oListBox
For i = 0 To .ListCount - 1
If .Selected(i) Then
.Selected(i) = False
End If
Next
End With
bSkipEvent = False
End Sub
这是我最近的代码(7 月 19 日)...
USERFORM 1 - uf1_assess_sched(包含用户为其创建 selection 的列表框)
Private Sub uf1_listbox3_Click()
If mbEvents Then Exit Sub
Debug.Print Me.Name, "uf1_listBox3_Click() called"
If bSkipEvent Then Exit Sub
With uf1_listbox3
Debug.Print Me.Name, "uf1_listBox3_Click() ListIndex: " & .ListIndex & " (" & .List(.ListIndex) & ")"
group_1.Show
'UserForm2.TextBox1.Value = .List(.ListIndex) ' This won't have effect if UserForm2 is True on ShowModal
End With
End Sub
USERFORM 2 - group_1(允许用户根据值 select 在 userform1 中输入附加数据。用户可以通过按退出按钮 (exit1) 选择放弃)
Private Sub exit1_Click()
Dim ui2 As VbMsgBoxResult
Dim lastrow As Long
Dim i As Long
If ws_vh.Range("E2") > 0 Then 'unsaved info
Me.Label34.Caption = " Saving unsaved rental data."
Me.Label34.BorderColor = RGB(50, 205, 50)
lastrow = ws_rd.Cells(ws_rd.Rows.Count, "A").End(xlUp).Row
ws_rd.Range("A3:FZ" & lastrow).Sort key1:=ws_rd.Range("A3"), order1:=xlAscending, Header:=xlNo
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Unload group_1
'End
Exit Sub
End If
If ws_vh.Range("B2") > 0 Then 'Outstanding rentals?
ui2 = MsgBox("You still have " & ws_vh.Range("C2") & " rentals with critical missing rental information." & Chr(13) & Chr(13) _
& "Active (Sports) rentals: " & ws_vh.Range("B3") & Chr(13) & "Passive (Picnics) rentals: " & ws_vh.Range("B4") & Chr(13) & Chr(13) _
& "Are you sure you wish to exit?", vbInformation + vbYesNo, "OUTSTANDING RENTAL INFORMATION")
If ui2 = vbYes Then
If ws_vh.Range("N4") > 0 Then
Me.Label34.Caption = " Saving unsaved rental data."
Me.Label34.BorderColor = RGB(50, 205, 50)
lastrow = ws_rd.Cells(ws_rd.Rows.Count, "A").End(xlUp).Row
ws_rd.Range("A3:FZ" & lastrow).Sort key1:=ws_rd.Range("A3"), order1:=xlAscending, Header:=xlNo
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Workbooks("Sports15c.xlsm").Activate
Debug.Print Me.Name, "EXIT1_Click() called"
'UserForm1.ListBox1_DeSelect ' No longer used.
Set oListBoxToDeselect = uf1_assess_sched.uf1_listbox3 ' [M2] This is required for the DelayedListBoxDeSelect(), if top right [X] is clicked, it won't do DeSelect
Unload Me
Else
Unload Me
End
End If
Else
Exit Sub
End If
End If
'If ws_vh.Range("N4") > 0 Then
' MsgBox "Unsaved rental data. Saving."
' lastrow = ws_rd.Cells(ws_rd.Rows.Count, "A").End(xlUp).row
' ws_rd.Range("A3:FZ" & lastrow).Sort key1:=ws_rd.Range("A3"), order1:=xlAscending, Header:=xlNo
' Application.DisplayAlerts = False
' ThisWorkbook.Save
' Application.DisplayAlerts = True
' Unload Me
'Else
' Worksheets("DYNAMIC").Activate
' Unload Me
'End If
'End If
Unload group_1
'Worksheets("DYNAMIC").Activate
End
End Sub
出于测试目的假设 ws_vh.Range("B2") > 0
以及独立辅助模块...
Option Explicit
' Generic ListBox Deselector
Sub ListBoxDeSelect(oListBox As Object)
Dim i As Long
If TypeName(oListBox) <> "ListBox" Then Exit Sub
bSkipEvent = True
With oListBox
For i = 0 To .ListCount - 1
If .Selected(i) Then
.Selected(i) = False
End If
Next
End With
bSkipEvent = False
End Sub
' METHOD 2 [M2] - When UserForm's ShowModal = True
Sub DelayedListBoxDeSelect()
Dim i As Long
If TypeName(oListBoxToDeselect) <> "ListBox" Then Exit Sub
bSkipEvent = True
With oListBoxToDeselect
For i = 0 To .ListCount - 1
If .Selected(i) Then
.Selected(i) = False
End If
Next
End With
bSkipEvent = False
Set oListBoxToDeselect = Nothing
End Sub
group_1 用户表单终止代码
Private Sub UserForm_Terminate()
Debug.Print Me.Name, "UserForm_Terminate() called"
Set oListBoxToDeselect = uf1_assess_sched.uf1_listbox3 ' [M2] This is required for the DelayedListBoxDeSelect(), if top right [X] is clicked, it won't do DeSelect
Application.OnTime Now + TimeSerial(0, 0, 1), "DelayedListBoxDeSelect" ' [M2] Sechedules the Sub named "DelayedListBoxDeSelect" to execute in 1 second.
End Sub
第 2 部分 - 需要 selection 被去除select的替代场景。
If i = 0 Then
MsgBox "Nothing to eliminate."
'--- > Deselect the user selection in uf_assess_sched.uf1_listbox2 < ---
Exit Sub
End If
至少有一种方法可以处理无意的用户窗体控件事件。
由于我不知道您的用户表单如何相互交互,我认为最简单的方法是添加一个 全局布尔变量 以允许您 跳过 需要时的事件,如下所示。
已编辑提示: 我已将全局布尔变量 bSkipEvent
和 Sub ListBoxDeSelect()
取出到普通模块作为代码缩减,并调用扔进 UserForm1.ListBox1
之类的东西。 (确保显示并启用该用户窗体中的列表框,否则添加错误捕获代码)。
当 UserForms ShowModal = True
(TSM) 时,需要一种不同的方法 - 一种方法是安排一个 Sub 被调用以改变另一个 TSM。在这里,我使用 Application.OnTime
将 DelayedListBoxDeSelect 安排在 UserForm2 完全关闭之前的 1 秒。请注意 UserFormHelper 中的额外 Public 对象。希望你明白我在这里做什么。
考虑这两个简单的用户表单:
- 加载 UserForm1 并单击列表框选项之一后:
- 单击 UserForm2 上的命令按钮将焦点带回 UserForm1:
请注意 ListBox1 中的虚线选择,我认为最好保留它作为提醒之前选择了什么。
代码:
UserForm1
Private Sub UserForm_Initialize()
bSkipEvent = False
End Sub
Private Sub ListBox1_Click()
Debug.Print Me.Name, "ListBox1_Click() called"
If bSkipEvent Then Exit Sub
With ListBox1
Debug.Print Me.Name, "ListBox1_Click() ListIndex: " & .ListIndex & " (" & .List(.ListIndex) & ")"
UserForm2.Show
UserForm2.TextBox1.Value = .List(.ListIndex) ' This won't have effect if UserForm2 is True on ShowModal
End With
End Sub
'Sub ListBox1_DeSelect() ' No longer used
' ListBoxDeSelect Me.ListBox1
'End Sub
UserFormsHelper(普通模块)
Public bSkipEvent As Boolean ' This makes accessible to Userforms and other Modules
Public oListBoxToDeselect As Object '[M2] This is for delayed ListBox Deselect method
' Generic ListBox Deselector
Sub ListBoxDeSelect(oListBox As Object)
Dim i As Long
If TypeName(oListBox) <> "ListBox" Then Exit Sub
bSkipEvent = True
With oListBox
For i = 0 To .ListCount - 1
If .Selected(i) Then
.Selected(i) = False
End If
Next
End With
bSkipEvent = False
End Sub
' METHOD 2 [M2] - When UserForm's ShowModal = True
Sub DelayedListBoxDeSelect()
Dim i As Long
If TypeName(oListBoxToDeselect) <> "ListBox" Then Exit Sub
bSkipEvent = True
With oListBoxToDeselect
For i = 0 To .ListCount - 1
If .Selected(i) Then
.Selected(i) = False
End If
Next
End With
bSkipEvent = False
Set oListBoxToDeselect = Nothing
End Sub
UserForm2
Private Sub CommandButton1_Click()
Debug.Print Me.Name, "CommandButton1_Click() called"
'UserForm1.ListBox1_DeSelect ' No longer used.
Set oListBoxToDeselect = UserForm1.ListBox1 ' [M2] This is required for the DelayedListBoxDeSelect(), if top right [X] is clicked, it won't do DeSelect
Unload Me
End Sub
Private Sub UserForm_Terminate()
Debug.Print Me.Name, "UserForm_Terminate() called"
Application.OnTime Now + TimeSerial(0, 0, 1), "DelayedListBoxDeSelect" ' [M2] Sechedules the Sub named "DelayedListBoxDeSelect" to execute in 1 second.
End Sub
调试输出
我的 Excel VBA 项目中有一个用户表单 (uf1_assess_sched),它有一个列表框 (uf1_listbox3)。
当用户 select 在此列表框中输入单个项目时,将打开第二个用户表单 (group_1),允许用户输入特定于她在 selection 上创建的信息第一个用户表单。如果用户希望放弃在 group_1 上的进一步输入,她可以通过单击名为 Exit 的命令按钮退出。
退出时,group_1被卸载,uf1_assess_sched走在最前面。这个想法是允许用户 select 来自 uf1)listbox3 的另一个项目。然而,她最初制作的 selection 仍然是 selected.
我如何去select这个以前制作的selection.
我试过:
With uf1_assess_sched
.uf1_listbox3.listindex = -1
End With
这是我在所有搜索中找到的最相关的内容。
根据帕特里克的建议,我对 Excel VBA 的理解有限,我是这样解释他的指示的。
With uf1_assess_sched
For i = 0 To .uf1_listbox3.ListCount - 1
If .uf1_listbox3.Selected(i) = True Then
.uf1_listbox3.Selected(i) = False
End If
Next i
End With
遗憾的是,这没有用。代码确实找到了真正的 selection,但该条目仍在列表框中 selected 并且还触发了 uf1_listbox3_Click 事件。
我希望我通过简单地编辑我的原始 post 以适当的方式提供反馈。我不确定如何将代码添加到评论中。 Whosebug 对我来说是一种新格式,所以尽我所能。
使用 Patrick 如此友好地提供的最新代码,我在遇到错误之前设法做到了这一点。我做了一些改编以反映用户表单和列表框名称。我在第二个用户表单 group_1.
中的代码中遇到 "Method or data member not found. " 错误Private Sub exit1_Click()
Dim ui2 As VbMsgBoxResult
Dim lastrow As Long
Dim i As Long
If ws_vh.Range("E2") > 0 Then 'unsaved info
Me.Label34.Caption = " Saving unsaved rental data."
Me.Label34.BorderColor = RGB(50, 205, 50)
lastrow = ws_rd.Cells(ws_rd.Rows.Count, "A").End(xlUp).Row
ws_rd.Range("A3:FZ" & lastrow).Sort key1:=ws_rd.Range("A3"), order1:=xlAscending, Header:=xlNo
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Debug.Print Me.Name, "exit1_Click() called"
uf1_assess_sched.ListBox3_DeSelect '<--- Error with ".Listbox3_DeSelect"
Unload Me
'Unload group_1
'End
Exit Sub
End If
If ws_vh.Range("B2") > 0 Then 'Outstanding rentals?
ui2 = MsgBox("You still have " & ws_vh.Range("C2") & " rentals with critical missing rental information." & Chr(13) & Chr(13) _
& "Active (Sports) rentals: " & ws_vh.Range("B3") & Chr(13) & "Passive (Picnics) rentals: " & ws_vh.Range("B4") & Chr(13) & Chr(13) _
& "Are you sure you wish to exit?", vbInformation + vbYesNo, "OUTSTANDING RENTAL INFORMATION")
If ui2 = vbYes Then
If ws_vh.Range("N4") > 0 Then
Me.Label34.Caption = " Saving unsaved rental data."
Me.Label34.BorderColor = RGB(50, 205, 50)
lastrow = ws_rd.Cells(ws_rd.Rows.Count, "A").End(xlUp).Row
ws_rd.Range("A3:FZ" & lastrow).Sort key1:=ws_rd.Range("A3"), order1:=xlAscending, Header:=xlNo
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Workbooks("Sports15c.xlsm").Activate
mbEvents = False
Debug.Print Me.Name, "exit1_Click() called"
uf1_assess_sched.ListBox3_DeSelect '<--- Error with ".Listbox3_DeSelect"
Unload Me
Exit Sub
Else
Unload Me
End
End If
Else
Exit Sub
End If
End If
Unload group_1
End
End Sub
我确实将 subs ListBox1_DeSelect() 和 ListBoxDeSelect(oListBox As Object) 放在一个单独的模块中(也许这就是问题所在)。
这是代码...
Sub ListBox3_DeSelect()
ListBoxDeSelect Me.uf1_listbox3
End Sub
Private Sub ListBoxDeSelect(oListBox As Object)
Dim i As Long
If TypeName(oListBox) <> "ListBox" Then Exit Sub
bSkipEvent = True
With oListBox
For i = 0 To .ListCount - 1
If .Selected(i) Then
.Selected(i) = False
End If
Next
End With
bSkipEvent = False
End Sub
这是我最近的代码(7 月 19 日)...
USERFORM 1 - uf1_assess_sched(包含用户为其创建 selection 的列表框)
Private Sub uf1_listbox3_Click()
If mbEvents Then Exit Sub
Debug.Print Me.Name, "uf1_listBox3_Click() called"
If bSkipEvent Then Exit Sub
With uf1_listbox3
Debug.Print Me.Name, "uf1_listBox3_Click() ListIndex: " & .ListIndex & " (" & .List(.ListIndex) & ")"
group_1.Show
'UserForm2.TextBox1.Value = .List(.ListIndex) ' This won't have effect if UserForm2 is True on ShowModal
End With
End Sub
USERFORM 2 - group_1(允许用户根据值 select 在 userform1 中输入附加数据。用户可以通过按退出按钮 (exit1) 选择放弃)
Private Sub exit1_Click()
Dim ui2 As VbMsgBoxResult
Dim lastrow As Long
Dim i As Long
If ws_vh.Range("E2") > 0 Then 'unsaved info
Me.Label34.Caption = " Saving unsaved rental data."
Me.Label34.BorderColor = RGB(50, 205, 50)
lastrow = ws_rd.Cells(ws_rd.Rows.Count, "A").End(xlUp).Row
ws_rd.Range("A3:FZ" & lastrow).Sort key1:=ws_rd.Range("A3"), order1:=xlAscending, Header:=xlNo
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Unload group_1
'End
Exit Sub
End If
If ws_vh.Range("B2") > 0 Then 'Outstanding rentals?
ui2 = MsgBox("You still have " & ws_vh.Range("C2") & " rentals with critical missing rental information." & Chr(13) & Chr(13) _
& "Active (Sports) rentals: " & ws_vh.Range("B3") & Chr(13) & "Passive (Picnics) rentals: " & ws_vh.Range("B4") & Chr(13) & Chr(13) _
& "Are you sure you wish to exit?", vbInformation + vbYesNo, "OUTSTANDING RENTAL INFORMATION")
If ui2 = vbYes Then
If ws_vh.Range("N4") > 0 Then
Me.Label34.Caption = " Saving unsaved rental data."
Me.Label34.BorderColor = RGB(50, 205, 50)
lastrow = ws_rd.Cells(ws_rd.Rows.Count, "A").End(xlUp).Row
ws_rd.Range("A3:FZ" & lastrow).Sort key1:=ws_rd.Range("A3"), order1:=xlAscending, Header:=xlNo
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Workbooks("Sports15c.xlsm").Activate
Debug.Print Me.Name, "EXIT1_Click() called"
'UserForm1.ListBox1_DeSelect ' No longer used.
Set oListBoxToDeselect = uf1_assess_sched.uf1_listbox3 ' [M2] This is required for the DelayedListBoxDeSelect(), if top right [X] is clicked, it won't do DeSelect
Unload Me
Else
Unload Me
End
End If
Else
Exit Sub
End If
End If
'If ws_vh.Range("N4") > 0 Then
' MsgBox "Unsaved rental data. Saving."
' lastrow = ws_rd.Cells(ws_rd.Rows.Count, "A").End(xlUp).row
' ws_rd.Range("A3:FZ" & lastrow).Sort key1:=ws_rd.Range("A3"), order1:=xlAscending, Header:=xlNo
' Application.DisplayAlerts = False
' ThisWorkbook.Save
' Application.DisplayAlerts = True
' Unload Me
'Else
' Worksheets("DYNAMIC").Activate
' Unload Me
'End If
'End If
Unload group_1
'Worksheets("DYNAMIC").Activate
End
End Sub
出于测试目的假设 ws_vh.Range("B2") > 0
以及独立辅助模块...
Option Explicit
' Generic ListBox Deselector
Sub ListBoxDeSelect(oListBox As Object)
Dim i As Long
If TypeName(oListBox) <> "ListBox" Then Exit Sub
bSkipEvent = True
With oListBox
For i = 0 To .ListCount - 1
If .Selected(i) Then
.Selected(i) = False
End If
Next
End With
bSkipEvent = False
End Sub
' METHOD 2 [M2] - When UserForm's ShowModal = True
Sub DelayedListBoxDeSelect()
Dim i As Long
If TypeName(oListBoxToDeselect) <> "ListBox" Then Exit Sub
bSkipEvent = True
With oListBoxToDeselect
For i = 0 To .ListCount - 1
If .Selected(i) Then
.Selected(i) = False
End If
Next
End With
bSkipEvent = False
Set oListBoxToDeselect = Nothing
End Sub
group_1 用户表单终止代码
Private Sub UserForm_Terminate()
Debug.Print Me.Name, "UserForm_Terminate() called"
Set oListBoxToDeselect = uf1_assess_sched.uf1_listbox3 ' [M2] This is required for the DelayedListBoxDeSelect(), if top right [X] is clicked, it won't do DeSelect
Application.OnTime Now + TimeSerial(0, 0, 1), "DelayedListBoxDeSelect" ' [M2] Sechedules the Sub named "DelayedListBoxDeSelect" to execute in 1 second.
End Sub
第 2 部分 - 需要 selection 被去除select的替代场景。
If i = 0 Then
MsgBox "Nothing to eliminate."
'--- > Deselect the user selection in uf_assess_sched.uf1_listbox2 < ---
Exit Sub
End If
至少有一种方法可以处理无意的用户窗体控件事件。
由于我不知道您的用户表单如何相互交互,我认为最简单的方法是添加一个 全局布尔变量 以允许您 跳过 需要时的事件,如下所示。
已编辑提示: 我已将全局布尔变量 bSkipEvent
和 Sub ListBoxDeSelect()
取出到普通模块作为代码缩减,并调用扔进 UserForm1.ListBox1
之类的东西。 (确保显示并启用该用户窗体中的列表框,否则添加错误捕获代码)。
当 UserForms ShowModal = True
(TSM) 时,需要一种不同的方法 - 一种方法是安排一个 Sub 被调用以改变另一个 TSM。在这里,我使用 Application.OnTime
将 DelayedListBoxDeSelect 安排在 UserForm2 完全关闭之前的 1 秒。请注意 UserFormHelper 中的额外 Public 对象。希望你明白我在这里做什么。
考虑这两个简单的用户表单:
- 加载 UserForm1 并单击列表框选项之一后:
- 单击 UserForm2 上的命令按钮将焦点带回 UserForm1:
请注意 ListBox1 中的虚线选择,我认为最好保留它作为提醒之前选择了什么。
代码:
UserForm1
Private Sub UserForm_Initialize()
bSkipEvent = False
End Sub
Private Sub ListBox1_Click()
Debug.Print Me.Name, "ListBox1_Click() called"
If bSkipEvent Then Exit Sub
With ListBox1
Debug.Print Me.Name, "ListBox1_Click() ListIndex: " & .ListIndex & " (" & .List(.ListIndex) & ")"
UserForm2.Show
UserForm2.TextBox1.Value = .List(.ListIndex) ' This won't have effect if UserForm2 is True on ShowModal
End With
End Sub
'Sub ListBox1_DeSelect() ' No longer used
' ListBoxDeSelect Me.ListBox1
'End Sub
UserFormsHelper(普通模块)
Public bSkipEvent As Boolean ' This makes accessible to Userforms and other Modules
Public oListBoxToDeselect As Object '[M2] This is for delayed ListBox Deselect method
' Generic ListBox Deselector
Sub ListBoxDeSelect(oListBox As Object)
Dim i As Long
If TypeName(oListBox) <> "ListBox" Then Exit Sub
bSkipEvent = True
With oListBox
For i = 0 To .ListCount - 1
If .Selected(i) Then
.Selected(i) = False
End If
Next
End With
bSkipEvent = False
End Sub
' METHOD 2 [M2] - When UserForm's ShowModal = True
Sub DelayedListBoxDeSelect()
Dim i As Long
If TypeName(oListBoxToDeselect) <> "ListBox" Then Exit Sub
bSkipEvent = True
With oListBoxToDeselect
For i = 0 To .ListCount - 1
If .Selected(i) Then
.Selected(i) = False
End If
Next
End With
bSkipEvent = False
Set oListBoxToDeselect = Nothing
End Sub
UserForm2
Private Sub CommandButton1_Click()
Debug.Print Me.Name, "CommandButton1_Click() called"
'UserForm1.ListBox1_DeSelect ' No longer used.
Set oListBoxToDeselect = UserForm1.ListBox1 ' [M2] This is required for the DelayedListBoxDeSelect(), if top right [X] is clicked, it won't do DeSelect
Unload Me
End Sub
Private Sub UserForm_Terminate()
Debug.Print Me.Name, "UserForm_Terminate() called"
Application.OnTime Now + TimeSerial(0, 0, 1), "DelayedListBoxDeSelect" ' [M2] Sechedules the Sub named "DelayedListBoxDeSelect" to execute in 1 second.
End Sub
调试输出