Onehdy jsem narazil na tuto odpověď na StackOverflow a chtěl jsem na ni upozornit (zdůrazňuji můj):
Tento problém se mi projevil při ladění, když měl jsem hodinky, které se pokusily vrátit položku „chybějícího“ klíče . Ve skutečnosti další frustrované ladění mělo stejný problém, když jsem doslova sledoval [scriptingdictonaryObject].exists() condtional); Navrhuji, aby ten „chybějící“ klíč byl přidán kvůli hodinkám . Když jsem odstranil hodinky a místo toho vytvořil dočasný list, do kterého jsem pole zkopíroval za běhu, nechtěné klíče již nebyly přidány.Objekt slovníku přidávající položky před .add() se nazývá Používám objekt slovníku z knihovny MS Scripting Runtime k uložení řady polí a provádění operací s buňkami pole podle potřeby. Procesem prochází smyčka for... Stack Overflowriddley_w
Co se tady děje?
Jednou z „vlastností“ objektu Dictionary je to, že bude implicitně vytvářet nové položky, aniž byste museli volat metodu .Add explicitně . Jaký je rozdíl mezi implicitním a explicitním?
Poznámka:Včasné použití objektu Dictionary vyžaduje odkaz na "Microsoft Scripting Runtime" (podrobnosti zde).
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")
Zde je relevantní část dokumentace týkající se implicitní vytvoření klíče:
Poznámky
Pokud klíč nebyl nalezen při změně položky , nový klíč je vytvořen pomocí zadaného newitem . Pokud klíč nebyl nalezen při pokusu o vrácení existující položky, nový klíč je vytvořen a jeho odpovídající položka je ponechána prázdná.
Reprodukce problému
Zopakujme si problém, abychom přesně viděli, kde věci jdou stranou.
Očekávané chování
Vytvořte následující ukázkovou rutinu:
Sub WatchOut()
Dim MyDict As Dictionary
Set MyDict = New Dictionary
Debug.Print "KeyA exists? "; MyDict.Exists("KeyA")
End Sub
Spusťte výše uvedenou rutinu z bezprostředního okna a měla by vrátit hodnotu False:
WatchOut
KeyA exists? False
Přidat hodinky
Nyní přidáme hodinky položky „KeyA“:
Zkusme spustit WatchOut znovu rutina:
WatchOut
KeyA exists? False
Zatím je vše dobré. Možná to nakonec není problém.
Projděte si kód
Přidejme Zastávku příkaz k vynucení přerušení kódu:
Sub WatchOut()
Dim MyDict As Dictionary
Set MyDict = New Dictionary
Stop
Debug.Print "KeyA exists? "; MyDict.Exists("KeyA")
End Sub
Nyní zkusme spustit WatchOut rutina:
WatchOut
KeyA exists? True
Aha! Kombinace hodinek a nabourání se do debuggeru stačí k tomu, aby se „štěnice“ objevila. Dal jsem chybu v děsivých uvozovkách, protože je to vlastně očekávané chování ladicího programu. Pro vývojáře je to ale téměř jistě neočekávané chování.
(Upozorňujeme, že na Stop není nic zvláštního příkaz, který toto chování způsobuje. Můžete odstranit Stop řádek a nastavte bod přerušení v kódu a dojde ke stejnému chování.)
Můžete vidět, kde by vám taková věc mohla způsobit vytrhávání vlasů při ladění. Kdykoli se chování vašeho programu při normálním běhu liší od chování při ladění, máte předpoklady pro jednu přitěžující relaci ladění.
Shrnutí
Kroky pro reprodukci problému:
- Vytvořte sledování pro konkrétní položku ve slovníku
- Při spouštění kódu se prolomte do ladicího programu
To pravděpodobně pomůže pouze jednomu nebo dvěma vývojářům. Ale potenciálně to těmto vývojářům ušetří hodiny frustrace. A abych byl upřímný, je pravděpodobné, že jako kdokoli jiný budu jedním z těchto vývojářů;-).