2017-11-08 5 views
1

가변 개체 인 가장자리 개체를 저장하는 데 사용되는 컬렉션 클래스 (이 경우 사전 클래스)가 있습니다. 루프를 통해 모든 정보를 보유하고있는 사전을 채울 때 데이터는 계속 덮어 쓰여지고 이유를 파악할 수 없습니다. 문제의 클래스에 대한 코드는 다음과 같습니다 가장자리 객체를 생성VBA 컬렉션 클래스 : Unwated 데이터 덮어 쓰기

Option Explicit 

Private pEdges As New Scripting.Dictionary 

Property Get Count() As Long 
    Count = pEdges.Count 
End Property 

Property Get EdgeByName(ByVal iName As Variant) As cEdge 
    Set EdgeByName = pEdges(iName) 
End Property 

'Would it be better to pass all of the data to this add sub, and create 
'the class objects here, rather than creating a temporary class object and 
'just passing it along? 
Sub Add(ByVal iEdge As cEdge) 
    Dim Edge As New cEdge 
    Set Edge = iEdge 
    pEdges.Add Edge.Name, Edge 
End Sub 

Sub Remove(ByVal iName As Variant) 
    pEdges.Remove (iName) 
End Sub 

Sub RemoveAll() 
    pEdges.RemoveAll 
End Sub 

Sub PrintNames() 
    Dim Key As Variant 
    For Each Key In pEdges 
     Debug.Print Key & " - " & pEdges(Key).Name & vbCrLf; 
    Next 
    Debug.Print vbdrlf; 
End Sub 

서브는 다음과 같습니다

Sub CalculateEdges(cCavities() As cCavity, dEdges As cEdges) 
    Dim i As Integer 

    For i = 1 To UBound(cCavities) 
     Dim TempEdge As cEdge 
     Set TempEdge = New cEdge 
     Dim AdjSize As Integer 
     AdjSize = cCavities(i).AdjacencySize 
     If AdjSize> MaxEdges Then MaxEdges = AdjSize 
     Dim j As Integer 
     For j = 1 To AdjSize 
      With TempEdge 
       'Edge Names are a combination of two node names 
       .Name = cCavities(i).Name & cCavities(i).Adjacency(j) 
       'Sets the start node (Object) for the edge 
       .SetNode cCavities(i), 0 
       'Sets the end node (Object) for the edge 
       .SetNode BackGround.NodeByName(cCavities, cCavities(i).Adjacency(j)), 1 
       'Used later in program 
       .Value = 0 
      End With 
      dEdges.Add TempEdge 
      dEdges.PrintNames 
     Next j 
    Next i 
End Sub 

dEdges.PrintNames 하위의 출력은 내가이 디버깅을 위해 사용 된 것입니다 (이후 시계 창에 사전의 항목 데이터가 표시되지 않습니다. 루프가 진행됨에 따라 키와 해당하는 가장자리 개체의 이름 값이 인쇄됩니다. 올바르게 작동하면이 두 문자열이 동일해야합니다. 그래도 새 사전 개체를 사전에 추가 할 때마다 이전에 입력 한 모든 키의 개체를 덮어 씁니다. 나는 이것이 Collection 클래스에 전달할 TempEdge 변수를 생성한다는 사실에 의문의 여지가 있지만 잘 모르겠습니다. 출력의

예 :

C1C2 - C1C2 

C1C2 - C1C3 
C1C3 - C1C3 

C1C2 - C1C4 
C1C3 - C1C4 
C1C4 - C1C4 

ETC 

이 테스트되고 하나의 단일 데이터 포인트이지만, 나를 cEdge 객체 내부의 모든 변수가 아니라 이름 문자열을 덮어 당신을 확신 할 수 있습니다. 문자열 일 뿐이므로 확인하는 것이 가장 쉽습니다.

"시계"창과 비슷하게 사전에 저장된 객체를 볼 수있는 방법이 있다면, 어떻게해야하는지 알고 싶습니다. 이 시점에서 임시 에지를 사용하고있는 전체 이유는 루프의 특정 시점에서 사전에 어떤 데이터가 들어 있는지 추적 할 수 있기 때문입니다.

이 작업을 수행 할 수 있으면 cCavities 배열을 유사한 컬렉션 클래스로 전환 할 가능성이 큽니다. 현재는 제대로 작동하지 않기 때문에 현재 하나가 아닙니다.

답변

0

모든 데이터를 추가 루틴에 전달한다는 아이디어가 나왔고 문제가 해결 된 것으로 보입니다. 나는 아직도 내가 사용하고있는 방법이 효과가 없었던 이유를 알고 싶다. 그래서 그것에 대해 논평하거나 대답 해 주시기 바랍니다.

Sub CalculateEdges(cCavities() As cCavity, dEdges As cEdges) 
    Dim i As Integer 

    For i = 1 To UBound(cCavities) 
     Dim AdjSize As Integer 
     AdjSize = cCavities(i).AdjacencySize 
     If AdjSize > MaxEdges Then MaxEdges = AdjSize 
     Dim j As Integer 
     For j = 1 To AdjSize 
      dEdges.Add cCavities(i).Name & cCavities(i).Adjacency(j), cCavities(i), BackGround.NodeByName(cCavities, cCavities(i).Adjacency(j)), 0 
      dEdges.PrintNames 
     Next j 
    Next i 
End Sub 
:

Sub Add(ByVal iName As String, iNode1 As cCavity, iNode2 As cCavity, iValue As Integer) 
    Dim Edge As New cEdge 
    With Edge 
     .Name = iName 
     .SetNode iNode1, 0 
     .SetNode iNode2, 1 
     .Value = iValue 
    End With 
    pEdges.Add Edge.Name, Edge 
End Sub 

이 모양을 위해 채우기 루프를 변경합니다

이 솔루션은 한 번 임시 에지 변수에 전달 된 모든 개별 매개 변수를 허용하는 cEdges.Add 하위를 변경했다

이 코드는 특히 .Add 라인을 지울 수 있습니다. 나는 그것을 할 가능성이 가장 높지만, 지금은 괜찮습니다.

EDIT : 추가 조사와 약간의 시행 착오를 거쳐 데이터를 덮어 쓸 이유를 발견했습니다. Set 키워드는 원래 값에 대한 포인터 만 생성하므로 효과적으로 위의 코드에 하나의 개체 인 TempEdge 변수와이를 가리키는 여러 가지 머리글이 있습니다. Temp 가장자리를 편집 할 때 이후의 헤드가 모두 변경되는 것입니다.