我试图找出一对ActiveX多选列表框的问题。
出于某种原因,一切似乎都能正常工作,除非我从"摘要"的第二个框中运行它。片材。
简而言之,使用调试器的断点运行第二个框的MouseUp
事件代码。只是在没有断点的情况下触发事件将使一切正常,但是在一两秒之后,选择将被清除。
我可以确认,从那时起重新运行代码以恢复选择将正常工作。此时的所有其他行为都按预期工作。只有当MouseUp
事件被触发(没有断点)时,它才会导致某些事件清除选择。 (我现在相信这是重新启用事件后的工作表计算...虽然我认为这也会在调试中发生...)
更新1:在设置EnableEvents
为true后,我找到了与存储选择的工作表相关的解决方法。因此我插入了Sheet(...).Calculate
,如下所示,现在按预期工作。这种行为似乎很奇怪,所以我想看看是否有其他人遇到过这样的事情。为什么即使在禁用事件时进行了更改,工作表也会重新计算?由于某些原因,暂时禁用计算似乎也没有做到,尽管我没有花太多时间来测试这个想法(它似乎创造了比修复更多的问题)。
这个问题与我原先的想法不同。我发现它与同步无关,实际上与列表框在不同的工作表上有关。两者都指的是动态范围(我忘了提及),这实际上与动态范围重新计算的方式有关(从而重置列表框)。最初,当我有一个盒子时,我通过不传递命名范围的盒子来解决这个问题,但是每次因为导入数据而更新范围的地址(或者使用就地控制进行调整)。
此框与动态范围位于同一页面上,而另一个则不是,这意味着我无法传递地址(ActiveX控件不会在" Linked Cell&#34中使用工作表引用;),所以我决定提到指定的范围。这再次引入了我所见过的问题,在这个问题出现之前,我的许多解决方法都处理了其他症状。
我能够通过制造另一个“停滞不前”来解决这个问题。命名范围,当我的其他宏更新时,我会更新引用以指向原始命名范围,从而阻止它重新计算(并重置我的列表框)。希望这对某人有帮助。
box1:LegSections2Check
Private Sub LegSections2Check_MouseUp(ByVal Button As Integer, _
ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Application.EnableEvents = False
Application.ScreenUpdating = False
Call SyncChoices(Sheets("Loads"))
Retain_Selections SetUp:=True
Retain_Selections SetUp:=False
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
box2:LegSections2Check2
Private Sub LegSections2Check2_MouseUp(ByVal Button As Integer, _
ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Application.EnableEvents = False
Application.ScreenUpdating = False
Call SyncChoices(Sheets("Summary"))
Retain_Selections SetUp:=True
'Sheets("Loads").Calculate '*** This seems to resolve the issue, although _
' I can't seem to resolve it by setting_
' Application.Calculation to manual in the functions _
' (this actually broke more things, haha)
Retain_Selections SetUp:=False
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
SyncChoices(检测编辑框所在的工作表并更新另一个框):
Sub SyncChoices(ByVal mySheet As Worksheet)
Dim i As Integer
If mySheet.Name = "Loads" Then
With ActiveWorkbook.Sheets("Loads").LegSections2Check
For i = 0 To .ListCount - 1
If .Selected(i) Then
ActiveWorkbook.Sheets("Summary").LegSections2Check2.Selected(i) = True
ElseIf Not .Selected(i) Then
ActiveWorkbook.Sheets("Summary").LegSections2Check2.Selected(i) = False
End If
Next
End With
ElseIf mySheet.Name = "Summary" Then
With ActiveWorkbook.Sheets("Summary").LegSections2Check2
For i = 0 To .ListCount - 1
If .Selected(i) Then
ActiveWorkbook.Sheets("Loads").LegSections2Check.Selected(i) = True
ElseIf Not .Selected(i) Then
ActiveWorkbook.Sheets("Loads").LegSections2Check.Selected(i) = False
End If
Next
End With
End If
End Sub
Retain_Selections功能:
Sub Retain_Selections(ByVal SetUp As Boolean)
'Dim myListBox As ListBox
Dim i As Integer
Dim MyVals As String
Dim Selections() As String
Dim offset As Integer
Dim myCount As Integer
With ActiveWorkbook.Sheets("Loads").LegSections2Check
RefColumn = ActiveWorkbook.Sheets("Loads").Range("RefCol").Column
If SetUp Then
ActiveWorkbook.Sheets("Loads").Cells(2, RefColumn).Value = GetSelections()
Else
Selections = Split(ActiveWorkbook.Sheets("Loads").Cells(2, RefColumn).Value, ", ")
ClearSelectedSections
myCount = .ListCount
ActiveWorkbook.Sheets("Summary").LegSections2Check2.ListFillRange = "LegsSections"
If UBound(Selections) > 0 Then If Selections(UBound(Selections)) * 1 > myCount - 1 Then offset = 1: ExtraRow = True
For i = 0 To UBound(Selections) - offset
.Selected(Selections(i)) = True
ActiveWorkbook.Sheets("Summary").LegSections2Check2.Selected(Selections(i)) = True
Next i
End If
End With
GetSelections()函数:
Function GetSelections()
Dim i As Integer
Dim MyVals As String
With ActiveWorkbook.Sheets("Loads").LegSections2Check
For i = 0 To .ListCount - 1
If .Selected(i) = True Then
If MyVals = "" Then
MyVals = i
Else
MyVals = MyVals & ", " & i
End If
End If
Next i
End With
GetSelections = MyVals
End Function
表格的代码' WorkSheet_Activate
:
"载荷和#34;
Private Sub Worksheet_Activate()
Retain_Selections Setup:=False
End Sub
"总结"
Sub Worksheet_Activate()
Retain_Selections Setup:=False
End Sub
答案 0 :(得分:0)
禁用事件时,不会关闭自动计算。 Excel引用单独的工作簿 - 全局属性来确定工作簿是否需要重新计算。所以你必须自己禁用/启用autocalc。
所以,有两件事:
除了暂时禁用事件外,我的“标准”实用程序功能还可选择将AutoCalc设置为手动Application.Calculation = xlManual
,以确保在允许计算之前完成所有宏。
此外,如果您的列表框位于不同的工作表上,则在用户激活该工作表之前,没有理由重新填充非活动工作表上的列表框。在这种情况下,当用户选择该表时,我会在每张表上使用Worksheet_Activate()
事件来填充列表框。
第二件事的推论:如果您的代码依赖于列表框中的项目列表作为部分代码中使用的“过滤器”,请考虑创建一个命名范围作为填充每个列表框的数据。此方法意味着您只更新工作表上的单元格区域,并且列表框在激活时会自动选择它。