Crear
funciones
|
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 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 compráis 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 porque
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 posibles 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, realmente 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 una 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 ejemplo:
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 siempre 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; comprobémoslo:
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 es lo 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 esperábamos... 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. Imagínate 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 sola 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"
Fíjate 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.), veámoslo:
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á.
Nos vemos en la próxima entrega, que espero que no sea tan tardona
como esta...

