Curso Básico de Programación
en Visual Basic
Séptima
Entrega: 10/Sep/97.
por Guillermo "guille" Som
Te recomiendo
que leas las entregas anteriores, aquí tienes los links:
La Primera, la Segunda, la Tercera, la Cuarta, la Quinta, la Quinta++, la Sexta.
![]()
Hola fans del curso básico, es que poco a poco se están apuntando más gente a este cursillo y eso me pone en un compromiso... ¡¡¡me vais a obligar a terminarlo!!!
Bromas aparte, espero que te siga interesando y que se lo digas a tus vecinas, compañeros de clase, gente de tu curro y demás personal que te encuentres por la calle, el bus, el metro, cuando llames a un 906 y sobre todo cuando te tomes unas copas con los amigos... a ver si al final entre todos me comprais una casita de verdad...
Vamos a ver las soluciones de los
ejercicios de la sexta entrega, para ver que nivel llevas, porque
me imagino que te has enterado de todo lo que ponía, ya que
últimamente no recibo preguntas ni dudas ni quejas porrque algo
estuviera mal... salvo algún que otro despistadillo que ha
empezado por la primera entrega, hace los ejercicios y me
"mailea" diciéndome que no le muestra nada... y eso
que lo he puesto al final de la primera entrega y en letra GORDA
pa que se vea bien...
Esto pasa por bajarse las páginas, guardarlas en el disco duro y
después leerla al montón de días...
Bueno, después del rapapolvo... todo para que se te olvide que esta entrega iba a estar el mes pasado...
SOLUCIONES A LOS EJERCICIOS DE LA SEXTA ENTREGA:
1.)
Private Sub Command1_Click() Dim A As Integer Dim B As Integer Dim i As Integer A = Val(Text1) B = Val(Text2) For i = A To B Print i Next Show End Sub
'El bucle también se puede hacer de esta forma:
i=A Do While i<=B Print i i=i+1 Loop
'Y de esta también
i=A While i<=B Print i i=i+1 Wend
2.)
Private Sub Command1_Click() Dim A As Integer Dim B As Integer Dim C As Integer Dim i As Integer A = Val(Text1) B = Val(Text2) C = Val(Text3) For i = A To B Step C Print i Next Show End Sub
'Otra forma de solucionarlo i=A Do While i<=B Print i i=i+C Wend
3.)
'Añadir estas líneas: Dim D As Integer '...
'...For D = D +1 '... Next Label1 = "Número de repeticiones: " & D
Y eso es todo, no pongo otras posbles formas de obtener los resultados, porque tu mismo habrás comprobado si están bien o no.
Ahora empezamos con la entrega
real, es decir la séptima.
Ya disponemos de instrucciones suficientes para empezar a
"profundizar" en las cosas más difíciles... o casi.
Ya sabes que hay que usar Option Explicit en todos los módulos
de código... Esto no es obligatorio, pero si no quieres que
perdamos la amistad, usalo. Gracias.
También cómo usar las variables y los diferentes tipos, puedes
hacer bucles, tomar decisiones, relamente es más correcto decir:
hacer que VB tome decisiones, ya sabes cómo pedir datos al
usuario y también cómo mostrarlos. Sabes crear tus propias
instrucciones... ¡Jo! ¡Cuanto sabes! Me tienes
"anonadado"
Pero aún no sabes una cosa: cómo
crear Funciones
¿Qué son las funciones?
Para simplificar, te diré que una función es un procedimiento
(como el Sub), que puede devolver un valor. Normalmente se usa
para que lo devuelva, aunque veremos que no siempre es necesario;
de todas formas, cuando necesites un procedimiento que no
necesite devolver un valor, usa el Sub.
¿Cómo declarar/codificar una función?
Ámbito Function Nombre ([parámetros]) As Tipo
Dónde Ámbito puede ser Public o Private, dependiendo de la
"cobertura" o visibilidad. Ya sabes, Private sólo es
visible en el propio módulo en el que se encuentra definido y
Public es en todo el proyecto, incluso fuera de él...
Los parámetros son los valores que esta función puede necesitar
para "cumplir" su misión. Éstos son opcionales, es
decir puede tenerlos o no, incluso si tiene, puede ser uno o
varios, para declarar varios parámetros hay que separarlos por
comas... Los corchetes, que se suelen usar en los manuales, la
ayuda, etc, sirven para indicar que son opcionales, ¡pero no
se te ocurra ponerlos en ninguna función!, ya que no forman
parte del lenguaje Basic...
El tipo es para saber que tipo de dato devolverá la función.
El valor devuelto por una función
lo podemos usar para asignarlo a una variable: a = MiFunción()
o incluirlo en una expresión: If MiFunción() + 15 > LoQueSea
Then
La ventaja real frente a los Subs
es la posibilidad de devolver un valor, imaginate que quieres
crearte tu propio procedimiento para averiguar si un determinado
archivo existe... si lo hace como función podrías devolver un
valor cero para indicar que no existe el archivo y un valor
distinto de cero indicaría que el archivo en cuestión existe.
Por tanto, podríamos usarlo de esta forma:
If Existe(NombreArchivo) Then ...
Ya que estamos puestos, veamos cómo hacer esta función de forma
simple y así te explico uan cosa muy importante de toda
función: ¡poder devolver el valor!
Public Function Existe(sArchivo As String) As Integer Existe = Len(Dir$(sArchivo)) End Function
Para devolver un valor, éste se
asigna a una variable que tiene el mísmo nombre que la función.
Ya vimos que LEN devuelve el número de caracteres de la cadena
que ponemos entre los paréntesis; si, LEN también es una
función, pero incluida en el propio Visual Basic.
Dir$ es otra función del VB que devuelve el nombre de un
archivo, (sólo el nombre), o una cadena vacía, en caso de que
no haya ninguno en la dirección pasada por el parámetro que se
ha usado. Para saber más de esta función, así como de otras,
puedes buscar en la ayuda...
Hemos visto que en las expresiones
usamos unos operadores para hacer las comparaciones, aquí tienes
los seis posibles:
= igual, > mayor que, < menor que, >= mayor o igual,
<= menor o igual y <> distinto.
Recuerda que el signo igual funciona de forma diferente, según
se use en un expresión o en una asignación.
Pero además de estos signos, podemos usar en nuestras
expresiones unos operadores lógicos, estos son: AND, OR y NOT
Podríamos desear hacer una comparación y comprobar si varias
cosas se cumplen, por ejemplo:
If A>10 And Len(Nombre)<>0 Then ...
Para que esta expresión se cumpla, deben ser ciertas las dos
condiciones, es decir que A sea mayor que 10 "y" que la
longitud de Nombre sea distinta de cero. Podemos usar tantas
condiciones como queramos, sin pasarnos demasiado para que la
cosa funciones mejor. Aquí las dos condiciones deben cumplirse,
pero en este otro jemplo:
If A>10 Or Len(Nombre)<>0 Then ...
cumpliéndose cualquiera de las dos, se acepataría como válido.
Cuando el If se procesa, se toma todo lo que hay entre IF y THEN
y se considera como una sóla expresión.
Si quieres puedes asignar a una variable el resultado de una
expresión, el valor devuelto siempres será 0 (cero) en caso de
que no se cumpla todo lo expuesto y -1 cuando sea cierta.
Para manejar estos valores de Cierto (-1) y Falso (0), Visual
Basic tiene un tipo especial llamado Boolean, los valores que
puede aceptar una variable de este tipo son: True (verdadero) y
False (falso).
Veamos un ejemplo:
Dim b As Boolean, i As Integer Dim a As Integer, Nombre As String Show a = 15 Nombre = "Guille" b=(a>10 And Len(Nombre)<>0) i=(a>10 Or Len(Nombre)<>0) Print "Valor de B "; b Print "Valor de i "; i
¿Te has fijado en el detalle? B vale True (verdadero), sin embargo i vale -1. Pero para el caso los dos valores significan lo mismo: si estas expresiones se hubiesen usado en una comparación, las dos hubiesen devuelto un valor verdadero.
El tercer operador lógico (Not)
sirve para negar algo, es decir invertir el valor contenido en
una variable, o casi...
If Not A>10 Then ...
Parece lógico el resultado, ¿verdad?, si no se cumple que A sea
mayor que diez, será cierto; comprobemoslo:
Dim A As Integer '¿recuedas que tienes que poner Show? A = 5 If Not A>10 Then Print A;"no es mayor que 10" End If
¡BINGO! ¡Funciona!
"Mu" bonito, pero... ¿que eslo que ocurre?
Se toma A > 10 y se procesa, como A no es mayor que 10, se
devuelve un valor falso (0) y después se hace Not 0 que da como
resultado -1 (verdadero), por tanto se cumple la condición.
Ya vimos que el valor devuelto por una variable se puede usar en
una comparación, si es cero se toma como falso y si es distinto
de cero, como verdadero.
Prueba ahora esto:
A=0 If Not A Then Print A;"es cero" Else Print A;"es distinto de cero" End If
También funciona, ya que Not 0 es -1, por tanto el If lo da por cierto, si cambiamos el valor incial de A por un valor distinto de cero:
A=5 If Not A Then Print A;"es cero" Else Print A;"es distinto de cero" End If
¿Que ha pasado aquí? Simple, que
no es lo que esperabamos... Cuando hicimos Not 0 era evidente, ya
que se convierte en -1, pero Not 5 no se convierte en cero, sino
en: -6 y ya sabes que el IF considera como verdadero todo lo que
no sea cero.
No quiero entrar en detalles de porqué ocurre esto, sólo
decirte que la responsable de todo es la notación binaria... los
ceros y unos que dicen que es el lenguaje nativo de los cacharros
estos... talvez más adelante tratemos un poco de la notación
binaria, pero no por ahora... recuerdo que en mis tiempos del
GwBasic la usaba bastante, incluso tenía rutinas para
"representar" en ceros y unos un número...
Vale, para que te entretengas probando... (este link es para
el programa completo
Dec2Bin.zip 1.75 KB)
Private Function Dec2Bin(sNumDec As String) As String
'Recibe una cadena que será un número decimal
'Devuelve ese número representado por ceros y unos
'
Dim i As Integer
Dim lngNum As Long 'Long, por si las moscas
Dim sTmp As String 'Cadena temporal
lngNum = Val(sNumDec)
sTmp = ""
For i = MaxBits - 1 To 0 Step -1
If lngNum And 2 ^ i Then
sTmp = sTmp & "1"
Else
sTmp = sTmp & "0"
End If
Next
Dec2Bin = sTmp
End Function
Ahora puedes
comprobar porqué NOT 5 da como resultado -6, usa esta rutina
para probarlo, si escribes 5, te mostrará:
00000101 y si escribes -6 lo que muestra es: 11111010, fijate que
ha cambiado todos los ceros por unos y viceversa.
Eso es lo que hace el NOT, invertir los valores binarios y como
un valor binario sólo puede ser 0 ó 1, no se complica demasiado
la vida. Prueba a escribir el valor 0 y el valor -1 y conviertelo
a notación binaria, fijate lo que el Visual Basic normalmente
ve.
Prueba con el
tema de la notación binaria, así sabrás realmente cómo
funciona todo esto de las comparaciones (por dentro).
Lo que nunca falla es completar la expresión, por ejemplo si
haces esto:
If Not A<>0 Then Print A;"es CERO" Else Print A;"NO es CERO" End If
Esto siempre
funcionará de la forma esperada.
Pero sería más fácil, o al menos más inteligible, hacerlo
así:
If A=0 Then Print A;"es CERO" Else Print A;"NO es CERO" End If
Es que algunas veces se puede uno complicar la vida más de lo necesario...
Cuando quieras comprobar un valor devuelto por cualquier expresión, puedes hacerlo asignándolo a una variable o bien mostrando el valor: Print Not A
Cuando se usa
AND pra evaluar varias partes de una expresión hay que tener
presente que siempre se procesan todas las condiciones y
finalmente se decide si es cierto o no el valor devuelto. Esto
que parece lógico, algunas veces puede llevar a confusión e
incluso producir efectos no deseados en el programa.
Prueba con esta nueva versión de la función Existe. En un form
debes poner una etiqueta Label1.
Private Function Existe(Archivo As String) As Integer
Existe = Len(Dir$(Archivo))
If Existe Then
Label1 = Archivo & " Si existe"
Else
Label1 = Archivo & " No existe"
End If
'Esto es más corto, pero talvez menos evidente:
'Label1 = Archivo & IIf(Existe, " Si", " No") & " existe"
DoEvents
End Function
Private Sub Form_Load()
Dim A As Integer, Nombre As String
Show
Label1 = ""
Nombre = "C:\Autoexec.BIN"
A=5
If A > 10 And Existe(Nombre) Then
Print A; "mayor de 10 y " & Nombre & " existe"
Else
Print A; "no es mayor de 10 o " & Nombre & " no existe"
End If
End Sub
En el ejemplo
comprobarás que a pesar de que la segunda parte de la
comparación no se cumpla, a no ser que tengas en tu disco C un
archivo que se llame así, el caption del Label se ha cambiado.
Es decir que se ha procesado la segunda parte de la expresión a
pesar de que la primera A>10 es FALSA. Imaginate que en lugar
de ser una función rápida, hubiese sido otra cosa que tardara
un poquito más de la cuenta...
Para casos como estos, (la verdad es que no son demasiado
habituales), deberías hacerlo así:
Private Sub Form_Load()
Dim A As Integer, Nombre As String
Show
Label1 = ""
Nombre = "C:\Autoexec.BIN"
A = 5
If A > 10 Then
If Existe(Nombre) Then
Print A; "mayor de 10 y " & Nombre & " existe"
Else
Print A; "es mayor de 10 pero " & Nombre & " no existe"
End If
Else
Print A; "no es mayor de 10 o " & Nombre & " no existe"
End If
End Sub
Talvez sea
más largo y haya que usar más código, pero en ocasiones es
más "resultón".
Usando este nuevo "estilo", sólo se comprobará si
existe el archivo cuando A sea mayor que diez. Lo que debes sacar
en claro de todo esto es que después de un THEN puedes
"anidar" más expresiones IF...THEN...ELSE. Incluso se
puede usar en una sóla línea, sólo que el resultado
"visual" del código no es tan
"presentable"...
If A > 10 And Existe(Nombre) Then Print A; "mayor de 10 y " & Nombre & " existe" Else Print A; "no es mayor de 10 o " & Nombre & " no existe"
Aunque podríamos usar el caracter _ que se puede usar en VB para separar líneas largas, pero es como si estuviese toda en la misma línea, así que la línea anterior, se quedaría así:
If A > 10 And Existe(Nombre) Then _
Print A; "mayor de 10 y " & Nombre & " existe" _
Else _
Print A; "no es mayor de 10 o " & Nombre & " no existe"
Fijate que a pesar de aparentar que es un BLOQUE IF, no tiene el END IF del final, esto es porque yo lo he "estructurado" de esa forma, no porque sea lo mismo. El uso de _ es sólo estético y para VB todo se trata de una misma línea, por tanto tendrá un límite de caracteres posibles a usar, el límite que VB le ponga, que creo que es 1024... pero no me hagas demasiado caso...
Antes he mencionado la palabra "anidación", ésta se usa para indicar que una serie de instrucciones están dentro de otras. En este caso hemos anidado dos IF... THEN, pero lo más habitual es hacerlo con los bucles (FOR, DO, etc), veamoslo:
Dim i%, j%, c%
For i = 1 To 10
For j = 1 To 10
c = c + 1
Next
Next
Print c
Lo que debes
saber, o al menos tener en cuenta, es que cuando anidamos varios
bucles, lo externos empiezan antes (elemental querido Watson),
pero los internos finalizan primero (...) y hasta que no lo
hagan, no podrán continuar los de fuera.
En el ejemplo, por cada repetición del bucle i, se completa un
bucle j. Por eso el valor de c es 100 (10*10)
Esto, en ocasiones, puede ralentizar el programa, y dar la
impresión de que el programa se ha quedado "colgado",
prueba a poner otro bucle dentro del j y cambia los valores
máximo de los dos bucles internos a 1000, te recomiendo que la
variable c sea LONG y que te sientes... No hace falta que hagas
la prueba, es una chorrada...
Lo que interesa es que dentro de un proceso cualquiera y por
supuesto también en los bucles, podríamos necesitar que el
Visual Basic nos mostrara alguna indicación de que está
"ocupado", por ejemplo cambiando la forma del cursor
del ratón, como hacen otros programas, incluso el propio VB
cuando está "atareado". Para ello tendremos que
cambiar la propiedad MousePointer para que muestre el reloj de
arena:
MousePointer = vbHourGlass 'vbHourglass es igual a 11, por si
tienes usas el VB3
'... lo que sea
MousePointer = vbDefault '0 si usas VB3
Pero algunas veces el cursor no se cambia... para asegurarnos que
cambie, usa el DoEvents después de asignar el valor para el
reloj de arena. De esta forma permitimos que Windows procese sus
mensajes (¿recuerdas?) y así tiene ocasión de cambiar el
puntero del ratón.
Bueno, hasta
aquí llega esta entrega. No hay ejercicios, sólo te pediría
que revisaras la ayuda y te leyeras lo que allí pone referente a
las instrucciones que vamos viendo... aunque me imagino que
tendrás otras cosas que hacer...
El caso es que no hay ejercicios y ya está.
Siguiendo con la costumbre todas las entregas anteriores, te pido tus comentarios sobre esta entrega y el curso en general, más que nada para saber si voy bien encaminado y no me pierdo, lo que pretendo es que se entienda y que aprendas...
Ya me
contarás.
Nos vemos en la próxima entrega, que espero que no sea tan
tardona como esta...
![]()