Curso Básico de Programación
en Visual Basic
Cuarta
Entrega: 4/Jul/97.
por Guillermo "guille" Som
Estos son los
links a las entregas anteriores, si no te las has leido, peor pa
ti, pero deberías leertelas.
La Primera, la Segunda y la Tercera.
![]()
Buenaaas,
aquí estamos de nuevo (tu, yo y mi otro yo), empiezo con
correcciones, ya sabes, fallos que tiene uno, y otras
aclaraciones.
El primero es un fallo garrafal, que gracias a Antonio Banderas,
al que le tengo que agradecer también otras cosas, que espero
que vaya en beneficio de los que estais leyendo todas estas cosas
sobre el VB, (si, aparte de nosotros tres hay otros que siguen
este curso). Bueno, a lo que iba, que siempre me despisto... en
la segunda entrega, en el último ejemplo de Num1, Num2, la
asignación: Num1 = Num1 + Num2, debería ser: Num1
= Num1 & Num2 (sé que te habrás dado cuenta del
detalle, sobre todo por la explicación posterior), este
"desliz" ya está corregido, así que si lo has leido
después del 30 de Junio (del 97), ya está como tenía que
estar.
La siguiente aclaración, es un despiste, no demasiado grande, ya
que doy por hecho de que algo habrás leido sobre VB, bien los
manuales, bien la Ayuda o algún libro sobre este lenguaje. Pues
la cosa consiste que en la tercera entrega se crea un
procedimiento: Contar, para crear procedimientos o funciones,
tienes que usar el menú Insert y seleccionar Procedure (esto en
VB4), en VB3 si no recuerdo mal, estaba en el menú
"View" y en VB5 está en Tools (Herramientas)
Bien, hechas
estas aclaraciones, voy a explicar, tengo que hacerlo, ya que me
comprometí y... lo prometido es deuda o eso dicen, a saber...
Antes del código hice este comentario:
Osea esto es lo que se dice un programa inútil que además de consumir recursos del sistema y hacernos perder el tiempo, no vale para nada... (es que después de probarlo, me he dado cuenta de que o todos los formatos son prácticamente igual de rápidos o yo he estado "engañado" durante todo este tiempo...)
Y la cosa es que antes de hacer este ejemplo, yo creía que algunos tipos de datos eran más rápidos que otros, (y a pesar de que el ejemplo demuestra, o casi, lo contrario, sigo creyendolo...). La cosa es que en 32 bits un Long debería ser más rápido que el resto. Y los enteros más rápidos que los de coma flotante... voy a probarlo en un 386 sin copro, a ver... ahora vuelvo...
Ya puestos a
probar, he probado, aquí se demuestra lo "morruo" (o
cabezón) que soy, y en esta tabla (pulsando en el link),
tienes los diferentes valores en distintos equipos y con
distintas versiones de VB.
Verás que sorprecilla te llevas... ¿Lo has visto?
Dejaré este tema, que ya es mucho lo que le he dedicado, vamos a ver el programa y así cambiamos de tercio...
Para
introducir código en cualquiera de los eventos de los controles
o del formulario, lo único que tienes que hacer es seleccionar
el control y el evento que queremos codificar de las listas
desplegables, en el módulo de código, pulsando en Código en la
ventana en la que se muestra los módulos y formularios que forma
un proyecto. En la lista de la izquierda seleccionamos el control
y en el de la derecha nos mostrará todos los eventos soportados
por VB para ese control. Si sabemos el nombre del control y el
del evento, podemos teclearlo directamente o bien si copiamos
código de otro sitio, simplemente con pegarlo, se va a su sitio.
En el caso de querer añadir al código, una función o
procedimiento se puede hacer de varias formas, lo acabo de decir,
pero lo repito un poco más claro:
En otra
ocasión veremos todas estas cosas y con ejemplos, que es lo que
"mola".
Bueno, toda esta "retahila" venía a cuento de cómo
introducir código en los eventos de los controles o del
formulario y cómo crear nuetras propias instrucciones (esto es
lo que más me gustó del QuickBasic 4.0, poder crear mis propias
instrucciones (subs) y funciones).
Ya es hora de coger el listado de la entrega anterior y "destriparlo". Vamos a ver cada cosa por separado, que aunque parezca que es mucho código, realmente está "repetido", o casi...
Option Explicit
Esto nos obliga a declarar todas las variables que usemos en el módulo, ponerlo es una recomendación, incluso te la impondría como norma. Para que salga de forma automática en cada nuevo módulo, selecciona del menú Tools/Advanced la opción Declare variables required (o algo parecido, que viene a significar Requiere la declaración de variables)
Siguiendo nuestro recorrido por el código, no encontramos con:
Private Sub Command1_Click()
Lo de Private
significa que sólo se puede acceder a este procedimiento desde
dentro del módulo en el que está declarado. Es decir no se
puede llamar desde otro form o módulo BAS.
Sub indica que es un procedimiento, no una
función, ni una propiedad. Los Subs actuan como intrucciones
propias del lenguaje. Las funciones también, pero devuelven un
valor, mientras que los subs no devuelven nada, lo que cogen se
los quedan ellos, aunque en su momento veremos que también nos
pueden dar algo a cambio.
Command1_Click, este es el nombre que habrá que
usar para acceder a él desde cualquier punto de éste módulo.
Los paréntesis sin nada dentro, indica que este procedimiento no
recibe parámetros; los parámetros lo veremos dentro de un
"ratillo"
Toda esta línea es la descripción del procedimiento y cuando se
le llame, bien desde nuestro propio código, bien porque se pulse
sobre el botón, se ejecutará todo lo que esté dentro de él.
El final del procedimiento está marcado por End Sub.
Las líneas con DIM indican que estamos declarando las variables y lo que se especifica después del AS es el tipo de variable, los cinco primeros son de cada uno de los tipos numéricos soportados (otro día veremos otro tipo cuasi-numérico), el sexto es Variant, el multi-uso, el que vale para todo.
Veamos ahora
que es lo que se hace con esta línea:
Dim timer1#, timer2 As Double
Aquí he declarado dos variables del tipo Double.
Al separarlas con comas no hay que repetir la palabra DIM,
pero sí el tipo de cada variable. Ya vimos en la entrega
anterior que algunos tipos de variables se podían indicar
mediante unos caracteres especiales, (estos tipos son los
heredados de versiones anteriores al Visual Basic 2, en esa
versión, se introdujo el tipo Variant), en este caso #
es lo mismo que Double, por tanto se podría
haber hecho también de cualquiera de estas tres formas:
Dim timer1#, timer2#
Dim timer1 As Double, timer2#
Dim timer1 As Double, timer2 As Double
Ahora fijate
que esta otra no haría la misma tarea:
Dim timer1, timer2 As Double
Esto funcionaría con lenguajes como el C, (realmente el tipo se
pone delante), pero en Basic no declara las dos variables como
Double. La segunda variable si es Double, pero la primera es del
tipo por defecto, en nuestro caso Variant.
Así que mucho ojito con las declaraciones de las variables. En
algún sitio, no voy a decir dónde, porque lo mismo fué un
"lapsus" del autor, pero decía que de esta forma
declaraba tres variables Integer: Dim i, j, k As Integer
Sigamos
nuestra andadura, ahora veamos esta declaración/asignación:
Const minBucle = 1, maxBucle = 10
Aquí lo que se declaran son dos constantes, éstas a diferencia
de las variables, no pueden cambiar de valor, de ahí su nombre,
por tanto permanecerán siempre con el mismo valor. Cuando se
declara una constante, no es necesario especificar el tipo, VB se
encarga de adivinarlo y usar el tipo adecuado, realmente lo que
hace es sustituir estas "palabras" por el valor que hay
después del signo igual. En caso de hacer esto: cNombre
= "Una palabra". Visual Basic sabe que es una
cadena de caracteres y cada vez que se encuentre con cNombre
lo sustituirá por "Una palabra".
Ahora viene la explicación del "por qué" usar
constantes. Además de "esclarecer" los listados, los
hace más fáciles de comprender, también nos permite modificar
un valor en un sólo sitio, con lo que ganamos en
"confianza", al asegurarnos de que no omitiremos alguno
de los sitios dónde tengamos o queramos cambiar el valor antiguo
por uno nuevo.
En nuetro ejemplo, minBucle y maxBucle se usan en seis partes
diferentes del procedimiento, si quisieras probar con otros
valores, tendrías que cambiar en seis sitios esos valores, pero
al declararlos como constantes, sólo cambiando el valor
asignado, tenemos todo el trabajo hecho. Esto además de ser más
fiable y legible, nos puede ahorrar algún que otro quebradero de
cabeza y si además le añadimos que no ocupan espacio extra,
salvo en la tabla de símbolos, una vez compilado el programa
sólo se "compilarán" las constantes usadas. Sin
embargo con las variables no ocurre esto, ya que aunque no se
usen, ocupan memoria.
Un inciso, esto de explicar tan detalladamente los listados, no va a ser norma, ya que al final todos nos aburriríamos, sólo lo haré cuando lo crea conveniente o bien si lo solicitas, en este caso, no tendré más remedio que cumplir tus deseos...
Command1.Caption
= "Calculando..."
Cambiamos el texto mostrado en el botón, para avisarnos de que
está haciendo algo...
timer1
= Timer
Asignamos el valor de la función Timer a la primera de las dos
variables que usaremos para calcular el tiempo empleado por cada
uno de los bucles. Esta función devuelve el número de segundos
transcurridos desde la media noche.
For
nInt = minBucle To maxBucle
Esto es un bucle, que se repetirá desde minBucle (1) hasta
maxBucle (10) y la variable nInt es la que llevará la cuenta o
la que se usará para saber el valor actual del bucle.
Deberíamos ver primero la declaración del procedimiento Contar, para entender lo que hace la línea que viene después del For.
Private Sub Contar(valor
As Integer, etiqueta As Control)
Declaramos un procedimiento privado llamado Contar (actúa como
una instrucción más del VB, ya que no representa a ningún
control ni evento), entre los paréntesis están declarados los
dos parámetros que espera recibir en la llamada, el primero es
un número entero y el segundo (separado por una coma), un
Control, que puede ser cualquier control de VB.
El resto del procedimiento ahora no es demasiado significativo
Ahora veamos esta línea:
Contar
CInt(nInt), Label1
Contar es el nombre del procedimiento y a continuación se deben
indicar los parámetros que espera recibir. En este caso no
sería necesario CINT ya que lo que hace esta
función es convertir el número que se pone dentro de los
paréntesis en un número entero y como resulta que nInt es un
número entero... pues ¡no hay nada que convertir!
El segundo parámetro es el control Label1, ya sabes que tenemos
6 etiquetas en nuestro programa desde Label1 a Label6
Cuando llegue estos datos al procedimiento Contar, valor tomará
lo que valga nInt y etiqueta se adueñará de Label1.
Next
Continua repitiendo el bucle hasta que se alcance el valor
máximo, realmente el Next lo que hace es lo siguiente:
nInt = nInt + 1
¿Es nInt menor o igual que maxBucle? Si la respuesta es SI,
sigue con lo que haya después de la línea FOR, en caso negativo
continúa con la línea siguiente al Next (realmente en la
siguiente instrucción después del Next, ya veremos esto en otra
ocasión)
timer2
= CDbl(Timer - timer1)
Asignamos a la segunda variable que usamos para el cálculo del
tiempo la diferencia entre el nuevo valor de los segundos
transcurridos desde la media noche (Timer) y el valor que tenía
timer1, es decir cuantos segundos... antes de empezar el bucle.
El CDBL es una fución que devuelve un valor Doble. Es decir hace
la resta y ese valor resultante lo convierte en doble.
Label1
= "Duración con Integer: " & timer2
Esta asignación realmente es Label1.Caption, si se omite la
propiedad, Visual Basic usa la que tiene por defecto, que según
los manuales, suele ser la propiedad que se usa con más
frecuencia. En este caso el Caption, es decir lo que se muestra
en la etiqueta.
DoEvents
Esta es una instrucción "controvertida" y a la que
muchos programadores no les hace demasiada gracia usar, no porque
no tenga su utilidad, sino porque hay que saber realmente lo que
hace y tener cuidado cuando la usamos, ya que algunas veces puede
crear errores o confusión... reálmente no es tan drástico,
pero casi...
DoEvents, detiene la ejecución del programa y devuelve el
control a Windows, para que ejecute los mensajes que tiene
pendientes en la cola de mensajes... ¿? no te preocupes si no te
enteras, es así y punto. ¿por qué la uso? Pues para dar tiempo
a que se vea el contenido del Label; prueba a quitarla y verás
lo que ocurre, o debería ocurrir... que ya a estas alturas no me
sorprendería nada que se mostrara...
El resto del programa es idéntico a este bucle, pero usando distintas variables y las demás etiquetas. El caso es que Contar espera una variable de número entero y un control, en el caso del control es obvio que se están poniendo las distintas etiquetas y en el caso del número se convierte a entero, porque eso es lo que espera nuestra instrucción y si no lo hacemos así, se quejará.
Ya sólo queda
ver una línea del procedimiento Contar:
etiqueta.Caption = valor * elMaximo + unDoble
unDoble contará desde 1 hasta elMaximo, en cada vuelta del
bucle, se asignará al caption de la etiqueta pasada al
procedimiento y el DoEVents que viene a continuación se
encargará de que se muestre ese contenido. Bueno, también se
asigna valor * elMaximo, es decir que cuando valor valga 1, se
estará mostrando 1000 + unDoble, realmente para hacer un
contador se tendría que haber usado lo siguiente:
etiqueta.Caption = (valor -1) * elMaximo + unDoble,
para que mostrara desde el 1, en lugar de empezar desde el 1001.
Una vez que Contar termina, por el End Sub, vuelve el control al bucle que lo llamó y se ejecuta la siguiente instrucción. Por tanto Contar se llamará tantas veces como dure el bucle en el que se encuentra.
Creo que queda todo más o menos claro y aunque este código no es muy útil por sí, ha servido para ver algunas cosillas del VB.
Para terminar vamos a ver una serie de cambios y a ver si adivinais que es lo que hace... así os servirá de ejercicio, cosa que algunos me habeis pedido, pero que aún no es el momento de hacerlos.
En las
declaraciones generales añade esta declaración:
Dim Contando As Integer
En Contar,
añade lo siguiente después del DoEvents:
If Contando = 0 Then Exit For
Al principio del Command1_Click, añade estas líneas:
If Contando Then
Command1.Caption = "Calcular"
Contando = 0
DoEvents
Exit Sub
End If
Contando = 1
En cada uno de
los bucles, pon esto después de llamar a Contar...
If Contando = 0 Then Exit Sub
Y antes del
End Sub añade esto otro:
Command1.Caption = "Calcular"
Contando = 0
Bueno, ahí
dejo esto y como ejercicio podrías añadir dos controles TextBox
para especificar los valores de maxBucle y elMaximo, de forma que
según los valores introducidos, que por defecto deben ser 10 y
1000, se usen los que especifiques en cada TextBox y se tengan en
cuenta cuando pulsas (haces click) en el botón.
Como pista te diré que las variables usadas y/o declaradas
dentro de un procedimiento son sólo visibles dentro de ese
procedimiento. No te quejarás del "pedazo" de pista
que te he dado...
A disfrutar y
hasta la próxima entrega... ¿cuando? Eso ni se sabe...
Y ya sabes que espero tus comentarios sobre el cursillo este
de marras...
Nos vemos.
![]()