문제

나는 어떻게 여부를 결정체 구성원의 컬렉션에서 VBA?

특히,나는 찾아야하는지 여부를 테이블이 정의의 구성원 TableDefs 컬렉션입니다.

도움이 되었습니까?

해결책

최선의 방법은 컬렉션의 구성원을 반복하고 원하는 대상이 있는지 확인하는 것입니다. 내가 여러 번해야했다고 믿으십시오.

두 번째 솔루션 (훨씬 더 나쁜)은 "수집되지 않은 항목"오류를 잡은 다음 항목이 존재하지 않는다고 말하도록 깃발을 설정하는 것입니다.

다른 팁

충분하지 않습니까?

Public Function Contains(col As Collection, key As Variant) As Boolean
Dim obj As Variant
On Error GoTo err
    Contains = True
    obj = col(key)
    Exit Function
err:

    Contains = False
End Function

정확히 우아하지는 않지만 내가 찾을 수있는 최고의 (그리고 가장 빠른) 솔루션은 onerror를 사용하는 것이 었습니다. 이것은 중간에서 큰 컬렉션의 반복보다 훨씬 빠릅니다.

Public Function InCollection(col As Collection, key As String) As Boolean
  Dim var As Variant
  Dim errNumber As Long

  InCollection = False
  Set var = Nothing

  Err.Clear
  On Error Resume Next
    var = col.Item(key)
    errNumber = CLng(Err.Number)
  On Error GoTo 0

  '5 is not in, 0 and 438 represent incollection
  If errNumber = 5 Then ' it is 5 if not in collection
    InCollection = False
  Else
    InCollection = True
  End If

End Function

이것은 오래된 질문입니다. 모든 답과 의견을 신중하게 검토했으며 성능 솔루션을 테스트했습니다.

나는 컬렉션에 원시인뿐만 아니라 객체가있을 때 실패하지 않는 환경을위한 가장 빠른 옵션을 생각해 냈습니다.

Public Function ExistsInCollection(col As Collection, key As Variant) As Boolean
    On Error GoTo err
    ExistsInCollection = True
    IsObject(col.item(key))
    Exit Function
err:
    ExistsInCollection = False
End Function

또한이 솔루션은 하드 코딩 된 오류 값에 의존하지 않습니다. 그래서 매개 변수 col As Collection 다른 수집 유형 변수로 대체 할 수 있으며 함수는 여전히 작동해야합니다. 예를 들어, 현재 프로젝트에서는 col As ListColumns.

컬렉션을 통한 반복을위한 마이크로 소프트 솔루션과 혼합 된 위의 제안 에서이 솔루션을 만들었습니다.

Public Function InCollection(col As Collection, Optional vItem, Optional vKey) As Boolean
On Error Resume Next

Dim vColItem As Variant

InCollection = False

If Not IsMissing(vKey) Then
    col.item vKey

    '5 if not in collection, it is 91 if no collection exists
    If Err.Number <> 5 And Err.Number <> 91 Then
        InCollection = True
    End If
ElseIf Not IsMissing(vItem) Then
    For Each vColItem In col
        If vColItem = vItem Then
            InCollection = True
            GoTo Exit_Proc
        End If
    Next vColItem
End If

Exit_Proc:
Exit Function
Err_Handle:
Resume Exit_Proc
End Function

이에 대한 제안 된 코드를 단축하고 예기치 않은 오류를 일반화 할 수 있습니다. 여기에 간다 :

Public Function InCollection(col As Collection, key As String) As Boolean

  On Error GoTo incol
  col.Item key

incol:
  InCollection = (Err.Number = 0)

End Function

특정 경우 (TableDefs) 컬렉션을 반복하고 이름을 확인하는 것은 좋은 방법입니다. 컬렉션 (이름)의 키는 컬렉션의 클래스의 속성이기 때문에 괜찮습니다.

그러나 VBA 컬렉션의 일반적인 경우 키가 컬렉션의 객체의 일부가 될 필요는 없습니다 (예 : 컬렉션을 사전으로 사용할 수 있으며 컬렉션의 객체와 관련이없는 키가있는 키가 있습니다). 이 경우 항목에 액세스하고 오류를 잡을 수밖에 없습니다.

편집, 컬렉션에 가장 적합한 작업이 있습니다.

Public Function Contains(col As collection, key As Variant) As Boolean
    Dim obj As Object
    On Error GoTo err
    Contains = True
    Set obj = col.Item(key)
    Exit Function
    
err:
    Contains = False
End Function

이 버전은 원시 유형 및 클래스에 대해 작동합니다 (짧은 테스트 방법 포함)

' TODO: change this to the name of your module
Private Const sMODULE As String = "MVbaUtils"

Public Function ExistsInCollection(oCollection As Collection, sKey As String) As Boolean
    Const scSOURCE As String = "ExistsInCollection"

    Dim lErrNumber As Long
    Dim sErrDescription As String

    lErrNumber = 0
    sErrDescription = "unknown error occurred"
    Err.Clear
    On Error Resume Next
        ' note: just access the item - no need to assign it to a dummy value
        ' and this would not be so easy, because we would need different
        ' code depending on the type of object
        ' e.g.
        '   Dim vItem as Variant
        '   If VarType(oCollection.Item(sKey)) = vbObject Then
        '       Set vItem = oCollection.Item(sKey)
        '   Else
        '       vItem = oCollection.Item(sKey)
        '   End If
        oCollection.Item sKey
        lErrNumber = CLng(Err.Number)
        sErrDescription = Err.Description
    On Error GoTo 0

    If lErrNumber = 5 Then ' 5 = not in collection
        ExistsInCollection = False
    ElseIf (lErrNumber = 0) Then
        ExistsInCollection = True
    Else
        ' Re-raise error
        Err.Raise lErrNumber, mscMODULE & ":" & scSOURCE, sErrDescription
    End If
