2014-12-08 3 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 및 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 다음 VALUE. http://stackoverflow.com/questions/915317/does-vba-have-dictionary-structure – dee

답변

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

Chris 님, 코드가 잘 작동합니다. 아이디어가 부족했습니다. 왜 코드 줄 dctSKEW.ADD "APZ4", 새로운 clsIVDATA Private Sub Class_Initialize() 루틴을 실행합니까? Excel vba에서 미리 정의 된 루틴입니까? – Zeus

+1

클래스의 인스턴스가 생성되면 (이 경우'New clsIVDATA'에 의해), Initialise 메소드가 자동으로 호출됩니다. 이것은 클래스의 기본 기능입니다. –

+0

다시 로그인하십시오. 간단한 질문 ... 코멘트에 코드를 강조하는 방법은 무엇입니까? 4 개의 들여 쓰기가 작동하지 않습니다 ... – Zeus