programing

컬렉션 항목의 값을 변경하는 방법

jooyons 2023. 6. 14. 21:50
반응형

컬렉션 항목의 값을 변경하는 방법

이 코드(excel-vba)를 사용하여 배열에 따라 여러 항목을 컬렉션에 추가합니다.
배열 값을 키로 사용하고 문자열 "NULL"을 추가된 각 항목의 값으로 사용합니다.

Dim Coll As New collection
Dim myArr()

Set Coll = New collection
myArr() = Array("String1", "String2", "String3")

For i = LBound(myArr) To UBound(myArr)
    Coll.Add "NULL", myArr(i)
Next i

이제 키로 식별하여 항목의 값을 변경하려면 항목을 제거한 다음 동일한 키로 항목을 추가해야 합니다. 아니면 항목 값을 변경할 수 있습니까?

이것이 유일한 방법입니까?

Coll.Remove "String1"
Coll.Add "myString", "String1"

또는 다음과 같은 것이 있습니까? (그것이 작동하지 않는다는 것을 압니다)

Coll("String1") = "myString"

(공개) 함수를 작성하여 컬렉션을 업데이트할 수도 있습니다.

public function updateCollectionWithStringValue(coll as Collection, key as string, value as string) as collection
    coll.remove key
    coll.add value, key
    set updateCollectionWithStringValue = coll
end function

다음을 통해 이 함수를 호출할 수 있습니다.

set coll = updateCollectionWithStringValue(coll, "String1","myString")

그러면 호출할 라이너가 하나 있습니다.

당신은 그것을 사용할 수 없습니다.Before이 요건을 충족하기 위한 주장?

예:

Option Explicit

Sub TestProject()
    Dim myStrings As New Collection

    myStrings.Add item:="Text 1"
    myStrings.Add item:="Text 2"
    myStrings.Add item:="Text 3"

    ' Print out the content of collection "myStrings"
    Debug.Print "--- Initial collection content ---"
    PrintCollectionContent myStrings
    ' Or with the "Call" keyword: Call PrintCollectionContent(myStrings)
    Debug.Print "--- End Initial collection content ---"

    ' Now we want to change "Text 2" into "New Text"
    myStrings.Add item:="New Text", Before:=2 ' myStrings will now contain 4 items
    Debug.Print "--- Collection content after adding the new content ---"
    ' Print out the 'in-between' status of collection "myStrings" where we have
    ' both the new string and the string to be replaced still in.
    PrintCollectionContent myStrings
    Debug.Print "--- End Collection content after adding the new content ---"

    myStrings.Remove 3
    ' Print out the final status of collection "myStrings" where the obsolete 
    ' item is removed
    Debug.Print "--- Collection content after removal of the old content ---"
    PrintCollectionContent myStrings
    Debug.Print "--- End Collection content after removal of the old content ---"

End Sub

Private Sub PrintCollectionContent(ByVal myColl As Variant)
    Dim i as Integer

    For i = 1 To myColl.Count()
        Debug.Print myColl.Item(i)
    Next i
End Sub

이렇게 하면 되지 않을까요?

다음은 다음과 같은 솔루션입니다.Coll("String1") = "myString" 효과가 있습니다.

당신이.AddVBA 컬렉션의 개체입니다. 개체 자체가 추가되고 값이 추가되지 않습니다.즉, 개체가 컬렉션에 있는 동안 개체의 속성을 변경할 수 있습니다.클래스 개체에서 단일 변형을 감싸는 클래스 모듈을 만들었습니다..Value기본 속성으로 사용합니다.저장 위치.cls파일, 그 다음File > Import FileVBA 편집기에서.

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "clsValue"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Compare Database
Option Explicit
Private MyValue As Variant
Property Get Value() As Variant
    Attribute Value.VB_UserMemId = 0
    Value = MyValue
End Property
Property Let Value(v As Variant)
    Attribute Value.VB_UserMemId = 0
    MyValue = v
End Property

이제 이 버전의 코드는 원하는 대로 작동합니다.

Private Sub clsValue_test()
Dim Coll As New Collection
Dim myArr()
Dim v As Variant
myArr = Array("String1", "String2", "String3")
For Each v In myArr
    Coll.Add New clsValue, v
    Coll(v) = "NULL"
Next v
Coll("String1") = "myString"    ' it works!
For Each v In myArr
    Debug.Print v, ": "; Coll(v)
Next v
End Sub

결과를 생성합니다.

String1       : myString
String2       : NULL
String3       : NULL

