VBA(Excel)ActiveX ListBox更改事件递归行为

use*_*265 5 excel vba listbox

我不是VBA程序员,所以如果我在这个问题上的一些术语不正确,我会提前道歉.我的一位同事希望在选择后立即从列表框中清除选择.经过一些谷歌搜索,我们发现一种方法是通过Change事件.最初我们尝试过:

Private Sub ListBox1_Change()
    For i = 0 To ListBox1.ListCount - 1
        ListBox1.Selected(i) = False
    Next i
End Sub
Run Code Online (Sandbox Code Playgroud)

但是,似乎将Selected属性设置为False会在列表框中触发Change事件,这实际上会成为无限循环并导致Excel(2007)崩溃.鉴于我们知道有两个条目我们也尝试过:

Private Sub ListBox1_Change()
    ListBox1.Selected(0) = False
    ListBox1.Selected(1) = False
End Sub
Run Code Online (Sandbox Code Playgroud)

这有效!虽然我们期望相同的行为 - 对于Selected属性的设置会导致Change事件再次触发并获得无限循环.

然而,似乎一旦例如ListBox1.Selected(0)= False,重新触发了Change事件,但是在那次迭代中它没有重新触发这一行 - 我猜是因为它知道这个Selected属性已被设置为False对于这个项目,所以没有任何变化.

但如果是这种情况,那么我们也会在第一个解决方案中期望这种行为.所以看起来ListBox1.Selected(i)= False与直接指定实际项目索引(而不是通过变量)之间存在一些差异i).

有谁知道这种行为的原因?希望这个问题有意义,我试图尽可能地解释它.

谢谢阿米特

gNe*_*erb 0

将循环附加到单击事件而不是更改事件以停止无限循环:

Private Sub ListBox1_Click()
'Do the stuff you want to do based on the selection

'Clear selections
For i = 0 To ListBox1.ListCount - 1
    ListBox1.Selected(i) = False
Next i
End Sub
Run Code Online (Sandbox Code Playgroud)

我不认为这个问题的“为什么”有一个简单的答案。一般来说,Word 是非常线性的,一次只能处理一件事。然而,现代处理器可以优化代码并同时运行。Word 会以足够可预测的方式产生混淆,从而为混淆提供相对一致的解决方法。您上面提到的技巧(执行两次)是处理此问题的一种流行方法(当我遇到与列表框相同的问题时,我看到了很多建议)。

我更喜欢增强逻辑,而不是尝试草率的解决办法。如上所述,我只是意识到更改事件不是正确使用的事件,而不是关闭事件或使用双重技巧。