Excel VBA – ActiveX列表框行为 – 正在清除select

我想找出一对ActiveX多选列表框的问题。

  1. 这些列表框位于不同的工作表上,但我已经设置为在两者之间同步鼠标上的值。
  2. 这些调用一个函数来同步这两个,然后更新一个单元格以保留select。
  3. 由于写入表单导致Excel计算,因此我必须恢复这些select。

出于某种原因,除了当我从“摘要”工作表的第二个框中运行时,一切似乎都正常工作。

简而言之,使用debugging器的断点运行第二个盒子的MouseUp事件代码工作。 只要触发事件而没有断点,一切都会奏效,但是在一两秒之后,select就会清除。

我可以确认,重新运行代码以恢复select将从此正常工作。 所有其他行为在这个时候按预期工作。 只有当MouseUp事件被触发(没有断点)时,它似乎会导致一些清除select的事件。 (我现在认为这是重新启用事件之后的表格计算…虽然我认为这也会发生在debugging过程中…)


更新1:在将EnableEvents设置为true之后,我find了一个解决scheme,该工作区与存储选定内容的表格相关。 因此,我已经插入Sheet(...).Calculate如下所示,事情现在按预期工作。 这种行为似乎很奇怪,所以我想看看是否有其他人遇到过这样的事情。 为什么即使在事件被禁用时进行了更改,工作表也会重新计算? 由于某种原因,暂时禁用计算似乎也没有做到这一点,尽pipe我没有花太多时间来testing这个想法(它似乎创造了更多的问题,而不是固定的)。


更新和解决scheme:

这个问题结果与我原先想象的不同。 我发现它与同步无关,实际上与列表框位于不同的页面上有关。 两者都指的是一个dynamic范围 (我忘了提及),这实际上是关于dynamic范围重新计算(从而重置列表框)。 最初当我有一个盒子时,我通过不通过命名范围的盒子来解决这个问题,但是每次由于导入数据(或者就地控制器调整)来更新范围的地址。

这个盒子与dynamic范围在同一页面,而另一个不在,这意味着我不能传递地址(ActiveX控件不会在“链接单元格”中使用表单引用),所以我已经解决了指向命名的范围。 这又重新提出了我所看到的问题,在这个问题出现之前,我的许多解决方法都处理了其他症状。

我能够通过创build另一个“停滞”的命名范围来解决这个问题,我将更新引用来指向原来的命名范围,当它被我的其他macros更新,从而阻止它重新计算(和重置我的列表框)。 希望这对某人有帮助。


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_Selectionsfunction:

 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

“负载”

 Private Sub Worksheet_Activate() Retain_Selections Setup:=False End Sub 

“概要”

 Sub Worksheet_Activate() Retain_Selections Setup:=False End Sub 

当您禁用事件时,自动计算没有closures。 Excel引用单独的工作簿全局属性来确定工作簿是否需要重新计算。 所以你必须自己禁用/启用autocalc。

所以,有两件事情:

除了暂时禁用事件之外,我的“标准”实用程序function还可以将Application.Calculation = xlManual设置为手动Application.Calculation = xlManual ,只是为了在允许计算前确保所有的macros都完成。

此外,如果您的列表框位于不同的工作表上,则无需重新填充非活动工作表上的列表框,直到用户使该工作表处于活动状态。 在这种情况下,我将使用每个Worksheet_Activate()上的Worksheet_Activate()事件来填充列表框,当用户select该工作表时。

推论第二件事:如果代码依赖列表框中的项目列表作为代码中部分代码使用的“filter”,请考虑创build一个命名范围作为填充每个列表框的数据。 这种方法意味着你只更新工作表上的单元格区域,列表框在激活时自动select它。