2017-08-28 1 views
0

J'ai développé les deux sous-marins suivants qui créent et suppriment une collection de cases à cocher à côté d'un objet de liste. Chaque ID distinct dans l'objet listObject reçoit une case à cocher. Comme ceci je peux approuver les entrées de listobject.Pourquoi les variables publiques sont-elles perdues après une erreur?

Le code est le follwing:

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 

Tout cela fonctionne assez bien. Pas de doubles cases à cocher et pas d'erreurs s'il n'y a pas de cases à cocher. Je suis en train de développer un système d'approbation pour développer et tester d'autres modules. Si je cours maintenant ce sous:

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

i = 1 
Set Im = i 
End Sub 

Il me donnera une erreur. Si j'essaie alors d'exécuter un de mes sous-cases à cocher, ils ne fonctionneront plus correctement. La collection est supprimée par l'erreur et je ne suis plus en mesure d'accéder aux collections. Pourquoi cela arrive-t-il et suis-je capable de contrer cet autre, ne causant pas d'erreurs? Y a-t-il une meilleure façon de mettre en œuvre un tel système, la perte de collections n'est pas un problème?

+0

qui est juste un comportement normal comment fonctionne VBA. Si vous arrêtez (pas en pause) l'exécution du code (par exemple en raison d'une exemption), toutes les variables sont effacées. Si vous devez enregistrer des données, vous devez les placer dans une feuille de calcul, que vous pouvez lire à l'initialisation si vous redémarrez votre code. De même, une gestion correcte des erreurs empêchera la fin de votre code. –

+0

Toutes les variables sont perdues lorsque le programme se termine, un moyen est par des erreurs. Lisez à propos de la gestion des erreurs. Quelques mots d'intérêt sont repris reprendre CV, etc – cyboashu

+0

Vous devriez changer votre code Vba de cette façon, il va charger les variables globales chaque fois que vous exécutez le code. Ne vous attendez jamais à ce que Vba conserve les variables globales à l'heure idel, et à cause de l'erreur, toutes les variables seront effacées lors du passage à l'heure idel. – Rolfi

Répondre

1

Vous pouvez envelopper l'objet de collection dans une propriété et le laisser gérer la création d'objets:

Private mCollection As Collection 

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

Pour l'appeler:

TheCollection.Count 
+0

Bon à savoir! Après toutes les personnes qui m'ont dit que ce n'est pas possible finalement une solution. J'ai déjà pensé à utiliser la collection OLEObjects de la feuille de calcul et à m'assurer manuellement que seuls les bons objets sont supprimés. Je vous remercie! –

0

Essayez On Error Resume Next avant la ligne qui provoque l'erreur. Il passera le problème et vos vairables seront toujours disponibles. Cependant, cela ne résoudra pas votre erreur. Essayez de créer une feuille cachée séparée dans votre classeur pour stocker vos variables globales afin qu'elles ne disparaissent pas. p.ex .:

Private Sub CreateSheet() 
    Dim ws As Worksheet 
    With ThisWorkbook 
     Set ws = .Sheets.Add(After:=.Sheets(.Sheets.Count)) 
     ws.Name = "Global" 
     .Worksheets("Global").Visible = False 
    End With 
End Sub