2014-12-08 143 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 “)。使用'dctSKEW.Item(”APZ4“)初始化RATIO(I),IV(I),KEY'初始RATIO(I),IV(I),KEY' – 2014-12-08 08:29:57

+0

@ vba4all谢谢,但它没有奏效。我认为字典项目被分配到类模块而不是模块中,所以这种改变不会有什么不同。所以我认为问题是GetRatio或GetIV函数 dRATIO.Exists(KEY)返回false,因此返回999 – Zeus 2014-12-08 12:34:18

+0

dRATIO.Add KEY,RATIO和dIV.Add KEY,IV ... KEY然后VALUE。 http://stackoverflow.com/questions/915317/does-vba-have-dictionary-structure – dee 2014-12-08 16:01:00

回答

3

你的主要问题是你混合了正开始与加载项将它(每次通话时间clsIVDATA.Init要创建一个新的空字典)的Dictioary对象。

此外,使用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”,新的clsIVDATA运行Private Sub Class_Initialize()例程?在excel vba中,子是一个预定义的例程吗? – Zeus 2014-12-09 09:33:34

+1

当创建一个类的实例时(在这种情况下,通过'new clsIVDATA'),它的Initialise方法被自动调用。这是Classes的基本功能。 – 2014-12-09 09:37:51

+0

再次。简单的问题...如何在评论中突出显示代码? 4缩进不适用于我... – Zeus 2014-12-09 09:40:07