Vérifier si un enregistrement existe dans une collection VB6?

j'ai hérité d'une grande application VB6 sur mon lieu de travail actuel. J'apprends un peu le VB6 au travail et il y a un certain nombre de problèmes que j'ai. Le problème principal pour le moment est que je ne peux pas trouver comment vérifier si une clé existe dans un objet de Collection. Quelqu'un peut-il aider?

18
demandé sur user4315 2008-09-03 01:00:27

9 réponses

Ma fonction standard est très simple. Cela fonctionnera quel que soit le type d'élément, puisqu'il ne prend pas la peine de faire n'importe quelle tâche, il exécute simplement la propriété de collection get.

Public Function Exists(ByVal oCol As Collection, ByVal vKey As Variant) As Boolean

    On Error Resume Next
    oCol.Item vKey
    Exists = (Err.Number = 0)
    Err.Clear

End Function
26
répondu Christian Hayter 2009-12-01 10:57:21

@Mark Biek vos keyExists correspondent étroitement à ma fonction standard Exists (). Pour rendre la classe plus utile pour les collections COM-exposées et la vérification des index numériques, je recommande de changer sKey et myCollection de ne pas être dactylographié. Si la fonction doit être utilisée avec une collection d'objets, 'set' est requis (sur la ligne où val est défini).

EDIT: c'était gênant que je n'ai jamais remarqué d'exigences différentes pour un objet basé sur la valeur Exists() fonction. J'utilise très rarement des collections pour des non-objets, mais cela semblait être un goulot d'étranglement parfait pour un bogue qui serait si difficile à dépister lorsque je devais vérifier l'existence. Parce que la gestion des erreurs échouera si un gestionnaire d'erreurs est déjà actif, deux fonctions sont nécessaires pour obtenir une nouvelle portée d'erreur. Seule la fonction Exists () doit jamais être appelée:

Public Function Exists(col, index) As Boolean
On Error GoTo ExistsTryNonObject
    Dim o As Object

    Set o = col(index)
    Exists = True
    Exit Function

ExistsTryNonObject:
    Exists = ExistsNonObject(col, index)
End Function

Private Function ExistsNonObject(col, index) As Boolean
On Error GoTo ExistsNonObjectErrorHandler
    Dim v As Variant

    v = col(index)
    ExistsNonObject = True
    Exit Function

ExistsNonObjectErrorHandler:
    ExistsNonObject = False
End Function

Et pour vérifier la fonctionnalité:

Public Sub TestExists()
    Dim c As New Collection

    Dim b As New Class1

    c.Add "a string", "a"
    c.Add b, "b"

    Debug.Print "a", Exists(c, "a") ' True '
    Debug.Print "b", Exists(c, "b") ' True '
    Debug.Print "c", Exists(c, "c") ' False '
    Debug.Print 1, Exists(c, 1) ' True '
    Debug.Print 2, Exists(c, 2) ' True '
    Debug.Print 3, Exists(c, 3) ' False '
End Sub
22
répondu Thomas G. Mayfield 2014-06-09 18:23:18

je l'ai toujours fait avec une fonction comme ceci:

public function keyExists(myCollection as collection, sKey as string) as Boolean
  on error goto handleerror:

  dim val as variant

  val = myCollection(sKey)
  keyExists = true
  exit sub
handleerror:
  keyExists = false
end function
8
répondu Mark Biek 2008-09-02 21:02:09

comme le souligne Thomas, vous devez définir un objet au lieu de Let. Voici une fonction générale de ma bibliothèque qui fonctionne pour les types de valeurs et d'objets:

Public Function Exists(ByVal key As Variant, ByRef col As Collection) As Boolean

'Returns True if item with key exists in collection

On Error Resume Next

Const ERR_OBJECT_TYPE As Long = 438
Dim item As Variant

'Try reach item by key
item = col.item(key)

'If no error occurred, key exists
If Err.Number = 0 Then
    Exists = True

'In cases where error 438 is thrown, it is likely that
'the item does exist, but is an object that cannot be Let
ElseIf Err.Number = ERR_OBJECT_TYPE Then

    'Try reach object by key
    Set item = col.item(key)

    'If an object was found, the key exists
    If Not item Is Nothing Then
        Exists = True
    End If

End If

Err.Clear

End Function

comme aussi conseillé par Thomas, vous pouvez changer le type de Collection en objet pour généraliser ceci. Le. La syntaxe de l'élément(clé) est partagée par la plupart des classes de collection, de sorte que cela pourrait en fait être utile.

EDIT il semble que J'ai été battu à plate couture par Thomas lui-même. Cependant pour une réutilisation plus facile Personnellement, je préfère une seule fonction sans dépendance privée.

5
répondu jevakallio 2008-09-02 22:29:36

