2013-02-28 2 views
2

Так что я использую немного кода здесь, где я использовал один словарь для заполнения двух разных словарей, которые хранятся в качестве атрибутов в пользовательском классе. Я делаю это для повышения эффективности.VBA: Проблемы памяти словаря? Заполнять dict, .removeall, populate issues

Примечание: У меня есть обходное решение этой проблемы, используя словарь для каждого атрибута, который я хочу установить, но это не слишком эффективно.

Так примерно вот мой код:

for iKey = 1 to class.maxnumber ' 8 
    dTempDict.add iKey, cdbl(24) ' enforce to 24 for calcs later 
next iKey 

Set class.dict1 = dTempDict ' commit to class.dict1 

dTempDict.removeall 'wipe temp dictionary 

for iKey = 1 to class.maxnumber ' 8 
    dTempDict.add iKey, "word" ' something other than 24 to test 
next iKey 

Set class.dict2 = dTempDict 

Так выше работает отлично. Затем я попытался выполнить цикл и распечатать ключи класса.dict1 без проблем. Когда я попытался присвоить значения предварительно объявленному dbl, я попал в беду. Затем я петельные через каждого ключа, как это в другом югу ближнего класса ByRef:

dim dTempDict as scripting.dictionary 
Set dTempDict = class.dict1 
for each iKey in dTempDict 
msgbox typename(dTempDict.Item(iKey)) 
next iKey 

Это вернуло результат ... «String» ... запутанным. Затем я изменил свой держатель стоимости на строку, и она сработала. Я проверил мои аксессоры внутри класса, и они не возвращаются к неправильному атрибуту словаря, поэтому кажется, что, хотя я назначаю их второй и даже делаю .removeall, значения для моего второго словаря заселяются в первый.

Любые идеи?

Как было сказано выше, с использованием другого словаря temp для class.dict1 и class.dict2 они назначаются правильно, но это все еще запутывает.

ответ

0

Когда вы сделаете это ...

Set class.dict1 = dTempDict 
dTempDict.removeall 
'... 
Set class.dict2 = dTempDict 

... тогда как dict1 и dict2 указывают на тот же объект словаря (dTempDict).

Назначение одной переменной объекта другому не создает копию этого объекта, а просто приводит к дополнительному «указателю» на тот же объект.

Вы должны создать новый словарь, а не повторно использовать тот же, что и для dict2.

0

Как правило, мне не нравятся словари в классах, кроме как для хранения других классов. Я не знаю вашей ситуации, поэтому я не могу комментировать это. Но что бы ни было «24», вы можете подумать, что это должен быть его собственный объект, и ваш класс будет содержать другой класс коллекции. Кстати, для этой цели я использую вместо них словари, а не словари. Затем доступ к таким вещам, как

clsDepartment.Employees.Count 

вместо

clsDepartment.mydict(1) 

Во всяком случае, за то, что у вас есть, вы должны заполнить словарь в классе, а не создавать словарь TEMP. Если ваш класс выглядит следующим образом

Private mdcTwentyFour As Scripting.Dictionary 
Private mdcNotTwentyFour As Scripting.Dictionary 

Public Property Get TwentyFour() As Scripting.Dictionary 
    Set TwentyFour = mdcTwentyFour 
End Property 

Public Property Get NotTwentyFour() As Scripting.Dictionary 
    Set NotTwentyFour = mdcNotTwentyFour 
End Property 

Public Property Get MaxNumber() As Long 
    MaxNumber = 8 
End Property 

Private Sub Class_Initialize() 

    Set mdcTwentyFour = New Scripting.Dictionary 
    Set mdcNotTwentyFour = New Scripting.Dictionary 

End Sub 

Тогда ваш суб может выглядеть следующим образом

Sub FillClassDicts() 

    Dim clsClass As CClass 
    Dim i As Long 

    Set clsClass = New CClass 

    For i = 1 To clsClass.MaxNumber 
     clsClass.TwentyFour.Add i, 24 
     clsClass.NotTwentyFour.Add i, "word" 
    Next i 

    Debug.Print clsClass.TwentyFour.Count, clsClass.NotTwentyFour.Count 
    Debug.Print TypeName(clsClass.TwentyFour(1)), TypeName(clsClass.NotTwentyFour(5)) 

End Sub 
Смежные вопросы