ELEMENTOS DEL LENGUAJE II

4.1.- ARRAYS Y FUNCIONES ASOCIADAS

 

Un array permite referirse a una serie de elementos del mismo tipo por un mismo nombre y referenciar un único elemento de la serie utilizando un índice. Los arrays deben ser declarados explícitamente.

 

ARRAYS ESTÁTICOS

 

Para declarar un array estático, formado por un número fijo de elementos, Visual Basic utiliza una sintaxis parecida a la declaración de variables. Veamos algunos ejemplos:

 

Dim Array_A(19) As String

declara un array unidimensional de 20 elementos: Array_A(0), Array_A(1)...

 

Dim Array_B(3, 1 To 6) As Integer

declara un array bidimensional de 4x6 elementos: Array_B(0,1), Array_B(1,2)...

 

 

ARRAYS DINÁMICOS

 

Para declarar un array dinámico, formado por un número variable de elementos, Visual Basic utiliza una sintaxis parecida a la declaración anterior. El espacio necesario para un array dinámico será asignado durante la ejecución del programa. Un array dinámico puede ser redimensionado en cualquier momento durante la ejecución. Para redimensionarlos se utiliza la sentencia ReDim. Esta sentencia puede aparecer solamente en un procedimiento y permite cambiar el número de elementos del array, no el número de dimensiones. Por ejemplo:

 

Dim Array_A() As String

declara un array unidimensional dinámico. Más tarde, un procedimiento puede utilizar la sentencia ReDim para asignar el espacio, p.e. ReDim Array_A(4,4)

 

Cada vez que se ejecuta la sentencia ReDim, todos los valores en el array se pierden. Cuando interese conservar los valores del array, se utilizará la sentencia ReDim Preserve. Sólo se puede cambiar el límite superior de la última dimensión.

 

 

FUNCIONES ASOCIADAS

LBound

Devuelve el índice más bajo posible de un array.

 

UBound

Devuelve el índice más alto posible de un array.

 

En general, la orden

LBound(Nombre_Matriz, I)

da el límite inferior para la dimensión Y (para un array unidimensional, la I es opcional). Por tanto, en el siguiente ejemplo:

Dim Test%(1 To 5, 6 To 10, 7 To 12)

Print LBound(Test%, 2)

devuelve un 6 y,

Print UBound(Test%, 3)

devuelve un 12.

 

Las órdenes LBound y UBound permiten copiar arrays de diferentes límites, siempre que el número total de filas y columnas sea el mismo. (Al sustraer LBound de UBound para cada dimensión, se puede comprobar si coinciden)

 

EJERCICIOS:

  1. Crear una aplicación que permita crear un cuadrado mágico. Un cuadrado mágico es aquel en el que todas las filas, columnas y diagonales principales suman lo mismo. Para resolver el ejercicio se utilizará el argumento de Loubère, que funciona solo con cuadrados mágicos impares:

 

17 24 1 8 15

23 5 7 14 16

4 6 13 20 22

10 12 19 21 3

11 18 25 2 9

 

  1. Crear una aplicación que permita obtener el elemento mayor de una matriz cuadrada de dimensión cualquiera. Los elementos de la matriz serán números entre el 1 y el 1000 introducidos aleatoriamente.

 

 

4.2- FUNCIONES Y PROCEDIMIENTOS

 

Para evitar duplicar código en los procedimientos de evento, se deben utilizar los procedimientos generales. Éstos deben escribirse como un procedimiento Sub o como una función Function.

 

Cuando un procedimiento es llamado para su ejecución, Visual Basic lo busca en el formulario o en el módulo donde se encuentre en ese momento. Si no lo encuentra, continúa la búsqueda en el resto de los módulos de la aplicación.

 

Para crear un procedimiento general, desde la ventana de código se accederá a Insertar/Nuevo Procedimiento.

 

Las funciones en Visual Basic son declaradas en los módulos o en la sección de declaraciones de un formulario y devuelven un valor al procedimiento que la invocó. La sintaxis empleada es la siguiente:

 

