Access
 sql >> Datenbank >  >> RDS >> Access

Achten Sie darauf, worauf Sie achten

Ich bin neulich auf diese Antwort auf StackOverflow gestoßen und wollte darauf aufmerksam machen (Hervorhebung von mir):

Ich hatte dieses Problem beim Debuggen, als ich eine Uhr hatte, die versuchte, das Element des "fehlenden" Schlüssels zurückzugeben . Tatsächlich hatte weiteres frustriertes Debuggen das gleiche Problem, als ich buchstäblich nach [scriptingdictonaryObject].exists() condtional) Ausschau hielt; Ich schlage vor, dass der "fehlende" Schlüssel wegen der Uhr hinzugefügt wird . Als ich die Uhr entfernte und stattdessen ein temporäres Arbeitsblatt erstellte, um das Array während der Ausführung zu kopieren, wurden die unerwünschten Schlüssel nicht mehr hinzugefügt.
Dictionary-Objekt, das Elemente hinzufügt, bevor .add() aufgerufen wirdIch verwende ein Dictionary-Objekt aus der MS Scripting Runtime-Bibliothek, um eine Reihe von Arrays zu speichern und bei Bedarf Operationen an den Array-Zellen auszuführen. Es gibt eine for-Schleife, um den Prozess zu durchlaufen ... Stack Overflowriddley_w

Was ist hier los?

Eine der "Eigenschaften" eines Dictionary-Objekts ist, dass es implizit wird Erstellen Sie neue Elemente, ohne die .Add-Methode explizit aufrufen zu müssen . Was ist der Unterschied zwischen implizit und explizit?

Hinweis:Die Verwendung des Dictionary-Objekts mit früher Bindung erfordert einen Verweis auf die "Microsoft Scripting Runtime" (Details hier).

Dim MyDict As New Dictionary

'Explicit add
MyDict.Add "KeyA", "Item A"

'Implicit add
MyDict.Item("KeyB") = "Item B"

Debug.Print MyDict("KeyA"); vbNewLine; MyDict("KeyB")

Hier ist der relevante Teil der Dokumentation bezüglich implizit Schlüsselerstellung:

Bemerkungen
Wenn Schlüssel wird beim Ändern eines Elements nicht gefunden , ein neuer Schlüssel wird mit dem angegebenen newitem erstellt . Wenn Schlüssel nicht gefunden wird, wenn versucht wird, ein vorhandenes Element zurückzugeben, ein neuer Schlüssel erstellt und das entsprechende Element leer gelassen wird.

Reproduktion des Problems

Lassen Sie uns das Problem reproduzieren, um genau zu sehen, wo es seitwärts geht.

Erwartetes Verhalten

Erstellen Sie die folgende Beispielroutine:

Sub WatchOut()
    Dim MyDict As Dictionary
    Set MyDict = New Dictionary
    
    Debug.Print "KeyA exists? "; MyDict.Exists("KeyA")
End Sub

Führen Sie die obige Routine aus dem unmittelbaren Fenster aus und sie sollte False zurückgeben:

WatchOut
KeyA exists? False

Uhr hinzufügen

Lassen Sie uns nun eine Überwachung des Elements „KeyA“ hinzufügen:

Lassen Sie uns versuchen, WatchOut auszuführen Routine wieder:

WatchOut
KeyA exists? False

So weit, ist es gut. Vielleicht ist das doch kein Problem.

Schrittweise durch den Code

Lassen Sie uns einen Halt hinzufügen -Anweisung, um den Code zu brechen:

Sub WatchOut()
    Dim MyDict As Dictionary
    Set MyDict = New Dictionary
    
    Stop
    Debug.Print "KeyA exists? "; MyDict.Exists("KeyA")
End Sub

Lassen Sie uns nun versuchen, WatchOut auszuführen Routine:

WatchOut
KeyA exists? True

Aha! Die Kombination aus der Überwachung und dem Einbruch in den Debugger reicht aus, um das Auftreten des "Fehlers" zu erzwingen. Ich habe Bug gesetzt in erschreckenden Anführungszeichen, weil es eigentlich das erwartete Verhalten für den Debugger ist. Aber es ist mit ziemlicher Sicherheit ein unerwartetes Verhalten für den Entwickler.

(Beachten Sie, dass der Stopp nichts Besonderes ist Befehl, der dieses Verhalten verursacht. Sie können den Stopp entfernen Zeile und setzen Sie einen Haltepunkt auf den Code und das gleiche Verhalten tritt auf.)

Sie können sehen, wo solche Dinge dazu führen können, dass Sie sich beim Debuggen die Haare ausreißen. Jedes Mal, wenn sich das Verhalten Ihres Programms während der normalen Ausführung von dem während des Debuggens unterscheidet, haben Sie das Zeug zu einer ärgerlichen Debugging-Sitzung.

Zusammenfassung

Schritte zum Reproduzieren des Problems:

  1. Erstellen Sie eine Überwachung für ein bestimmtes Wörterbuchelement
  2. In den Debugger einbrechen, während der Code ausgeführt wird

Dies wird wahrscheinlich immer nur einem oder zwei Entwicklern helfen. Aber es wird diesen Entwicklern möglicherweise Stunden sparen von Frust. Und wenn ich ehrlich bin, bin ich wahrscheinlich einer dieser Entwickler;-).