¿VBA tiene Estructura de Diccionario?
¿Tiene VBA estructura de diccionario? Como clave matriz de valor?
9 answers
Sí.
Establezca una referencia al tiempo de ejecución de MS Scripting ('Microsoft Scripting Runtime'). Según el comentario de @regjo, vaya a Herramientas - >Referencias y marque la casilla 'Microsoft Scripting Runtime'.
Cree una instancia de diccionario usando el siguiente código:
Set dict = CreateObject("Scripting.Dictionary")
O
Dim dict As New Scripting.Dictionary
Ejemplo de uso:
If Not dict.Exists(key) Then
dict.Add key, value
End If
No olvide establecer el diccionario en Nothing
cuando haya terminado de usarlo.
Set dict = Nothing
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-27 10:53:30
VBA tiene el objeto collection:
Dim c As Collection
Set c = New Collection
c.Add "Data1", "Key1"
c.Add "Data2", "Key2"
c.Add "Data3", "Key3"
'Insert data via key into cell A1
Range("A1").Value = c.Item("Key2")
El objeto Collection
realiza búsquedas basadas en claves usando un hash para que sea rápido.
Puede usar una función Contains()
para verificar si una colección en particular contiene una clave:
Public Function Contains(col As Collection, key As Variant) As Boolean
On Error Resume Next
col(key) ' Just try it. If it fails, Err.Number will be nonzero.
Contains = (Err.Number = 0)
Err.Clear
End Function
Editar 24 de junio de 2015: Más corto Contains()
gracias a @TWiStErRob.
Editar 25 de septiembre de 2015 : Agregado Err.Clear()
gracias a @scipilot.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-12 20:04:46
VBA no tiene una implementación interna de un diccionario, pero desde VBA aún puede usar el objeto dictionary de la Biblioteca de tiempo de ejecución de MS Scripting.
Dim d
Set d = CreateObject("Scripting.Dictionary")
d.Add "a", "aaa"
d.Add "b", "bbb"
d.Add "c", "ccc"
If d.Exists("c") Then
MsgBox d("c")
End If
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-27 12:19:03
Un ejemplo de diccionario adicional que es útil para contener la frecuencia de ocurrencia.
Fuera del bucle:
Dim dict As New Scripting.dictionary
Dim MyVar as String
Dentro de un bucle:
'dictionary
If dict.Exists(MyVar) Then
dict.Item(MyVar) = dict.Item(MyVar) + 1 'increment
Else
dict.Item(MyVar) = 1 'set as 1st occurence
End If
Para comprobar la frecuencia:
Dim i As Integer
For i = 0 To dict.Count - 1 ' lower index 0 (instead of 1)
Debug.Print dict.Items(i) & " " & dict.Keys(i)
Next i
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-26 13:04:35
Construyendo a partir de la respuesta de cjrh, podemos construir una función Contains que no requiere etiquetas (no me gusta usar etiquetas).
Public Function Contains(Col As Collection, Key As String) As Boolean
Contains = True
On Error Resume Next
err.Clear
Col (Key)
If err.Number <> 0 Then
Contains = False
err.Clear
End If
On Error GoTo 0
End Function
Para un proyecto mío, escribí un conjunto de funciones auxiliares para hacer que un Collection
se comporte más como un Dictionary
. Todavía permite colecciones recursivas. Notarás que la clave siempre viene primero porque era obligatoria y tenía más sentido en mi implementación. También usé solo las teclas String
. Puedes cambiarlo si quieres.
Conjunto
I renombrado esto a set porque sobrescribirá valores antiguos.
Private Sub cSet(ByRef Col As Collection, Key As String, Item As Variant)
If (cHas(Col, Key)) Then Col.Remove Key
Col.Add Array(Key, Item), Key
End Sub
Get
El material err
es para objetos ya que pasarías objetos usando set
y variables sin. Creo que puedes comprobar si es un objeto, pero estaba presionado por el tiempo.
Private Function cGet(ByRef Col As Collection, Key As String) As Variant
If Not cHas(Col, Key) Then Exit Function
On Error Resume Next
err.Clear
Set cGet = Col(Key)(1)
If err.Number = 13 Then
err.Clear
cGet = Col(Key)(1)
End If
On Error GoTo 0
If err.Number <> 0 Then Call err.raise(err.Number, err.Source, err.Description, err.HelpFile, err.HelpContext)
End Function
Tiene
La razón de este post...
Public Function cHas(Col As Collection, Key As String) As Boolean
cHas = True
On Error Resume Next
err.Clear
Col (Key)
If err.Number <> 0 Then
cHas = False
err.Clear
End If
On Error GoTo 0
End Function
Eliminar
No lanza si no existe. Sólo se asegura de que se quite.
Private Sub cRemove(ByRef Col As Collection, Key As String)
If cHas(Col, Key) Then Col.Remove Key
End Sub
Teclas
Obtener una matriz de claves.
Private Function cKeys(ByRef Col As Collection) As String()
Dim Initialized As Boolean
Dim Keys() As String
For Each Item In Col
If Not Initialized Then
ReDim Preserve Keys(0)
Keys(UBound(Keys)) = Item(0)
Initialized = True
Else
ReDim Preserve Keys(UBound(Keys) + 1)
Keys(UBound(Keys)) = Item(0)
End If
Next Item
cKeys = Keys
End Function
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:44
El diccionario de tiempo de ejecución de scripting parece tener un error que puede arruinar su diseño en etapas avanzadas.
Si el valor del diccionario es un array, no puede actualizar los valores de los elementos contenidos en el array a través de una referencia al diccionario.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-02 18:36:53
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-26 12:13:23
Si por alguna razón, no puede instalar características adicionales a su Excel o no desea, también puede usar matrices, al menos para problemas simples. Como WhatIsCapital pones el nombre del país y la función te devuelve su capital.
Sub arrays()
Dim WhatIsCapital As String, Country As Array, Capital As Array, Answer As String
WhatIsCapital = "Sweden"
Country = Array("UK", "Sweden", "Germany", "France")
Capital = Array("London", "Stockholm", "Berlin", "Paris")
For i = 0 To 10
If WhatIsCapital = Country(i) Then Answer = Capital(i)
Next i
Debug.Print Answer
End Sub
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-22 12:29:55
Todos los demás ya han mencionado el uso del scripting.versión en tiempo de ejecución de la clase Dictionary. Si no puede usar esta DLL, también puede usar esta versión, simplemente agréguela a su código.
Https://github.com/VBA-tools/VBA-Dictionary/blob/master/Dictionary.cls
Es idéntico a la versión de Microsoft.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-23 01:27:04