[Private | Public] [Static] Function nombre [(lista_argumentos) ] [As tipo]

[Declaraciones]

[nombre = expresión]

[Exit Function]

[Declaraciones]

[nombre = expresión]

End Function

 

Los procedimientos generales necesitan ser invocados explícitamente para poder ser ejecutados. No devuelven ningún valor. La sintaxis para declarar procedimientos generales es:

 

[Private | Public] [Static] Sub nombre [(lista_argumentos) ]

[Declaraciones]

[Exit Sub]

[Declaraciones]

End Sub

 

donde:

[[Optional] [ByVal | ByRef] [ParamArray] varnombre [( )] As tipo]

donde:

 

La forma de llamar a una función es

var = nombre_función([argumentos] )

 

La forma de invocar a un procedimiento es utilizando cualquiera de las dos formas siguientes:

Call nombre_procedimiento[(argumentos)]

nombre_ procedimiento [argumentos]

 

 

PASO DE PARÁMETROS

 

Por defecto, los argumentos son pasados por referencia.; de este modo cualquier cambio de valor que sufra un parámetro en el cuerpo de la función o del procedimiento también se produce en el argumento correspondiente de la llamada a la función o procedimiento.

 

Cuando se llama a una función o a un procedimiento, se podrá especificar que el valor de un argumento sea pasado por valor, poniendo dicho argumento entre paréntesis en la llamada. Otra forma de especificar que un argumento será siempre pasado por valor es anteponiendo la palabra ByVal a la declaración del parámetro en la cabecera del procedimiento.

 

 

EJERCICIOS:

 

 

4.3- MATRICES DE CONTROLES

 

Una Matriz de Controles es un grupo de controles que comparten el mismo nombre y tipo. A su vez, comparten los mismos procedimientos de eventos, pero son controles físicamente separados y cada uno posee su propio conjunto de propiedades. Una matriz de controles tiene al menos un elemento y no puede exceder de 254. Para crear una matriz de controles es suficiente con asignar el mismo nombre a dos o más controles (propiedad Name) durante el diseño de la aplicación, o bien asignar un valor a la propiedad Index de un control. En el último caso se genera una matriz de un solo elemento, lo cual es útil cuando se quieren crear controles en tiempo de ejecución. Cuando Visual Basic crear una matriz de controles, asigna por defecto los índices 0, 1, ..., los cuales pueden modificarse a voluntad del usuario cambiando el valor de la propiedad Index. Esta operación solo puede hacerse durante el diseño.

 

Cuando cualquier control de la matriz reconoce un suceso, Visual Basic pasa el índice como argumento extra y, sirve para determinar que control ha recibido el suceso. Un elemento de la matriz de controles puede referenciarse escribiendo NombreMatriz(Index)

 

 

AÑADIR Y RETIRAR CONTROLES EN TIEMPO DE EJECUCIÓN

 

Una vez se ha creado una matriz de controles durante el diseño, se pueden añadir controles mientras se ejecuta la aplicación. Cuando Visual Basic crea un nuevo control en una matriz de controles, el objeto es invisible. El resto de propiedades se copian del elemento de la matriz con menor índice. Como lo controles creados se apilan unos sobre otros, deben moverse con el método Move.

 

Para eliminar elementos de una matriz de controles, se utilizará la sentencia

Unload Nombre_Matriz(índice)

 

EJEMPLO:

Crear un formulario con dos cajas de texto a las que se les haya cambiado la propiedad Name para que ponga, en ambas, "Prueba". De esta forma tenemos creada una matriz de controles. Vamos a escribir un procedimiento de evento asociado a las dos cajas de texto.

 

Private Sub Prueba_Change(Index As Integer)

If Index = 0 Then

Print "Ha escrito en la caja de texto 0"

Else

Print "Ha escrito en la caja de texto 1"

End If

End Sub

 

Ahora modificaremos el ejemplo para que, al cargar el formulario, se añadan cuatro cajas de texto nuevas a la matriz de controles.

 

