Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 为什么公共变量在发生错误后丢失?_Vba_Excel_Checkbox_Collections - Fatal编程技术网

Vba 为什么公共变量在发生错误后丢失?

Vba 为什么公共变量在发生错误后丢失?,vba,excel,checkbox,collections,Vba,Excel,Checkbox,Collections,我开发了以下两个sub,它们创建和删除listobject旁边的复选框集合。listobject中的每个不同ID都会得到一个复选框。这样我就可以批准listobject条目 代码如下: Public CBcollection As Collection Public CTRLcollection As Collection Sub create_chbx() If Approval.CBcollection Is Nothing Then Dim i As Integer Dim tbl As

我开发了以下两个sub,它们创建和删除listobject旁边的复选框集合。listobject中的每个不同ID都会得到一个复选框。这样我就可以批准listobject条目

代码如下:

Public CBcollection As Collection
Public CTRLcollection As Collection

Sub create_chbx()
If Approval.CBcollection Is Nothing Then
Dim i As Integer
Dim tbl As ListObject
Dim CTRL As Excel.OLEObject
Dim CB As MSForms.CheckBox
Dim sht As Worksheet
Dim L As Double, T As Double, H As Double, W As Double
Dim rng As Range
Dim ID As Long, oldID As Long

Set CBcollection = New Collection
Set CTRLcollection = New Collection
Set sht = ActiveSheet
Set tbl = sht.ListObjects("ApprovalTBL")
Set rng = tbl.Range(2, 1).Offset(0, -1)
      W = 10
      H = 10
      L = rng.Left + rng.Width / 2 - W / 2
      T = rng.Top + rng.Height / 2 - H / 2

For i = 1 To tbl.ListRows.count
      ID = tbl.Range(i + 1, 1).Value
      If Not (ID = oldID) Then
            Set CTRL = sht.OLEObjects.Add(ClassType:="Forms.CheckBox.1", Link:=False, DisplayAsIcon:=False, Left:=L, Top:=T, Width:=W, Height:=H)
            Set CB = CTRL.Object
            CBcollection.Add Item:=CB
            CTRLcollection.Add Item:=CTRL
      End If

      Set rng = rng.Offset(1, 0)
      T = rng.Top + rng.Height / 2 - H / 2
      oldID = ID
Next i
End If
End Sub


Sub remove_chbx()
If Not Approval.CBcollection Is Nothing Then
With Approval.CBcollection ' Approval is the module name
      While .count > 0
            .Remove (.count)
      Wend
End With
With Approval.CTRLcollection
      While .count > 0
            .Item(.count).Delete
            .Remove (.count)
      Wend
End With
Set Approval.CBcollection = Nothing
Set Approval.CTRLcollection = Nothing
End If
End Sub
这一切都很有效。没有双重复选框,如果没有复选框,则没有错误。如果我需要开发和测试其他模块,我正在开发一个批准方案。如果我现在运行此sub:

Sub IdoStupidStuff()
Dim i As Integer
Dim Im As Image

i = 1
Set Im = i
End Sub

这会给我一个错误。如果我尝试运行我的一个复选框sub,它们将不再正常工作。该集合已被错误删除,我无法再访问该集合。为什么会发生这种情况?我是否能够反作用于此,而不是造成错误?如果不存在收集丢失的问题,是否有更好的方法来实现这样一个系统?

尝试在出错时继续下一步在导致错误的行之前。它将跳过这个问题,你的虚幻仍然可用。 然而,这并不能解决您的错误。尝试在工作簿中创建一个单独的隐藏表来存储全局变量,这样它们就不会丢失。 f、 例:


您可以将集合对象包装在属性中,并让它处理对象创建:

Private mCollection As Collection

Public Property Get TheCollection() As Collection
    If mCollection Is Nothing Then Set mCollection = New Collection
    Set TheCollection = mCollection
End Property
称之为:

TheCollection.Count

这只是VBA的正常工作方式。如果您停止(而不是暂停)代码的执行(例如,由于豁免),那么所有变量都将被清除。如果需要保存数据,则需要将其放入工作表中,如果重新启动代码,则可以在初始化时读取该工作表。此外,正确的错误处理将防止代码被终止。当程序终止时,所有变量都将丢失,一种方法是通过错误。阅读有关错误处理的信息。下面几个有趣的词是resume next等。您应该以这种方式更改Vba代码,它将在每次运行代码时加载全局变量。千万不要指望Vba会在idel时间保留全局变量,由于错误,它会在转到idel时间时清除所有变量。@Rolfi和@peh:那会是什么样子?我在工作表中输入公共变量初始化是否全部?是将所有持久值放入工作表中,并在每次运行代码之前读取它们。您可以检查您的公共变量是否为空,如果为空,请从工作表中读取,否则请使用该变量。有很多方法取决于你如何实现它。很高兴知道!毕竟所有的人都告诉我,这是不可能最终解决的。我已经考虑过使用工作表的OLEObjects集合并手动确保只删除正确的对象。非常感谢。尝试使用这种有趣的方法时,我发现只有使用模块才能访问它。我已经把它放在MSAccessVBA代码中的FormonLoad事件中。但试图从任何其他模块调用它,我得到“变量未定义”。很遗憾,这是一个非常漂亮的解决方案…@Smok表单的代码隐藏文件是用于处理控制事件的表单的私有文件,因此无法访问。如果您想要应用程序范围的访问,您必须将其放在标准模块中。然后可以使用
模块名称访问它。收藏
。很棒的提示!而且,似乎没有必要使用模块名!看起来使用集合调用它就足够了。这对我来说已经足够了。您使用我的配置模块为我节省了很多时间。@Smok确实没有必要,但它可以帮助您找到属性/方法所在的模块。此外,如果您有两个同名的属性/方法(当然是在不同的模块中),则需要模块名称来解决冲突。
TheCollection.Count