2017-02-01 9 views
1

Ich bin neu in VBA, also könnte ich etwas verpasst haben.VBA: Verwenden eines Wörterbuchs außerhalb eines Benutzerformulars

Ich fülle ein Wörterbuch DicOption in einem Sub aus einem Modul. Dies ist die sub:

Public Sub ExchangeToDicOption() 

Static DicOption As Object 
Dim LR As Long 
Dim Rg As Range 
Dim ws As Worksheet 
Dim i As Long 
Set ws = ActiveWorkbook.Worksheets(2) 
Set Rg = ws.Columns(2) 

If Not DicOption Is Nothing Then 
    DicOption.RemoveAll 
End If 


    LR = Rg.Find(What:="*", Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _ 
     SearchDirection:=xlPrevious, MatchCase:=False).Row 

    Set DicOption = CreateObject("Scripting.Dictionary") 

    If LR > 1 Then 
     For i = 2 To LR 
      DicOption.Add key:=Cells(i, 1).Value, Item:=Cells(i, 2).Value 
     Next i 
    End If 

End Sub 

Aber das Wörterbuch scheint sich zu leeren, wenn es seine process.I endet am die Unter ExchangeToDicOption in UserForm_Initialize aufrufen. Creation_step ist ein Schlüssel in DicOption.

Private Sub UserForm_Initialize() 
Dim control As control 
Dim opt As String 

Call ExchangeToDicOption 

opt = DicOption(Creation_step) 
With UBidStatus 
    Select Case opt 
     Case Is > 0 
      For Each control In UBidStatus.Controls 
       control.Enabled = False 
      Next control 
      With UBidStatus 
       .Image4.Enabled = True 
       .LProject.Enabled = True 
       .LClient.Enabled = True 
       .Label6.Enabled = True 
       .Label7.Enabled = True 
       .IProjectinfoNOK.Enabled = True 
       .IProjectinfoOK.Enabled = True 
       .LProjectinfo.Enabled = True 
       .CBProjectinfo.Enabled = True 
       .IProjectinfoNOK.Visible = True 
       .IProjectinfoOK.Visible = False 
      End With 
ect.... 

Ich habe auch versucht Public DicOption as Object als globalen Variable zu verwenden (vor allem meiner subs in Fenster-Modul bearbeiten), aber es hat nicht funktioniert. Vielen Dank für Ihre Hilfe !!

+0

Ich hatte zuvor auf diesen Thread verweisen, um mir zu helfen, meinen Code http://stackoverflow.com/questions/22382729/setting-a-global-scripting-dictionary-invisual-basic-for-applications-vba – Gab

+1

zu vervollständigen Sie sollten wahrscheinlich die Goto Fill, Else und Fill-Label entfernen ... und verschieben Sie das Ende If bis zu wo Sie die Else haben. Es ist schlechte Form, einen Teil von If Goto den anderen Teil zu haben. Macht logisch keinen Sinn. Das wird dein Problem nicht lösen, es ist einfach keine gute Programmierung. – Rdster

+0

Danke für deinen Kommentar @Rdster, ich dachte auch, dass es komisch ist, aber ich denke, dass ich mich mehr auf das Wörterbuchproblem konzentrierte. Ich werde Ihren Rat annehmen und diesen Code ändern. – Gab

Antwort

2
Public Sub ExchangeToDicOption() 

Static DicOption As Object 

Das DicOption Objektvariable ist in lokalen Bereich - es existiert nur immer innerhalb des ExchangeToDicOption Verfahrens.

Diese Zeile in UserForm_Initialize:

opt = DicOption(Creation_step) 

Sieht aus wie es eine Variable in einem anderen Umfang erklärt zuzugreifen versucht. Es kann nicht.

Geben Sie Option Explicit an der Oberseite Ihrer Module an; Diese Form hört auf zu kompilieren. Oder wenn es gibt einen anderen DicOption Variable in Modul-Rahmen (auf der Oberseite des Moduls erklärt, über die Verfahren), dann die DicOption, die ExchangeToDicOption lokale Zeit sind versteckt es (VBA löst Anrufe DicOption auf die lokale Erklärung, nicht die Modulebene). Entfernen Sie die Static DicOption As Object Deklaration.

Da Sie über zwei Prozeduren verfügen, die auf dasselbe Objekt zugreifen müssen, müssen Sie dieses Objekt auf Modulebene deklarieren.

Option Explicit 
Private DicOption As Object 

Private Sub UserForm_Initialize() 
    Set DicOption = CreateObject("Scripting.Dictionary") 
End Sub 

Private Sub UserForm_Terminate() 
    Set DicOption = Nothing 
End Sub 

Public Sub ExchangeToDicOption() 
    DicOption.RemoveAll 
    LR = Rg.Find(What:="*", Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _ 
     SearchDirection:=xlPrevious, MatchCase:=False).Row 

    If LR > 1 Then 
     For i = 2 To LR 
      DicOption.Add key:=Cells(i, 1).Value, Item:=Cells(i, 2).Value 
     Next i 
    End If 
End Sub 

nun nicht sicher, warum Sie zu einer Bibliothek späte Bindung, die seit 1998 auf jedem Windows-Box Standard installiert ist ... aber das ist ein anderes Thema.

Indem Sie die Instanz in UserForm_Initialize initialisieren und sie in UserForm_Terminate löschen, stellen Sie sicher, dass für die gesamte Lebensdauer der Objektinstanz UserForm ein Objektverweis ungleich null vorhanden ist.

+0

Vielen Dank @ Mat's Mug, ich muss zugeben, dass ich mehr über Objekteigenschaften und Instanz ans lernen muss. Ich werde Ihre Abschlussmethode in meinen Code aufnehmen.Was das Wörterbuch betrifft, verwendete ich die späte Bindung, weil ich las, dass es robuster für Multi-User-Zwecke war. – Gab

+1

Late Binding lädt die letzte installierte Version einer gegebenen Bibliothek, wenn Sie also frühzeitig an * SomeRandomLibrary v2.4 * und * binden Wenn ein Benutzer v2.6 installiert hat, schlägt die Bindung fehl, da die frühe Bindung versionsspezifisch ist. Die Skriptbibliothek hat in diesem Jahrhundert jedoch kein Update erhalten und wird wahrscheinlich auch keins bekommen. –

+0

Auch, sollte ich "Public Dicto Option als Objekt" anstelle von "Private DicOption als Objekt" machen, damit es für andere Formen/Subs zur Verfügung steht? Muss ich in jeder Form, die DicOption verwendet, initialisieren und beenden? Oder suggest du, dass initialisieren und beenden in meinem allgemeinen Modul und nicht in meinem Modul "Form" geht? Vielen Dank im Voraus – Gab

Verwandte Themen