컬렉션 항목을 키로 삭제하는 기능을 만드는 변형으로, VBA 속성으로 구현하는 것입니다.

Public Property Let CollectionValue(coll As Collection, key As String, value As String)
    On Error Resume Next
    coll.Remove key
    On Error GoTo 0
    coll.Add value, key
End Property


Public Property Get CollectionValue(coll As Collection, key As String) As String
    CollectionValue = coll(key)
End Property

그리고 이렇게 사용됩니다.

'Writing
CollectionValue(coll, "Date") = Now()

'Reading
Debug.Print(CollectionValue(coll, "Date")) 

키가 존재하지 않는 경우 무시함으로써 항목을 추가하는 데도 사용할 수 있습니다.

컬렉션을 루프하고 새 값을 새 컬렉션에 추가하기만 하면 됩니다.

function prep_new_collection(my_old_data as collection) as collection

dim col_data_prep as new collection

for i = 1 to my_old_data.count

if my_old_data(i)(0)= "whatever" then

  col_data_prep.add array("NULL", my_old_data(i)(1))

else

 col_data_prep.add array(my_old_data(i)(0), my_old_data(i)(1))

end if

next i

 set prep_new_collection = col_data_prep

end function

저는 방금 같은 문제에 부딪혔는데, 제 솔루션을 필요로 하는 사람들을 위해 여기에 게시할 생각이었습니다. 제 해결책은 업데이트 기능이 있는 클래스를 만드는 것이었습니다. 이 코드를 이름이 붙은 파일에 저장한 다음 프로젝트로 가져오는 것입니다.

    VERSION 1.0 CLASS
    BEGIN
      MultiUse = -1  'True
    END
    Attribute VB_Name = "EnhancedCollection"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = False
    Attribute VB_Exposed = False
    Option Explicit
    
    Private data As New Collection
       
    '=================================ADD
    
    If IsMissing(key) Then
        If IsMissing(before) Then
            If IsMissing(after) Then
                data.Add Value
            Else
                data.Add Value, , , after
            End If
        Else
            data.Add Value, , before
        End If
    ElseIf key = "TEMP_ITEM" Then
        Exit Sub
    Else
        If IsMissing(before) Then
            If IsMissing(after) Then
                data.Add Value, key
            Else
                data.Add Value, key, , after
            End If
        Else
            data.Add Value, key, before
        End If
    End If
End Sub
'=================================REMOVE

Sub Remove(key As Variant)
    data.Remove key
End Sub

    '=================================COUNT
    
    Function Count() As Integer
        Count = data.Count
    End Function
    '=================================ITEM
    
    Function Item(key As Variant) As Variant
    'This is the default Function of the class
    Attribute Item.VB_Description = "returns the item"
    Attribute Item.VB_UserMemId = 0
    On Error GoTo OnError
        If VarType(key) = vbString Or VarType(key) = vbInteger Then
            Item = data.Item(key)
        End If
        Exit Function
    OnError:
        Item = Null
    End Function
    '=================================Update
    
    Function Update(key As Variant, Value As Variant) As Variant
    On Error GoTo OnError
        If VarType(key) = vbString Or VarType(key) = vbInteger Then
            data.Add "", "TEMP_ITEM", , key
            data.Remove key
            data.Add Value, key, "TEMP_ITEM"
            data.Remove "TEMP_ITEM"
        End If
        Exit Function
    OnError:
        Update = Null
    End Function

추가적인 이점으로 언제든지 더 많은 기능을 추가할 수 있습니다.

Sub tcoll()
 Dim c As New Collection
 c.Add Array("1", 2, False)
 c.Add Array("2", 3, False)
 c.Add Array("1", 4, False)
 For Each ci In c:  Debug.Print ci(0), ci(1), ci(2): Next
 If 1 Then
  'ok
  For X = c.Count To 1 Step -1
   Select Case c(X)(0)
   Case "1"
    c.Add Array(c(X)(0), c(X)(1), 1), after:=X
    c.Remove X
   Case "2"
    c.Remove X
   End Select
  Next
 Else
  'Subscript out of range
  For X = 1 To c.Count
   Select Case c(X)(0)
   Case "1"
    c(X)(2) = 1 'no error but collection is not changed
   Case "2"
    c.Remove X
   End Select
  Next
 End If
 For Each ci In c:  Debug.Print ci(0), ci(1), ci(2): Next
 Set c = Nothing
End Sub

언급URL : https://stackoverflow.com/questions/29541710/how-to-change-value-of-an-item-of-a-collection

반응형