Parece que no encuentro la documentación que explica cómo crear una tabla hash o una matriz asociativa en VBA. ¿Es posible?Tabla hash/matriz asociativa en VBA
¿Se puede vincular a un artículo o mejor aún publicar el código?
Parece que no encuentro la documentación que explica cómo crear una tabla hash o una matriz asociativa en VBA. ¿Es posible?Tabla hash/matriz asociativa en VBA
¿Se puede vincular a un artículo o mejor aún publicar el código?
creo que busca el objeto Dictionary, que se encuentra en la biblioteca Microsoft Scripting Runtime. (Agregue una referencia a su proyecto desde el menú Herramientas ... Referencias en el VBE.)
Funciona prácticamente con cualquier valor simple que pueda caber en una variante (Las claves no pueden ser matrices, y tratando de hacer convierten en objetos no tiene mucho sentido Véase el comentario de @Nile abajo):..
Dim d As dictionary
Set d = New dictionary
d("x") = 42
d(42) = "forty-two"
d(CVErr(xlErrValue)) = "Excel #VALUE!"
Set d(101) = New Collection
también puede utilizar el objeto VBA Colección si sus necesidades son más simples y que sólo quieren claves de cadena.
No sé si en realidad has hash en nada, por lo que es posible que quieras profundizar si necesitas un rendimiento similar al de hashtable. (EDITAR: Scripting.Dictionary usa internamente un hash table)
sí - el diccionario es la respuesta. Encontré la respuesta en este sitio, también. http://stackoverflow.com/questions/915317/does-vba-have-dictionary-structure – user158017
Esa es una buena respuesta: pero las claves nunca son objetos, lo que realmente está sucediendo es que la propiedad predeterminada del objeto es el lanzamiento como una cadena y se utiliza como la clave. Esto no funciona si el objeto no tiene definida ninguna propiedad predeterminada (generalmente 'nombre'). –
@Nile, gracias. Veo que de hecho estás en lo cierto. También parece que si el objeto no tiene una propiedad predeterminada, la clave del diccionario correspondiente es 'Vacío '. Edité la respuesta en consecuencia. – jtolle
Pruebe usar el objeto de diccionario o el objeto de colección.
http://visualbasic.ittoolbox.com/documents/dictionary-object-vs-collection-object-12196
He usado Francesco Balena's HashTable class varias veces en el pasado cuando una colección o un diccionario no encajaban perfectamente y solo necesitaba una HashTable.
Aquí vamos ... sólo tienes que copiar el código a un módulo, que está listo para usar
Private Type hashtable
key As Variant
value As Variant
End Type
Private GetErrMsg As String
Private Function CreateHashTable(htable() As hashtable) As Boolean
GetErrMsg = ""
On Error GoTo CreateErr
ReDim htable(0)
CreateHashTable = True
Exit Function
CreateErr:
CreateHashTable = False
GetErrMsg = Err.Description
End Function
Private Function AddValue(htable() As hashtable, key As Variant, value As Variant) As Long
GetErrMsg = ""
On Error GoTo AddErr
Dim idx As Long
idx = UBound(htable) + 1
Dim htVal As hashtable
htVal.key = key
htVal.value = value
Dim i As Long
For i = 1 To UBound(htable)
If htable(i).key = key Then Err.Raise 9999, , "Key [" & CStr(key) & "] is not unique"
Next i
ReDim Preserve htable(idx)
htable(idx) = htVal
AddValue = idx
Exit Function
AddErr:
AddValue = 0
GetErrMsg = Err.Description
End Function
Private Function RemoveValue(htable() As hashtable, key As Variant) As Boolean
GetErrMsg = ""
On Error GoTo RemoveErr
Dim i As Long, idx As Long
Dim htTemp() As hashtable
idx = 0
For i = 1 To UBound(htable)
If htable(i).key <> key And IsEmpty(htable(i).key) = False Then
ReDim Preserve htTemp(idx)
AddValue htTemp, htable(i).key, htable(i).value
idx = idx + 1
End If
Next i
If UBound(htable) = UBound(htTemp) Then Err.Raise 9998, , "Key [" & CStr(key) & "] not found"
htable = htTemp
RemoveValue = True
Exit Function
RemoveErr:
RemoveValue = False
GetErrMsg = Err.Description
End Function
Private Function GetValue(htable() As hashtable, key As Variant) As Variant
GetErrMsg = ""
On Error GoTo GetValueErr
Dim found As Boolean
found = False
For i = 1 To UBound(htable)
If htable(i).key = key And IsEmpty(htable(i).key) = False Then
GetValue = htable(i).value
Exit Function
End If
Next i
Err.Raise 9997, , "Key [" & CStr(key) & "] not found"
Exit Function
GetValueErr:
GetValue = ""
GetErrMsg = Err.Description
End Function
Private Function GetValueCount(htable() As hashtable) As Long
GetErrMsg = ""
On Error GoTo GetValueCountErr
GetValueCount = UBound(htable)
Exit Function
GetValueCountErr:
GetValueCount = 0
GetErrMsg = Err.Description
End Function
para utilizar en su VB (A) Aplicación:
Public Sub Test()
Dim hashtbl() As hashtable
Debug.Print "Create Hashtable: " & CreateHashTable(hashtbl)
Debug.Print ""
Debug.Print "ID Test Add V1: " & AddValue(hashtbl, "Hallo_0", "Testwert 0")
Debug.Print "ID Test Add V2: " & AddValue(hashtbl, "Hallo_0", "Testwert 0")
Debug.Print "ID Test 1 Add V1: " & AddValue(hashtbl, "Hallo.1", "Testwert 1")
Debug.Print "ID Test 2 Add V1: " & AddValue(hashtbl, "Hallo-2", "Testwert 2")
Debug.Print "ID Test 3 Add V1: " & AddValue(hashtbl, "Hallo 3", "Testwert 3")
Debug.Print ""
Debug.Print "Test 1 Removed V1: " & RemoveValue(hashtbl, "Hallo_1")
Debug.Print "Test 1 Removed V2: " & RemoveValue(hashtbl, "Hallo_1")
Debug.Print "Test 2 Removed V1: " & RemoveValue(hashtbl, "Hallo-2")
Debug.Print ""
Debug.Print "Value Test 3: " & CStr(GetValue(hashtbl, "Hallo 3"))
Debug.Print "Value Test 1: " & CStr(GetValue(hashtbl, "Hallo_1"))
Debug.Print ""
Debug.Print "Hashtable Content:"
For i = 1 To UBound(hashtbl)
Debug.Print CStr(i) & ": " & CStr(hashtbl(i).key) & " - " & CStr(hashtbl(i).value)
Next i
Debug.Print ""
Debug.Print "Count: " & CStr(GetValueCount(hashtbl))
End Sub
No voy a rechazar un nuevo usuario que publique código, pero por lo general llamar a algo una "tabla hash" implica que la implementación subyacente es en realidad una tabla hash. Lo que tienes aquí es una matriz asociativa implementada con una matriz regular más una búsqueda lineal. Vea aquí la diferencia: http://en.wikipedia.org/wiki/Hash_table – jtolle
De hecho. El punto de una tabla hash es la 'hash' de la clave que conduce a la ubicación de su valor en el almacenamiento subyacente (o al menos lo suficientemente cerca, en el caso de claves duplicadas), eliminando así la necesidad de una búsqueda potencialmente costosa. –
Demasiado lento para hashtables más grandes. Agregar 17,000 entradas lleva más de 15 segundos. Puedo agregar 500,000 en menos de 6 segundos usando el diccionario. 500,000 en menos de 3 segundos usando mschlib hashtable. –
posible duplicado de [¿El VBA tiene estructura de diccionario?] (Http://stackoverflow.com/questions/915317/does-vba-have-dictionary-structure) – Mark