End Function

Private Sub Test_ExistsInCollection()
    Dim asTest As New Collection

    Debug.Assert Not ExistsInCollection(asTest, "")
    Debug.Assert Not ExistsInCollection(asTest, "xx")

    asTest.Add "item1", "key1"
    asTest.Add "item2", "key2"
    asTest.Add New Collection, "key3"
    asTest.Add Nothing, "key4"
    Debug.Assert ExistsInCollection(asTest, "key1")
    Debug.Assert ExistsInCollection(asTest, "key2")
    Debug.Assert ExistsInCollection(asTest, "key3")
    Debug.Assert ExistsInCollection(asTest, "key4")
    Debug.Assert Not ExistsInCollection(asTest, "abcx")

    Debug.Print "ExistsInCollection is okay"
End Sub

컬렉션의 항목이 객체가 아니라 어레이 인 경우 몇 가지 추가 조정이 필요합니다. 그 외에 그것은 나를 위해 잘 작동했습니다.

Public Function CheckExists(vntIndexKey As Variant) As Boolean
    On Error Resume Next
    Dim cObj As Object

    ' just get the object
    Set cObj = mCol(vntIndexKey)

    ' here's the key! Trap the Error Code
    ' when the error code is 5 then the Object is Not Exists
    CheckExists = (Err <> 5)

    ' just to clear the error
    If Err <> 0 Then Call Err.Clear
    Set cObj = Nothing
End Function

원천: http://coderstalk.blogspot.com/2007/09/visual-basic-programming-how-to-check.html

Key가 수집에 사용되지 않은 경우 :

Public Function Contains(col As Collection, thisItem As Variant) As   Boolean

  Dim item As Variant

  Contains = False
  For Each item In col
    If item = thisItem Then
      Contains = True
      Exit Function
    End If
  Next
End Function

나의 코드,하지만 그것은 아주 멋지게 된다.그것은을 확인할 수 있습에 의하여 열쇠 뿐 아니라 개체에 의해 요소는 자체와 손잡이 모두에 오류 방법과 반복을 통해 모든 요소입니다.

https://danwagner.co/how-to-check-if-a-collection-contains-an-object/

겠지 않은 복사본을 전체 설명이기 때문에 사용할 수 있게 되었습니다.자체 솔루션에서 복사한 케이스 페이지로 결국 사용할 수 없다.

의심가 코드에 대한은 overusage 의 고토에서 처음으면 차단 하는 쉽게 해결을 위해 누군가는 그렇게 나를 떠나본 코드로 그것입니다.

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'INPUT       : Kollection, the collection we would like to examine
'            : (Optional) Key, the Key we want to find in the collection
'            : (Optional) Item, the Item we want to find in the collection
'OUTPUT      : True if Key or Item is found, False if not
'SPECIAL CASE: If both Key and Item are missing, return False
Option Explicit
Public Function CollectionContains(Kollection As Collection, Optional Key As Variant, Optional Item As Variant) As Boolean
    Dim strKey As String
    Dim var As Variant

    'First, investigate assuming a Key was provided
    If Not IsMissing(Key) Then

        strKey = CStr(Key)

        'Handling errors is the strategy here
        On Error Resume Next
            CollectionContains = True
            var = Kollection(strKey) '<~ this is where our (potential) error will occur
            If Err.Number = 91 Then GoTo CheckForObject
            If Err.Number = 5 Then GoTo NotFound
        On Error GoTo 0
        Exit Function

CheckForObject:
        If IsObject(Kollection(strKey)) Then
            CollectionContains = True
            On Error GoTo 0
            Exit Function
        End If

NotFound:
        CollectionContains = False
        On Error GoTo 0
        Exit Function

    'If the Item was provided but the Key was not, then...
    ElseIf Not IsMissing(Item) Then

        CollectionContains = False '<~ assume that we will not find the item

        'We have to loop through the collection and check each item against the passed-in Item
        For Each var In Kollection
            If var = Item Then
                CollectionContains = True
                Exit Function
            End If
        Next var

    'Otherwise, no Key OR Item was provided, so we default to False
    Else
        CollectionContains = False
    End If

End Function

나는 Vadims 코드의 변형 인 것처럼 이것을 좋아했지만 조금 더 읽을 수 있습니다.

' Returns TRUE if item is already contained in collection, otherwise FALSE

Public Function Contains(col As Collection, item As String) As Boolean

    Dim i As Integer

    For i = 1 To col.Count

    If col.item(i) = item Then
        Contains = True
        Exit Function
    End If

    Next i

    Contains = False

End Function

나는이 코드를 썼다. 누군가를 도울 수 있다고 생각합니다 ...

Public Function VerifyCollection()
    For i = 1 To 10 Step 1
       MyKey = "A"
       On Error GoTo KillError:
       Dispersao.Add 1, MyKey
       GoTo KeepInForLoop
KillError: 'If My collection already has the key A Then...
        count = Dispersao(MyKey)
        Dispersao.Remove (MyKey)
        Dispersao.Add count + 1, MyKey 'Increase the amount in relationship with my Key
        count = Dispersao(MyKey) 'count = new amount
        On Error GoTo -1
KeepInForLoop:
    Next
End Function
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top