Private Sub Form_Load(Index As Integer)

Dim I As Integer

For I = 2 To 5

Load Prueba(I)

Prueba(I).Text = "Caja de texto " & Str(I)

Prueba(I).Move 0, 495 * (I - 2)

Prueba(I).Visible = True

Next I

End Sub

 

EJERCICIOS:

  1. Crear una aplicación que permita simular un tablero de juego tres en raya. Cada vez que el usuario haga clic sobre un cuadrado, la aplicación debe controlar si el cuadrado ya está marcado y, si no lo está, lo marcará con la señal del jugador. En caso de hacer tres en raya, dar un mensaje de felicitación.
  2.  

  3. Diseñar una aplicación que muestre en su formulario tres botones con el texto "+6%", +13%", "+33%" respectivamente. El usuario debe ser capaz de escribir en una caja de texto el valor de una cantidad determinada y, al seleccionar cualquiera de los porcentajes, la aplicación debe mostrar el tanto por ciento correspondiente y, la suma de dicho valor. Si la cantidad introducida por el usuario supera los 100.000.000, debe aparecer otro botón con el texto "+54%" y, si la cantidad es menor, debe desaparecer.
  4.  

  5. Diseñar una calculadora científica utilizando matrices de controles. Se debe poder obtener cualquier operación aritmética básica: sumar, restar, multiplicar y dividir. Llevar un control de la memoria. Obtener la raíz cuadrada y el tanto por ciento de un número. Debe permitir un encendido/apagado de la calculadora (p.e. un botón que inicialmente muestre ON y, una vez pulsado, visualice un cero en la pantalla y, en el botón, el texto OFF)
  6.  

  7. Se pretende realizar una aplicación que permita al usuario llevar la gestión de sus apuestas en la Lotería Primitiva. Para ello, la aplicación debe permitir marcar seis números seleccionados al azar entre el 1 y el 49. Se pretende que el botón correspondiente a "Marcar" seleccione seis números al azar y, los marque en las casillas adecuadas (equivalente al menú Apuesta / Marcar). El botón "Nueva apuesta" debe permitir desactivar las casillas marcadas en la apuesta anterior (Apuesta / Nueva). La aplicación debe tener un formulario inicial con el nombre del alumno, de forma que, transcurridos 5 segundos, muestre el formulario de la Primitiva.

 

 

VARIABLES DE OBJETO

 

Igual que se tienen variables para manipular enteros, cadenas, etc. se pueden utilizar variables para manipular objetos de Visual Basic. Utilizando variables objeto se podrá crear en tiempo de ejecución múltiples instancias de formularios, escribir procedimientos que modifiquen cualquier formulario o control y construir arrays de formularios. Un ejemplar o instancia de un formulario es una copia que existe con independencia del original. Una variable objeto no contiene una copia de un objeto, sino una referencia a dicho objeto.

 

Para declarar una variable objeto se utiliza la sintaxis:

 

{Dim | ReDim | Static} VarObj As [New] TipoObj

 

donde TipoObj puede ser: un formulario existente o las palabras reservadas Form, Control MDIForm, TextBox, ...

 

EJEMPLO:

Crear un formulario con un botón de comando, que tenga asociado el siguiente código:

 

Private Sub Command1_Click()

Dim MiForm As New Form1 ‘Variable objeto;

‘se crea un nuevo ejemplar

MiForm.Show ‘carga y visualiza MiForm

‘Mover y colorear el nuevo ejemplar

MiForm.Move Left + (Width \ 10), Top + (Height \ 6)

MiForm.BackColor = RGB(Rnd * 256, Rnd * 256, Rnd * 256)

End Sub

 

Para asignar un objeto específico a una variable objeto, se utiliza la sentencia Set:

 

Set VarObj = RefObj

 

Cuando una variable objeto no se refiere a un determinado objeto, tiene asignado el valor especial, Nothing.

 

