2014-12-08 12 views
2

Я пытаюсь сохранить данные в словаре, объявленном в модуле класса. Я использовал словарь в модуле класса, потому что количество групп и связанных с ними точек данных неизвестно в начале. Приведенный ниже код компилируется, но операторы dRATIO.exists в модуле класса и возвращают false (однако при первом проходе оператор отладки в модуле класса дает правильное значение, после этого ошибки), а затем Function GetRATIO возвращает 999. Любые предложения ?Excel VBA, записывающий данные в словарь в модуле класса

'CODE IN A CLASS MODULE CALLED clsIVDATA 
Option Explicit 

Public dRATIO 
Public dIV 
' 

Sub Init(RATIO As Variant, IV As Variant, KEY As String) 

'Dim I As Long 
Dim VAL As String 
Dim RowKeys 
Dim COLKEYS 

Set dRATIO = CreateObject("Scripting.Dictionary") 
Set dIV = CreateObject("Scripting.Dictionary") 

dRATIO.ADD ITEM:=RATIO, KEY:=KEY 
dIV.ADD ITEM:=RATIO, KEY:=KEY 

Debug.Print dRATIO.Exists("1") 
Debug.Print dRATIO.ITEM("1") 

End Sub 


Function GetRATIO(KEY As String) 
    If dRATIO.Exists(KEY) Then 
     GetRATIO = dRATIO(KEY) 
    Else 
     GetRATIO = 999 'or raise an error... 
    End If 
End Function 

Function NO_VALUES() 

NO_VALUES = dRATIO.COUNT 

End Function 

Function GetIV(KEY As String) 
    If dIV.Exists(KEY) Then 
     GetIV = dIV(KEY) 
    Else 
     GetIV = 999 'or raise an error... 
    End If 
End Function 

'===================================================== 
'CODE IN A NORMAL MODULE 
Sub tstclass() 
Dim RATIO() As Variant 
Dim IV() As Variant 
Dim I As Integer 

Dim dctSKEW As Object 
Set dctSKEW = CreateObject("Scripting.Dictionary") 
dctSKEW.ADD "APZ4", New clsIVDATA 

RATIO = Array(0.879, 0.843, 0.802, 0.756, 0.658) 
IV = Array(0.165, 0.156, 0.145, 0.136, 0.125) 

For I = 1 To 5 
    KEY = CStr(I) 
    dctSKEW("APZ4").Init RATIO(I), IV(I), KEY 
Next I 

Debug.Print dctSKEW("APZ4").GetRATIO("1") 
Debug.Print dctSKEW("APZ4").GetRATIO("2") 
Debug.Print dctSKEW("APZ4").NO_VALUES 

End Sub 
+0

попробуйте заменить 'dctSKEW (" APZ4 ") .Введите RATIO (I), IV (I), KEY' с' dctSKEW.Item ("APZ4"). Init RATIO (I), IV (I), KEY' –

+0

@ vba4all Спасибо, но это не сработало. Я думаю, что элемент словаря назначается в модуле класса, а не модулем, поэтому это изменение не будет иметь значения. Поэтому я думаю, что проблема связана с функциями GetRatio или GetIV dRATIO.Exists (KEY) возвращает false, и поэтому возвращается 999 – Zeus

+0

. DRATIO.Add KEY, RATIO и dIV.Add KEY, IV ... KEY then VALUE. http://stackoverflow.com/questions/915317/does-vba-have-dictionary-structure – dee

ответ

3

Ваш основной вопрос вы путаете Инициализация Dictioary объекта с погрузкой в ​​него элементов (каждый раз, когда вы звоните clsIVDATA.Init вы создаете новый пустой словарь).

Кроме того, массивы, созданные с помощью Array(...), основаны на 0, поэтому ваш цикл For будет ошибочным и приведет к неожиданным результатам.

Вот ваш код, переработан для решения этих и некоторые другие незначительные проблемы

Код класса

Option Explicit 

'CODE IN A CLASS MODULE CALLED clsIVDATA 

Private dRATIO As Object 
Private dIV As Object 
' 

Private Sub Class_Initialize() 
    Set dRATIO = CreateObject("Scripting.Dictionary") 
    Set dIV = CreateObject("Scripting.Dictionary") 
End Sub 

Sub Init(RATIO As Variant, IV As Variant, KEY As String) 
    dRATIO.Add Item:=RATIO, KEY:=KEY 
    dIV.Add Item:=RATIO, KEY:=KEY 
End Sub 

Function GetRATIO(KEY As String) 
    If dRATIO.Exists(KEY) Then 
     GetRATIO = dRATIO(KEY) 
    Else 
     GetRATIO = 999 'or raise an error... 
    End If 
End Function 

Function NO_VALUES() 
    NO_VALUES = dRATIO.Count 
End Function 

Function GetIV(KEY As String) 
    If dIV.Exists(KEY) Then 
     GetIV = dIV(KEY) 
    Else 
     GetIV = 999 'or raise an error... 
    End If 
End Function 

Модуль Код

Option Explicit 

'===================================================== 
'CODE IN A NORMAL MODULE 
Sub tstclass() 
    Dim RATIO() As Variant, KEY As String 
    Dim IV() As Variant 
    Dim I As Long 
    Dim c As clsIVDATA 

    Dim dctSKEW As Object 
    Set dctSKEW = CreateObject("Scripting.Dictionary") 
    dctSKEW.Add "APZ4", New clsIVDATA 

    Set c = dctSKEW.Item("APZ4") 
    RATIO = Array(0.879, 0.843, 0.802, 0.756, 0.658) 
    IV = Array(0.165, 0.156, 0.145, 0.136, 0.125) 

    For I = 0 To 4 
     KEY = CStr(I + 1) 
     c.Init RATIO(I), IV(I), KEY 
    Next I 

    Debug.Print dctSKEW("APZ4").GetRATIO("1") 
    Debug.Print dctSKEW("APZ4").GetRATIO("2") 
    Debug.Print dctSKEW("APZ4").NO_VALUES 

End Sub 
+1

Спасибо Крису, ваш код работает хорошо - у меня не было идей. Почему строка кода dctSKEW.ADD «APZ4», New clsIVDATA запускает процедуру Private Sub Class_Initialize()? Является ли sub предопределенной процедурой в excel vba? – Zeus

+1

Когда экземпляр класса создается (в этом случае с помощью 'New clsIVDATA'), его метод Initialize вызывается автоматически. Это фундаментальная особенность классов. –

+0

tks снова. Простой вопрос ... как я выделяю код в комментарии? 4 indents не работают для меня ... – Zeus

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