utiliser le gestionnaire d'erreurs pour saisir les cas où la clé n'existe pas dans la Collection peut rendre le débogage avec l'option "casser sur toutes les erreurs" assez ennuyeux. Pour éviter les erreurs indésirables je crée assez souvent une classe qui a les objets stockés dans une Collection et toutes les clés dans un dictionnaire. Dictionnaire a existe(clé) -fonction donc je ne peux appeler que avant d'essayer d'obtenir un objet de la collection. Vous ne pouvez stocker des cordes dans un dictionnaire, donc une Collection est encore nécessaire si vous avez besoin de stocker objet.

3
répondu Kaniu 2008-09-09 19:52:44

l'énoncé "la gestion des erreurs échouera si un gestionnaire d'erreurs est déjà actif" n'est que partiellement exact.

Vous pouvez avoir plusieurs gestionnaires d'erreur dans votre routine.

Ainsi, on pourrait accommoder la même fonctionnalité dans une seule fonction.

Juste de réécrire votre code comme ceci:

Public Function Exists(col, index) As Boolean
Dim v As Variant

TryObject:
    On Error GoTo ExistsTryObject
        Set v = col(index)
        Exists = True
        Exit Function

TryNonObject:
    On Error GoTo ExistsTryNonObject

        v = col(index)
        Exists = True
        Exit Function

ExistsTryObject:
   ' This will reset your Err Handler
   Resume TryNonObject

ExistsTryNonObject:
        Exists = False
End Function

cependant, si vous deviez seulement incorporer le code dans la section TryNonObject de la routine, cela donnerait le même information.

Il réussira à la fois pour les objets et pour les non-objets. Il accélérera votre code pour les non-objets, cependant, puisque vous n'aurez à effectuer qu'une seule déclaration pour affirmer que l'article existe dans la collection.

3
répondu R. van Drie 2012-03-02 16:21:32

La meilleure solution serait d'écrire une fonction TryGet. Beaucoup du temps que vous allez vérifier existe, puis obtenir l'élément. Gagnez du temps en le faisant en même temps.

public Function TryGet(key as string, col as collection) as Variant
  on error goto errhandler
  Set TryGet= col(key)
  exit function
errhandler:
  Set TryGet = nothing  
end function
2
répondu Pedro Fialho 2013-04-08 13:00:37

voir http://www.visualbasic.happycodings.com/Other/code10.html l'implémentation a ici l'avantage de retourner aussi l'élément trouvé en option, et fonctionne avec des types objet/natif (selon les commentaires).

reproduit ici puisque le lien n'est plus disponible à:

déterminer si un article existe dans une collection

Le code suivant vous montre comment déterminer si un élément existe dans un collection.

Option Explicit

'Purpose     :  Determines if an item already exists in a collection
'Inputs      :  oCollection         The collection to test for the existance of the item
'               vIndex              The index of the item.
'               [vItem]             See Outputs
'Outputs     :  Returns True if the item already exists in the collection.
'               [vItem] The value of the item, if it exists, else returns "empty".
'Notes       :
'Example     :

Function CollectionItemExists(vIndex As Variant, oCollection As Collection, Optional vItem As Variant) As Boolean
    On Error GoTo ErrNotExist

    'Clear output result
    If IsObject(vItem) Then
        Set vItem = Nothing
    Else
        vItem = Empty
    End If

    If VarType(vIndex) = vbString Then
        'Test if item exists
        If VarType(oCollection.Item(CStr(vIndex))) = vbObject Then
            'Return an object
            Set vItem = oCollection.Item(CStr(vIndex))
        Else
            'Return an standard variable
            vItem = oCollection.Item(CStr(vIndex))
        End If
    Else
        'Test if item exists
        If VarType(oCollection.Item(Int(vIndex))) = vbObject Then
            'Return an object
            Set vItem = oCollection.Item(Int(vIndex))
        Else
            'Return an standard variable
            vItem = oCollection.Item(Int(vIndex))
        End If
    End If
    'Return success
    CollectionItemExists = True
    Exit Function
ErrNotExist:
    CollectionItemExists = False
    On Error GoTo 0
End Function

'Demonstration routine
Sub Test()
    Dim oColl As New Collection, oValue As Variant

    oColl.Add "red1", "KEYA"
    oColl.Add "red2", "KEYB"
    'Return the two items in the collection
    Debug.Print CollectionItemExists("KEYA", oColl, oValue)
    Debug.Print "Returned: " & oValue
    Debug.Print "-----------"
    Debug.Print CollectionItemExists(2, oColl, oValue)
    Debug.Print "Returned: " & oValue
    'Should fail
    Debug.Print CollectionItemExists("KEYC", oColl, oValue)
    Debug.Print "Returned: " & oValue
    Set oColl = Nothing
End Sub
2
répondu Vijay 2017-01-31 08:24:34

en cherchant une fonction comme celle-ci, je l'ai conçue comme suit. Cela devrait fonctionner avec les objets et les non-objets sans affecter de nouvelles variables.

Public Function Exists(ByRef Col As Collection, ByVal Key) As Boolean
    On Error GoTo KeyError
    If Not Col(Key) Is Nothing Then
        Exists = True
    Else
        Exists = False
    End If

    Exit Function
KeyError:
    Err.Clear
    Exists = False
End Function
0
répondu Martin 2013-03-05 10:22:35