Heredé una gran aplicación VB6 en mi lugar de trabajo actual. Estoy aprendiendo VB6 en el trabajo y tengo varios problemas. El principal problema en este momento es que no puedo averiguar cómo verificar si existe una clave en un objeto Collection. ¿Alguien puede ayudar?¿Verifica si existe un registro en una colección VB6?
Respuesta
que siempre he hecho con una función como esta:
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
@ Marcos Biek Sus keyExists se acerque a mi nivel existe la función(). Para que la clase sea más útil para colecciones expuestas a COM y para verificar índices numéricos, recomiendo cambiar sKey y myCollection para que no se tipeen. Si la función se va a usar con una colección de objetos, se requiere 'set' (en la línea donde se establece val).
EDIT: Me molestaba saber que nunca había notado los diferentes requisitos para una función Exists() basada en objetos y basada en valores. Muy rara vez uso colecciones para objetos no-objetos, pero esto parecía un cuello de botella perfecto para un error que sería tan difícil de rastrear cuando necesitaba verificar la existencia. Debido a que el manejo de errores fallará si un manejador de errores ya está activo, se requieren dos funciones para obtener un nuevo alcance de error. Sólo la función existe() tiene por qué nunca se llamará:
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
y verificar la funcionalidad:
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
Como ha señalado Thomas, necesita configurar un objeto en lugar de Let. He aquí una función general de mi biblioteca que funciona para los tipos de valor y objetos:
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
Como también se aconseja por Thomas, puede cambiar el tipo de colección a objeto de generalizar esto. La sintaxis de .Item (clave) es compartida por la mayoría de las clases de colección, por lo que en realidad podría ser útil.
EDIT Parece que el mismo Thomas me golpeó un poco. Sin embargo, para una reutilización más fácil, personalmente prefiero una única función sin dependencias privadas.
Usar el controlador de errores para detectar casos cuando la clave no existe en la Colección puede hacer que la depuración con la opción "interrumpir todos los errores" sea bastante molesta. Para evitar errores no deseados, muy a menudo creo una clase que tiene los objetos almacenados en una Colección y todas las claves en un Diccionario. El diccionario tiene una función (clave) para poder invocar eso antes de intentar obtener un objeto de la colección. Solo puede almacenar cadenas en un diccionario, por lo que aún se necesita una colección si necesita almacenar objetos.
Eso no está bien: puedes almacenar cualquier tipo de objeto/valor en un Dictiionary https://msdn.microsoft.com/en-us/library/x4k5wbx4%28v= vs.84% 29.aspx "Los elementos pueden ser cualquier tipo de datos" – Clon
Un diccionario simple es suficiente cuando lo único que desea es almacenar una cantidad de valores/objetos junto con una clave y verificar si existe una clave en el diccionario. Si desea asegurarse de que el diccionario contenga solo cierto tipo de datos, debe ajustar el diccionario a un objeto y personalizar sus propiedades y métodos. Esto también se puede hacer con un objeto Collection y el método Exists() dado en otras respuestas. https://msdn.microsoft.com/en-us/library/aa262338%28v=vs.60%29.aspx – Clon
La mejor solución sería escribir una función TryGet. Gran parte del tiempo que va a verificar existe y luego obtiene el artículo. Ahorre tiempo al hacerlo al mismo tiempo.
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
ver http://www.visualbasic.happycodings.com/Other/code10.html la implementación de aquí tiene también la ventaja de devolver opcionalmente el elemento que se encuentra, y trabaja con los tipos de objetos/nativos (de acuerdo con los comentarios).
reproducido aquí, ya que el enlace ya no está disponible:
determinar si existe un elemento en una colección
El código siguiente muestra cómo determinar si existe un elemento dentro de una colección.
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
Mi función estándar es muy simple. Esto funcionará independientemente del tipo de elemento, ya que no molesta hacer ninguna asignación, simplemente ejecuta la obtención get de la propiedad.
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
La declaración "el manejo de errores fallará si un controlador de errores ya está activo" es parcialmente cierto.
Puede tener múltiples manejadores de errores dentro de su rutina.
Entonces, uno podría acomodar la misma funcionalidad en una sola función.
Sólo reescribir su código como este:
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
Sin embargo, si usted fuera sólo para incorporar el código en la sección TryNonObject de la rutina, esto dió la misma información.
Será exitoso tanto para Objetos como para no objetos. Sin embargo, acelerará el código de los objetos que no son, ya que solo tendrías que realizar una única declaración para afirmar que el elemento existe dentro de la colección.
Mientras buscaba una función como esta, la diseñé de la siguiente manera. Esto debería funcionar con objetos y no objetos sin asignar nuevas 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
- 1. ¿Verifica si existe un diseño en Rails?
- 2. ¿Cómo verifica si existe un cierto índice en una tabla?
- 3. Usando WatiN ... verifica si existe un elemento?
- 4. Verifica si existe proc almacenado en DB?
- 5. ¿Verifica si existe papel en DB?
- 6. ¿Verifica si el registro NO existe en Rails (desde una matriz de identificadores)?
- 7. ¿Cómo verifica si existe una tabla con NHibernate (o Fluent)?
- 8. ¿Cómo verifica si existe un nombre de dominio?
- 9. ¿Cómo verifico si existe una clave en un registro?
- 10. Comprobando si existe una clave de registro
- 11. Cakephp comprobar si existe registro
- 12. ¿Cómo saber si existe una colección en MongoDB usando Mongoid?
- 13. ¿Cómo verificar en PyMongo si existe una colección y si existe vacía (eliminar todo de la colección)?
- 14. VB6, archivo no existe, ¿Cómo manejo elegantemente?
- 15. ¿Verifica si una variable contiene un valor numérico en Javascript?
- 16. Si existe el registro, actualice Else Insert
- 17. Javascript - verifica si div contiene una palabra?
- 18. Pruebe si existe valor de registro
- 19. Compruebe si existe la clave de registro
- 20. Magento - ¿Verifica si hay un módulo instalado?
- 21. ¿Verifica si un NSMutableDictionary está vacío?
- 22. SQLite Consulta para insertar un registro Si no existe
- 23. Cómo verificar si existe un registro usando JPA
- 24. ¿Cómo INSERTAR un registro o ACTUALIZAR si ya existe?
- 25. ¿Cómo verificar si existe un valor de registro usando C#?
- 26. Estructura de datos para consultar si existe un subconjunto dado en una colección de conjuntos
- 27. ¿Verifica si existe una columna de lista con el modelo de objetos de cliente de SharePoint?
- 28. VB6: cómo crear un archivo de registro en VB6 al iniciar la aplicación
- 29. Comprobar si la cadena/registro existe en DataTable
- 30. verifica si largeAddressAware está en efecto?
Para evitar este problema, es mejor omitir la parte de asignación, es decir, la caída de las instrucciones establecidas o = col (índice) o v = col (índice) y la declaración de variables, y simplemente escribir col. índice de elemento, que funciona igual con objetos y valores simples. – Clon
Ahora veo que esto ya fue demostrado por Christian Hayter – Clon