Array
Multidimensional
|
Realizamos
programas para la gestión de empresas. Empresas medianas y
pequeñas. Programas de contabilidad, cartera de pedidos
clientes proveedores, facturación control de albaranes,
tesorería cartera de cobros y pagos y estadísticas.
Nuestro
agradecimiento a todos los que por unas causas o por otras
visitan nuestra web. Gestión de empresas PYMES. Curso de
programación de Visual Basic.
|
Hola, ya estoy de nuevo por estos
lares... para seguir dándole caña al curso básico.
La entrega anterior fue un pequeño alto en el camino antes de
continuar nuestra andadura por los escabrosos caminos de los
arrays... ¡UF! ¿Quién ese ese que escribe? ¡¡¡Guille!!!
Arrays Multidimensionales
En algunas ocasiones hasta los
arrays se quedan cortos... al menos los arrays simples o
unidimensionales, (una sola dimensión), si en el ejemplo de la
octava entrega, el de los rascamientos, quisieras saber las veces
que te has rascado cada día del mes... tendríamos otra vez el
problema, podríamos usar un array para cada día del mes: Dia1(24),
Dia2(24)... pero de nuevo tendríamos complicaciones para algunos
cálculos...
Por suerte para nosotros, existe otra forma de usar los arrays.
En nuestro caso nos serviría el que los arrays tuviesen dos
dimensiones, al estilo de una tabla con filas para cada día del mes
y columnas para cada una de las horas del día en cuestión, para
hacer esto, dimensionaremos un array de esta forma:
Dim Dias(31, 24) As Integer
Para guardar o recuperar un valor lo haremos de la misma forma que
con un array simple, pero especificando dos valores separados por
una coma:
Dias(DiaMes, HoraDia) = 1
y por supuesto, podemos usarlo con bucles FOR:
For Dia = 1 To 31
For Hora = 1 To 24
RascadasMes = RascadasMes + Dias(Dia, Hora)
Next
Next
Después que estos dos bucles
terminen, la variable RascadasMes tendrá el total de veces que nos
hemos rascado cada uno de los días del mes que estamos procesando.
Si queremos almacenar las rascadas de cada día de cada mes de un
año, No Problem!
Dim Meses(12, 31, 24) As Integer
De esta forma solucionaríamos en problema, ya que al añadir una
tercera dimensión, podemos usar esta para cada uno de los meses,
por ejemplo, el total de veces que nos hayamos rascado a las 22
horas del día 30 del mes 9 (septiembre), estaría en: Meses(9, 30,
22)
Reconozco que este ejemplo de las
rascada no es útil, pero por lo menos hemos visto cómo usar los
arrays.
Recuerda que los arrays pueden ser de cualquier tipo: Integer,
String, Double, etc.
¿Cuántos elementos tiene
un array?
En algunas ocasiones podemos
necesitar saber el número de elementos contenidos en un array, para
estos casos existen dos funciones, una para saber el índice menor y
otra para saber el mayor.
Por ejemplo si tenemos este array: Horas(8 To 22)
El menor sería 8 y el mayor 22, para averiguarlo:
Menor = LBound(Horas)
Mayor = UBound(Horas)
Esta forma es para los arrays
unidimensionales, para averiguar estos valores en arrays con más de
una dimensión, tendremos que especificar la dimensión de la que
queremos averiguar ese valor menor o mayor, por ejemplo, si tenemos
Dias(1 To 31, 0 To 23)
MenorMes = LBound(Dias,1) 'Devolvería 1
MayorMes = Ubound(Dias, 1) 'Devolvería 31
MenorHora = LBound(Dias, 2) 'Devolvería 0
MayorHora = UBound(Dias, 2) 'Devolvería 23
Redimensionando arrays
multidimensionales
Veamos ahora cómo funciona el
Redim y Redim Preserve con los arrays con varias dimensiones: igual
Sí, da lo mismo que el array tenga una o muchas dimensiones. Lo
único que debemos saber es que no podemos cambiar el número de
dimensiones, aunque sí el número de elementos de cada una de las
dimensiones.
Un ejemplo:
Tenemos inicialmente esta declaración: Dim Meses(1 To 6, 1 To 31, 0
To 23) As Integer
y necesitamos ampliar la primera dimensión de 6 a 12:
Redim Meses(1 To 12, 1 To 31, 0 To 23) o
Redim Preserve Meses(1 To 12, 1 To 31, 0 To 23) si queremos
conservar los valores almacenados.
Lo que no podemos hacer es esto: Redim Meses(1 To 31, 0 To 23)
porque pasamos de tener tres dimensiones a pretender tener sólo dos
y eso, no está permitido.
Ni al revés tampoco, es decir si tenemos un array con dos
dimensiones y queremos que tenga tres.
Si queremos hacer esto último, tendremos que eliminar el primer
array y volver a dimensionarlo con las dimensiones que queramos
tener:
Dim Dias(31, 24)
Erase Dias
Dim Dias(12, 31, 24)
El problema es que perdemos los datos... cosa que, en caso de
necesidad, podríamos solucionar copiando los datos a otra variable
y volviendo a asignarla al nuevo array dimensionado...
Pero muchos de estos problemas se
solucionan con las colecciones y el uso del tipo Variant, así como
con los objetos o clases definidas por nosotros... pero eso será
más adelante... todavía hay muchas otras cosas
"esenciales" que aprender y conceptos que siempre debes
tener en cuenta... que poco a poco estoy intentando recalcar para
que tu "coco" vaya asimilándolos... espero conseguirlo.
¿Cuantas dimensiones puede
tener un array?
Si la mente no me falla, el número
de dimensiones es 256. ¿Quién necesita tantas?
Los valores menor y mayor de los índices están comprendidos dentro
del rango de un valor Integer del VB, es decir entre -32768 y 32767
o sea 65536 valores o índices distintos. Esto lo comento como
"curiosidad" pero deberías comprobarlo en los manuales.
Unas cadenas, por favor
Ya he comentado en la octava
entrega que los arrays también permiten asignar cadenas de
caracteres, realmente se pueden tener arrays de cualquier tipo de
variables. Pero no mezcladas. Si un array se dimensiona del tipo
Integer sólo podremos almacenar valores numéricos enteros. Incluso
cuando lo Redimensionemos deberá tener el mismo tipo con el que en
un principio lo habíamos dimensionado. Este inconveniente se
solucionará en una próxima entrega y con las colecciones.
Con lo que sabemos hasta ahora es con lo que vamos a trabajar. Y
vamos a practicar un poco con los arrays de caracteres, para ello
vamos a crear un array de cadenas con caracteres aleatorios. No
tiene ninguna utilidad, pero servirá para uno de los ejercicios.
Dimensionaremos un array de 100
elementos, a cada uno de esos elementos asignarle entre 10 y 50
caracteres comprendidos entre la A y la Z, recuerda que los códigos
ASCII de la A es el 65 y la Z el 90.
Ahora os pondré una forma "fácil" de clasificar ese
array, la parte de la asignación es la que tú tendrás que hacer.
'
Const MaxCadenas = 100
Dim cadena(1 To MaxCadenas) As String
Dim c As Integer
Dim sTmp As String
Dim i As Integer
Dim j As Integer
Randomize Timer
list1.Clear
'Asignar los valores
'...Escribe aquí tu código...
'Clasificar
For i = 1 To MaxCadenas
For j = 1 To i - 1
'para ordenar de forma descendente:
'If cadena(i) > cadena(j) Then
If cadena(i) < cadena(j) Then
'intercambiar los valores
sTmp = cadena(i)
cadena(i) = cadena(j)
cadena(j) = sTmp
End If
Next
Next
list1.Clear
For i = 1 To MaxCadenas
list1.AddItem cadena(i)
Next
Creo que el procedimiento es lo
suficientemente "simple" como para que lo entiendas...
¿verdad?
Lo que debes "observar" en este método es que cada uno de
los elementos del bucle i se compara con todos los anteriores, de
forma que si alguno anterior es "mayor" se intercambien
las posiciones...
Supón que en la posición cadena(1) tienes almacenado
"HOLA" y en la posición 2 está la palabra
"AMIGO"
La condición se cumplirá cuando la variable i valga 2 y j valga 1,
quedando por tanto en el orden correcto.
Lo que debes saber de las cadenas
de caracteres es que cuando se hace una comparación el Visual Basic
comprueba los valores ASCII de las letras que componen la palabra,
en este caso la letra A está antes que la H, así que A es menor
que H.
También deberás saber que los números están antes que las
letras, por tanto si una cadena de caracteres empieza por una cifra
del 0 al 9, se ordenará antes que la "A" y que la
"a" estará después que la Z
Si quieres saber los valores ASCII de los caracteres "más o
menos" stándard, haz este bucle:
'Códigos ASCII
For i = 32 To 122
Debug.Print i; Chr$(i)
Next
Ahora los ansiados
ejercicios, (realmente ha sido cortita esta entrega
¿verdad?)
Para los ejercicios, usando este
trozo para guardar números aleatorios en un array unidimensional,
espero que no tengas problemas para guardarlos en un array
multidimensional.
T = Int(Rnd * 31) + 20 'Número de rascadas, T valdrá de 20 a 50
For i = 1 To T
H = Int(Rnd * 23) + 1 'H valdrá de 1 a 23
Horas(H) = Horas(H) + 1
Next
Los ejercicios usando este ejemplo:
- Saber que hora tiene el valor
mayor y a que hora empezaste a rascarte (es decir la primera
hora del array que contiene un valor)
- Que hora fue la última en que
te arrascaste (no necesita explicación...)
- Modificar el ejemplo anterior
para que el número de veces que te rascas valga
(aleatoriamente) de 100 a 1000 y saber también cual de estas
horas tiene el valor menor (en caso de que haya varios, sólo
tienes que averiguar uno de ellos)
Para que no te compliques mucho la
vida, decirte que con un par de líneas, puedes averiguar el mayor o
el menor... no sea que quieras hacer un mogollón de comparaciones.
¡A disfrutarlo!
Esta entrega no da más de sí, no
es que haya querido hacerla deprisa y corriendo, es que realmente lo
"básico" está aquí explicado, si quieres profundizar
más, ya sabes dónde buscar información... en los libracos esos
que venían con tu VB.
Si aún así, piensas que no te has enterado... repásatela unas
dieciséis veces más...
Nos vemos.
Las
soluciones de esta entrega.
