sql >> Database teknologi >  >> RDS >> Access

Pas på, hvad du holder øje med

Jeg stødte på dette svar på StackOverflow den anden dag og ville gerne gøre opmærksom på det (min fremhævelse):

Jeg havde dette problem manifest under fejlfinding, da jeg havde et ur, der forsøgte at returnere den "manglende" nøgles element . Faktisk havde yderligere frustreret debugging det samme problem, da jeg bogstaveligt talt havde vagt for [scriptingdictonaryObject].exists() condtional); Jeg foreslår, at den "manglende" nøgle tilføjes på grund af uret . Da jeg fjernede uret og i stedet oprettede et midlertidigt regneark at kopiere arrayet til, mens jeg kørte, blev de uønskede nøgler ikke længere tilføjet.
Ordbogsobjekt, der tilføjer elementer før .add() kaldes.Jeg bruger et ordbogsobjekt fra MS Scripting Runtime-biblioteket til at gemme en række arrays og udføre operationer på arraycellerne efter behov. Der er en for-løkke til at gå gennem processen... Stack Overflowriddley_w

Hvad sker der her?

En af "funktionerne" ved et ordbogsobjekt er, at det vil implicit oprette nye elementer uden at skulle kalde .Add-metoden eksplicit . Hvad er forskellen mellem implicit og eksplicit?

Bemærk:Tidlig bundet brug af Dictionary-objektet kræver en reference til "Microsoft Scripting Runtime" (detaljer her).

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")

Her er den relevante del af dokumentationen vedrørende implicit nøgleoprettelse:

Bemærkninger
Hvis nøgle findes ikke, når du ændrer et element , en ny nøgle er oprettet med det angivne newitem . Hvis nøgle er ikke fundet, når du forsøger at returnere en eksisterende vare, en ny nøgle oprettes, og dets tilsvarende element efterlades tomt.

Gengivelse af problemet

Lad os reproducere problemet for at se præcis, hvor tingene går sidelæns.

Forventet adfærd

Opret følgende eksempelrutine:

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

Kør ovenstående rutine fra det øjeblikkelige vindue, og den skulle returnere False:

WatchOut
KeyA exists? False

Tilføj et ur

Lad os nu tilføje et ur af "KeyA"-elementet:

Lad os prøve at køre WatchOut rutine igen:

WatchOut
KeyA exists? False

Så langt så godt. Måske er dette alligevel ikke et problem.

Gå gennem koden

Lad os tilføje et Stop sætning for at tvinge koden til at bryde:

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

Lad os nu prøve at køre WatchOut rutine:

WatchOut
KeyA exists? True

Aha! Kombinationen af ​​uret og indbrud i debuggeren er nok til at tvinge "fejlen" til at dukke op. Jeg har lagt bug i skræmmeanførselstegn, fordi det faktisk er forventet adfærd for debuggeren. Men det er næsten helt sikkert uventet adfærd for udvikleren.

(Bemærk, at der ikke er noget særligt ved Stop kommando, der forårsager denne adfærd. Du kan fjerne Stop linje og sæt et brudpunkt på koden, og den samme adfærd vil forekomme.)

Du kan se, hvor denne slags ting kan få dig til at trække dit hår ud, mens du fejlfinder. Når som helst dit programs opførsel er anderledes, mens det kører normalt i forhold til under fejlretning, har du muligheden for én skærpende fejlretningssession.

Oversigt

Trin til at genskabe problemet:

  1. Opret et ur til et specifikt ordbogselement
  2. Bryd ind i debuggeren, mens du udfører koden

Dette vil sandsynligvis kun hjælpe en eller to udviklere. Men det vil potentielt spare disse udviklere timer af frustration. Og hvis jeg skal være ærlig, er det lige så sandsynligt, som nogen andre, at jeg er en af ​​disse udviklere;-).


  1. Formattering af data i Power BI Desktop-visualiseringer

  2. Vil ANSI JOIN vs. ikke-ANSI JOIN-forespørgsler fungere anderledes?

  3. Oracle Database-ændringsmeddelelse

  4. Hvordan sender jeg værdi til en lagret procedureparameter i OLE DB-kildekomponent?