Попаднах на този отговор на StackOverflow онзи ден и исках да обърна малко внимание на него (подчертайте моето):
Този проблем се прояви по време на отстраняване на грешки, когато Имах часовник, който се опита да върне елемента на „липсващия“ ключ . Всъщност, по-нататъшното разочаровано отстраняване на грешки имаше същия проблем, когато буквално имах часовник за условието [scriptingdictonaryObject].exists()); Предлагам да се добави липсващият ключ заради часовниката . Когато премахнах часовника и вместо това създадох временен работен лист, в който да копирам масива по време на работа, нежеланите ключове вече не бяха добавени.Речников обект, добавящ елементи преди .add() се извиква. Използвам обект на речник от библиотеката на MS Scripting Runtime, за да съхранявам серия от масиви и да извършвам операции върху клетките на масива, ако е необходимо. Има цикъл for за преминаване през процеса... Stack Overflowriddley_w
Какво става тук?
Една от „характеристиките“ на обект от речник е, че той имплицитно създавайте нови елементи, без да е необходимо да извиквате метода .Add изрично . Каква е разликата между имплицитно и явно?
Забележка:Ранното използване на обекта Dictionary изисква препратка към „Microsoft Scripting Runtime“ (подробности тук).
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")
Ето съответната част от документацията относно неявно създаване на ключ:
Забележки
Ако ключ не се намира при промяна на елемент , нов ключ се създава с посочения newitem . Ако ключ не е намерен при опит за връщане на съществуващ елемент, нов ключ се създава и съответният елемент остава празен.
Възпроизвеждане на проблема
Нека възпроизведем проблема, за да видим къде точно нещата отиват настрани.
Очаквано поведение
Създайте следната примерна рутина:
Sub WatchOut()
Dim MyDict As Dictionary
Set MyDict = New Dictionary
Debug.Print "KeyA exists? "; MyDict.Exists("KeyA")
End Sub
Изпълнете горната рутина от непосредствения прозорец и тя трябва да върне False:
WatchOut
KeyA exists? False
Добавяне на часовник
Сега нека добавим часовник на елемента "KeyA":
Нека опитаме да стартираме WatchOut рутина отново:
WatchOut
KeyA exists? False
Дотук добре. Може би това все пак не е проблем.
Преминаване през кода
Нека добавим Стоп изявление за принудително прекъсване на кода:
Sub WatchOut()
Dim MyDict As Dictionary
Set MyDict = New Dictionary
Stop
Debug.Print "KeyA exists? "; MyDict.Exists("KeyA")
End Sub
Сега нека опитаме да стартираме WatchOut рутина:
WatchOut
KeyA exists? True
Аха! Комбинацията от часовника и проникването в дебъгера е достатъчна, за да накара "бъгът" да се появи. Сложих бъг в плашещи кавички, защото това всъщност е очаквано поведение за дебъгера. Но това е почти сигурно неочаквано поведение за разработчика.
(Обърнете внимание, че няма нищо специално за Стоп команда, която причинява това поведение. Можете да премахнете Стоп ред и задайте точка на прекъсване на кода и ще се случи същото поведение.)
Можете да видите къде този вид нещо може да ви накара да издърпате косата си, докато отстранявате грешки. Всеки път, когато поведението на вашата програма е различно, докато работи нормално, отколкото по време на отстраняване на грешки, имате предпоставките за една утежняваща сесия за отстраняване на грешки.
Резюме
Стъпки за възпроизвеждане на проблема:
- Създайте часовник за конкретен елемент от речника
- Пробив в инструмента за отстраняване на грешки, докато изпълнявате кода
Това вероятно ще помогне само на един или двама разработчици. Но това потенциално ще спести на тези разработчици часове на разочарование. И ако трябва да съм честен, имам голяма вероятност като всеки друг да бъда един от тези разработчици;-).