Para pasar una variable objeto a un procedimiento se debe definir en la cabecera del procedimiento los parámetros que se necesitan de tipo de objeto genérico (Form, Control y MDIForm) y específico (TextBox, etc.). Un parámetro declarado de tipo Form puede actuar sobre cualquier formulario, un parámetro declarado de tipo Control puede operar sobre cualquier control.

 

Para determinar el tipo de una variable objeto se puede utilizar alguna de las sentencias siguientes:

 

{If | ElseIf} TypeOf VarObj Is TipoObj Then

 

Una colección se define como un grupo de objetos. Visual Basic provee de colecciones que se pueden utilizar para acceder a todos los formularios de una aplicación, o a todos los controles de un formulario particular. Una aplicación tiene una colección de formularios global y cada formulario tiene una colección de controles.

 

La colección de formularios contiene los formularios cargados. La sintaxis para referirse a la colección de formulario es:

 

Foms(índice)

 

donde índice es un valor entre 0 y Forms.Count -1. La propiedad Count devuelve el número de formularios en la colección.

 

La colección de controles permite referirse solamente a los controles cargados en un formulario. Cuando en un formulario hay array de controles, cada elemento de cada array es incluido en la colección. La sintaxis para referirse a la colección de controles es:

 

[formulario.] Controls(índice)

 

donde índice es un valor entre 0 y Controls.Count -1.

 

Visual Basic provee de cinco objetos especiales para obtener información acerca del entorno en el cual se está trabajando. Estos objetos son:

 

App Suministra información específica de la aplicación.

Clipboard Permite manipular texto y gráficos a través del portapapeles.

Debug Permite enviar información a la ventana de depuración.

Printer Permite enviar texto y gráficos a la impresora.

Screen Indica el formulario activo, control activo y otros datos.

 

EJEMPLO:

Diseñar un formulario que permita obtener una lista de las fuentes de la pantalla:

 

Private Sub Form_Click()

Dim I As Integer

For I = 1 To Screen.FontCount - 1

Font.Name = Screen.Fonts(I)

Print "Escrito en letra "; Screen. Fonts(I)

Next I

End Sub

 

 

4.4- LAS HERRAMIENTAS DE DEPURACIÓN

 

Cuando se realiza una aplicación se pueden presentar tres clases de errores:

 

 

 

DEPURACIÓN

 

Durante el diseño y puesta en marcha de una aplicación, hay tres modos en los que se puede estar: diseño, ejecución y pausa.

 

 

Para depurar una aplicación, se debe entrar en el modo pausa. Para ejecutar el código paso a paso desde un punto determinado, se insertarán puntos de parada, que detienen la ejecución de la aplicación pasando del modo de ejecución al de pausa.

 

 

VENTANA DE DEPURACIÓN

 

Para poder mostrarla se accede a Ver/Ventana Depuración. Sirve para poder visualizar los valores de las expresiones y poderlas verificar. Para ello, desde la ventana de depuración se podrá utilizar la sentencia Print o ? o utilizar la orden Herramientas/Agragar Inspección. También es posible mediante código, insertar sentencias del tipo:

 

Debug.Print Var_A_Depurar

 

EJEMPLOS

  1. Diseñar una aplicación que permita utilizar las herramientas de depuración. Para ello, la aplicación ordenará alfabéticamente 5 nombres. Utilizar las herramientas de depuración para depurarlo.

 

Private Sub Form_Click()

Static Nombres(4) As String

Nombres(0) = "Juan"

Nombres(1) = "Tomás"

Nombres(2) = "Eduardo"

Nombres(3) = "Samuel"

Nombres(4) = "Francisco"

For I = 0 To 4

For J = 0 To 4

If Nombres(I) > Nombres(J) Then

Temp$ = Nombres(I)

Nombres(I) = Nombres(J)

Nombres(J) = Tmp$

End If

Next J

Next I

For I = 0 To 4

Print Nombres(I)

Next I

