我有一个UserForm
,如果用户输入不正确,则会调用以下过程,该过程将突出显示该字段并禁用“保存更改”按钮。
Private disabledElems As New Collection
Private Sub disable(ByRef controlName As String)
UserForm1.Controls(controlName).BackColor = &H8080FF
Me.save_button.Enabled = False
Dim i As Byte
If disabledElems.Count <> 0 Then
For i = 1 To disabledElems.Count
If disabledElems(i) = controlName Then
Exit Sub ' we dont want to add duplicates to collection
End If
Next i
End If
disabledElems.Add controlName ' otherwise add to collection
End Sub
如果输入正确,它将调用enable
过程,如下所示:
Private Sub enable(ByRef controlName As String)
Me.Controls(controlName).BackColor = &H80000005
Dim i As Byte
For i = 1 To disabledElems.Count
If disabledElems(i) = controlName Then
disabledElems.Remove i ' remove the enabled element upon match
End If
Next i
If disabledElems.Count = 0 Then
save_button.Enabled = True
End If
End Sub
当我尝试使用一个
时,这似乎很好用Textbox
但是,一旦我有多个不正确的条目,我的enable
过程似乎就毫无理由地抛出了 Subscript out of range error
。>
调试器中突出显示的行是:
If disabledElems(i) = controlName Then
我不明白是什么原因造成的。有什么想法吗?
答案 0 :(得分:1)
好的,这是那些经典的”之一,当删除一行时,循环 从头到尾”
基本上,抛出 Subscript out of range
的原因-一旦通过
disabledElems.Remove i
将Collection
的大小从Collection.Count
减小到Collection.Count - 1
,但是在for
循环声明期间,i
已经很困难了-设置到前一个Collection.Count
在一个实际示例中:
假设我的Collection
看起来像这样
disabledElems = "button1", "button2"
执行此操作
controlName = "button1"
For i = 1 to disabledElems.Count ' <= 2
If disabledElems(i) = controlName ' < True for i = 1
disabledElems.Remove i ' < button1 was removed from collection, however it still loops
End If
' will loop to i = 2. However disabledElems(2) no longer exists, because upon removal _
the button2 was shifted to disabledElems(1) - hence Subscript out of range
Next i
一个试图访问元素的明确案例,该元素在队列中的位置已经改变。
有两种可能的修复方法(我能想到):
1。删除后强制执行Exit Sub
For i = 1 to disabledElems.Count
If disabledElems(i) = controlName
disabledElems.Remove i
Exit Sub
End If
Next i
2。从头到尾循环
Dim i as Integer ' needs to be redeclared to int, because Byte can't -1
For i = disabledElems.Count to 1 Step -1
If disabledElems(i) = controlName
disabledElems.Remove i
End If
Next i