Curso Básico de Programación
en Visual Basic

Décima Entrega: 30/Sep/97.
por Guillermo "guille" Som

Desde aquí puedes enlazar con las entregas anteriores.
La Primera, la Segunda, la Tercera, la Cuarta, la Quinta, la Quinta++, la Sexta, la Séptima, la Octava, la Novena


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:

  1. 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)
  2. Que hora fue la última en que te arrascaste (no necesita explicación...)
  3. 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.

10/Ene/98: Las soluciones de esta entrega.


 

entrega anterior ir al índice siguiente entrega

Ir al índice principal del Guille