End Sub

 

  1. Diseñar una aplicación que permita realizar una inversión de 1000 Pts al 7% durante 12 años, lo que debe dar una resultado de: inversión * (1 + Interés/100)Años = 1000 * (1 + 0,07)12 = 2252,19 Pts. El formulario estará formado por 4 cajas de texto y un botón de comando. Añadiremos las etiquetas necesarias para una mejor comprensión.

 

CONTROL

PROPIEDAD

VALOR

Form

Appearance

1 - 3D

 

Name

frmInversión

Label

Caption

Inversión en Pts

Text Box

Text

(ninguno)

 

Name

txtInversión

Label

Caption

Interés

Text Box

Caption

(ninguno)

 

Name

txtInterés

Label

Caption

Periodo en años

Text Box

Caption

(ninguno)

 

Name

txtAños

Label

Caption

Resultado

Text Box

Caption

(ninguno)

 

Name

txtResultado

 

TabStop

False

 

Locked

True

Command Button

Caption

Rendimiento

 

Name

cmdRendimiento

 

Private Sub cmdRendimiento_Click()

Inversión = Val(txtInversión.Text)

Interés = Val(txtInterés.Text)

Años = Val(txtAños.Text)

Resultado = Inversión * (1 + Interes / 100) ^ Años

txtResultado = Format(Resultado, Currency)

End Sub

 

 

4.5- CONTROL DE ERRORES EN TIEMPO DE EJECUCIÓN

 

Cuando se produce un error en tiempo de ejecución, Visual Basic detiene la aplicación. Para habilitar la captura de errores en tiempo de ejecución para su uso posterior, se tendrá que utilizar la sentencia:

 

On Error GoTo...

 

donde los tres puntos indican la etiqueta que define la captura del error. El código etiquetado debe estar en el procedimiento actual. Una etiqueta es un identificador que finaliza con dos puntos. Para que no se ejecute la rutina de tratamiento de errores cuando la aplicación funcione bien, es aconsejable tener una salida (Exit Function, Exit sub, etc.) en la línea inmediatamente anterior a la rutina de tratamiento.

 

En caso de que el error pueda corregirse, la sentencia Resume lleva a la instrucción que provocó el error inicialmente. Si no puede resolverse, se puede identificar el error con la función Err, que devuelve el entero asociado al último error producido.

 

La sentencia Resume Next permite saltarse la instrucción que provocó el error y, se comienza a procesar la instrucción inmediatamente posterior a la que ha causado el problema. También se puede restaurar la ejecución a cualquier punto mediante la sentencia Resume Etiqueta.

 

Para conocer el mensaje del error producido, se puede utilizar la función Error$.

 

Para desactivar la captura de errores, se utiliza la sentencia:

 

On Error GoTo 0

 

EJEMPLO:

Diseñar una aplicación que permita ejecutar una aplicación Windows introducida por el usuario.

 

CONTROL

PROPIEDAD

VALOR

Form

Caption

Ejecutar...

 

Name

frmEjecutar

 

MinButton

False

 

MaxButton

False

 

BorderStyle

1 - Fixed Single

Text Box

Text

(ninguno)

 

Name

txtArchivo

Command Button

Name

cmdAceptar

 

Caption

Aceptar

 

Default

True

Command Button

Caption

Cancelar

 

Name

cmdCancelar

 

Default

True

 

Private Sub cmdAceptar_Click()

Dim Retorno As Long

Dim NombreArchivo As String

NombreArchivo = txtArchivo.Text

If Existe(NombreArchivo) Then

Retorno = Shell(NombreArchivo, vbNormalFocus)

Else

MsgBox "Por favor, inténtalo de nuevo con un fichero existente", vbExclamation, _

"Ejecutar Programa"

End If

End Sub

 

Private Function Existe(F As String) As Boolean

‘Comprueba la existencia de un archivo

Dim X As Long

On Error Resume Next

X = FileLen(F)

If X Then

Existe = True

Else

Existe = False

End If

End Function

 

Private Sub cmdCancelar_Click()

End

End Sub