arrays - longitud - VBA(Excel) inicializa toda la matriz sin bucle
vba array function (7)
Quiero inicializar cada elemento de la matriz con un valor inicial. Entonces, si tengo una matriz Dim myArray (300) Como Entero de 300 enteros, por ejemplo, los 300 elementos tendrían el mismo valor inicial (por ejemplo, el número 13).
¿Alguien puede explicar cómo hacer esto, sin bucles? Me gustaría hacerlo en una declaración si es posible.
¿Qué gano?
Sub SuperTest()
Dim myArray
myArray = Application.Transpose([index(Row(1:300),)-index(Row(1:300),)+13])
End Sub
Soy bastante nuevo en VBA, así que esta puede ser una pregunta simple, pero aquí va.
Me gustaría inicializar una matriz completa myArray
, digamos de enteros, en VBA. Sé que puedo hacer esto con una inicialización simple como esta:
Dim myArray
myArray = Array(1, 2, 4, 8)
Pero si la matriz es grande, esto es engorroso, y me gustaría inicializar todos los elementos con el mismo valor. Idealmente sería algo como esto:
myArray(:) = 0
Intenté eso pero el compilador se quejó. Luego probé myArray() = 0
y se quejó de eso también.
¿Alguien puede explicar cómo hacer esto, sin bucles ? Me gustaría hacerlo en una declaración si es posible.
Aclaración :
Quiero inicializar cada elemento de la matriz con un valor inicial. Entonces, si tengo una matriz Dim myArray(300) As Integer
de 300 enteros, por ejemplo, los 300 elementos tendrían el mismo valor inicial (por ejemplo, el número 13).
Más aclaración
Encontré esta respuesta que dice que puedes hacer esto con una variable como esta:
Dim x As Double: x = 0
Tal vez hay una forma de actualizar la sintaxis un poco para que sea aplicable a las matrices.
Esta función trabaja con variables de tamaño y valor inicial, combina respuestas de tbur y Filipe.
Function ArrayIniValue(iSize As Integer, iValue As Integer)
Dim sIndex As String
sIndex = "INDEX(Row(1:" & iSize & "),)"
ArrayIniValue = Evaluate("=Transpose(" & sIndex & "-" & sIndex & "+" & iValue & ")")
End Function
Llamado de esta manera:
myArray = ArrayIniValue(350, 13)
Esto es fácil, al menos si desea una matriz de variantes 1D, 1D o 2D:
Sub StuffVArr()
Dim v() As Variant
Dim q() As Variant
v = Evaluate("=IF(ISERROR(A1:K1), 13, 13)")
q = Evaluate("=IF(ISERROR(A1:G48), 13, 13)")
End Sub
Las matrices de bytes tampoco son tan malas:
Private Declare Sub FillMemory Lib "kernel32" Alias "RtlFillMemory" _
(dest As Any, ByVal size As Long, ByVal fill As Byte)
Sub StuffBArr()
Dim i(0 To 39) As Byte
Dim j(1 To 2, 5 To 29, 2 To 6) As Byte
FillMemory i(0), 40, 13
FillMemory j(1, 5, 2), 2 * 25 * 5, 13
End Sub
Puede usar el mismo método para completar matrices de otros tipos de datos numéricos, pero está limitado a solo valores que se pueden representar con un único byte repetitivo:
Sub StuffNArrs()
Dim i(0 To 4) As Long
Dim j(0 To 4) As Integer
Dim u(0 To 4) As Currency
Dim f(0 To 4) As Single
Dim g(0 To 4) As Double
FillMemory i(0), 5 * LenB(i(0)), &HFF ''gives -1
FillMemory i(0), 5 * LenB(i(0)), &H80 ''gives -2139062144
FillMemory i(0), 5 * LenB(i(0)), &H7F ''gives 2139062143
FillMemory j(0), 5 * LenB(j(0)), &HFF ''gives -1
FillMemory u(0), 5 * LenB(u(0)), &HFF ''gives -0.0001
FillMemory f(0), 5 * LenB(f(0)), &HFF ''gives -1.#QNAN
FillMemory f(0), 5 * LenB(f(0)), &H80 ''gives -1.18e-38
FillMemory f(0), 5 * LenB(f(0)), &H7F ''gives 3.40e+38
FillMemory g(0), 5 * LenB(g(0)), &HFF ''gives -1.#QNAN
End Sub
Si desea evitar un bucle en otras situaciones, se vuelve aún más peludo. Realmente no vale la pena a menos que su matriz tenga 50,000 entradas o más. Simplemente establece cada valor en un bucle y serás lo suficientemente rápido , como ya mencioné en una respuesta anterior .
Para VBA, necesita inicializar en dos líneas.
Sub TestArray()
Dim myArray
myArray = Array(1, 2, 4, 8)
End Sub
Puede inicializar la matriz especificando las dimensiones. Por ejemplo
Dim myArray(10) As Integer
Dim myArray(1 to 10) As Integer
Si está trabajando con arreglos y si esta es la primera vez, le recomendaría visitar el WEBSITE Chip Pearson.
¿A qué se inicializa esto? Por ejemplo, ¿qué pasa si quiero inicializar toda la matriz a 13?
Cuando desee initailizar la matriz de 13 elementos, puede hacerlo de dos maneras
Dim myArray(12) As Integer
Dim myArray(1 to 13) As Integer
En el primero, el límite inferior de la matriz comenzaría con 0
por lo que puede almacenar 13 elementos en la matriz. Por ejemplo
myArray(0) = 1
myArray(1) = 2
''
''
''
myArray(12) = 13
En el segundo ejemplo, ha especificado los límites inferiores como 1
por lo que su matriz comienza con 1
y puede volver a almacenar 13 valores.
myArray(1) = 1
myArray(2) = 2
''
''
''
myArray(13) = 13
Cuando inicialice una matriz utilizando cualquiera de los métodos anteriores, el valor de cada elemento en la matriz es igual a 0
. Para comprobar que pruebe este código.
Sub Sample()
Dim myArray(12) As Integer
Dim i As Integer
For i = LBound(myArray) To UBound(myArray)
Debug.Print myArray(i)
Next i
End Sub
o
Sub Sample()
Dim myArray(1 to 13) As Integer
Dim i As Integer
For i = LBound(myArray) To UBound(myArray)
Debug.Print myArray(i)
Next i
End Sub
SEGUIMIENTO DE COMENTARIOS
Entonces, en este ejemplo, cada valor sería 13. Entonces, si tuviera una matriz Dim myArray (300) como entero, los 300 elementos tendrían el valor 13
Como mencioné, AFAIK, no hay una manera directa de lograr lo que quieres. Habiendo dicho eso, aquí hay una manera que usa la función de la hoja de cálculo Rept
para crear una cadena repetitiva de 13. Una vez que tenemos esa cadena, podemos usar SPLIT
usando ","
como un delimitador. Pero tenga en cuenta que esto crea una matriz variante, pero puede utilizarse en los cálculos.
Tenga en cuenta también que, en los ejemplos siguientes, myArray
tendrá en realidad 301 valores de los cuales el último está vacío; deberá contabilizarlo inicializando adicionalmente este valor o eliminando el último "," de sNum
antes de la operación de Split
.
Sub Sample()
Dim sNum As String
Dim i As Integer
Dim myArray
''~~> Create a string with 13 three hundred times separated by comma
''~~> 13,13,13,13...13,13 (300 times)
sNum = WorksheetFunction.Rept("13,", 300)
sNum = Left(sNum, Len(sNum) - 1)
myArray = Split(sNum, ",")
For i = LBound(myArray) To UBound(myArray)
Debug.Print myArray(i)
Next i
End Sub
Usar la matriz variante en los cálculos
Sub Sample()
Dim sNum As String
Dim i As Integer
Dim myArray
''~~> Create a string with 13 three hundred times separated by comma
sNum = WorksheetFunction.Rept("13,", 300)
sNum = Left(sNum, Len(sNum) - 1)
myArray = Split(sNum, ",")
For i = LBound(myArray) To UBound(myArray)
Debug.Print Val(myArray(i)) + Val(myArray(i))
Next i
End Sub
Un método que se puede usar para asignar valores a elementos completos de una matriz es colocar los datos en una hoja de cálculo no utilizada y luego volver a leer los valores de la hoja de trabajo en la matriz. Por ejemplo, quiero asignar valores de 123 a elementos completos de una matriz de 5x5. Aquí está el código de una línea para implementar tal tarea:
ReDim MyArray(1 To 5, 1 To 5): Range("A1:E5") = 123: MyArray = Range("A1:E5")
Aunque es un poco lento pero funciona bien. También puede eliminar la declaración de matriz.
Range("A1:E5") = 123: MyArray = Range("A1:E5")
De hecho, puede cambiar el valor de algunos elementos fácilmente. Por ejemplo, suponga que desea cambiar el valor de los elementos MyArray (1,1), MyArray (1,5), MyArray (3,3), MyArray (5,1) y MyArray (5,5) a 789 , entonces el código será así
Range("A1:E5") = 123: Range("A1,E1,C3,A5,E5") = 789: MyArray = Range("A1:E5")
Una manera elegante de poner la respuesta @rdhs en una función:
Function arrayZero(size As Integer)
arrayZero = Evaluate("=IF(ISERROR(Transpose(A1:A" & size & ")), 0, 0)")
End Function
Y use esto:
myArray = arrayZero(15)