Visual Basic

143
  A estas alturas no es fácil hacer un curso de introducción a la programación con Visual Basic. Si fuese a raiz de la primera o segunda versión, incluso con la tercera, sería más fácil. Pero ahora está más crudo, por aquello de que soporta 16 y 32 bits y te enfocas en una u otra dirección o... Pero como el título indica, esto será una cosa para introducir al que quiere empezar a programar, incluso para el que viene de otro lenguaje, aunque seguramente, sobre todo al principio, se encontrará con conceptos demasiados básicos. Como este curso no se publica sobre algo que ya está terminado, iré haciéndolo sobre la marcha, espero tus indicaciones sobre si voy demasiado rápido o si realmente me estoy pasando en cuanto a 'simpleza'. De cualquier forma, me gustaría oir tu comentario y tus impresiones, eso me animará a seguir y sobre todo a terminar. Bueno, manos a la obra. A ver como me sale el tema, (al final no he encontrado los apuntes que ya tenía hechos, de cuando daba clases a niños y a no tan niños, de esto hace ya 10 añillos de nada) Lo advierto, a los que saben algo y a los que lo saben todo (o casi todo), lo que viene a continuación es super básico. Y pensando también en los que por una razón u otra no tienen unos conocimientos que a otros les parecerá absurdo, sé que aún hay gente que no tienen ni 'repajolera' idea de lo que es una expresión, una variable y ni que decir tiene sobre las matrices, los números binarios o la notación hexadecimal...  ¿Que es una variable? En cualquier programa siempre necesitaremos hacer cálculos, usar información, procesarla y mostrarla. En la mayoría de los casos, necesitaremos un lugar temporal en el cual guardar parte de esa información, incluso toda. Todos los lenguajes, y el Basic no iba a ser menos, nos permiten guardar datos en la memoria, para que cuando los necesitemos, podamos tomarlos, modificarlos y volverlos a guardar para usarlos más tarde. Si no seguimos unas normas o usamos unas reglas, de poco nos iba a servir el guardar esa información, si después no podemos almacenarla en ningún sitio, pero ese será tema de otro capítulo... ahora centremosno en la memoria. ¿La memoria? Espero que este concepto lo tengas claro, pero si no es así, ahí va un poco de 'rollo': La memoria es el lugar donde el ordenador almacena de forma temporal los programas y parte de la información que necesita o utiliza. Así pues, los lenguajes de programación usan también esa memoria para guardar información propia del lenguaje y del programa que queramos realizar. El programa una vez que se está ejecutando puede necesitar también guardar información, aunque esta información sólo estará disponible mientras se esté ejecutando. Esas posiciones o lugares de la memoria donde los programas pueden almacenar información son las variables. El que se llamen de esta forma es porque podemos hacer que el contenido de ese lugar de almacenamiento varie, es como si tuviesemos una serie de cajas y en ellas pudiesemos guardar cosas, con la salvedad de que en cada caja sólo puede haber una cosa a la vez; aunque también veremos cómo hacer que el contenido pueda variar y que varie dependiendo de lo que contenía antes... Veamos un ejemplo: Imaginate que quieres guardar tu nombre en una variable, para ello tendriamos que 'guardar' el nombre en la memoria, es decir asignar a una variable un valor. En este caso nuestro nombre. Para ello el lenguaje de programación pone a nuestra disposición unos lugares deonde almacenar nuestro nombre, pero nos impone una serie de reglas de conducta. Si queremos guardar en una de nuestras cajas una hoja, por lo menos tendremos una caja con el tamaño adecuado y que tenga una 'forma', para que el papel no vuele al menor soplo de viento.

Transcript of Visual Basic

&XUVR%iVLFRGH3URJUDPDFLyQHQ9LVXDO%DVLFINTRODUCCIN A estas alturas no es fcil hacer un curso de introduccin a la programacin con Visual Basic. Si fuese a raiz de la primera o segunda versin, incluso con la tercera, sera ms fcil. Pero ahora est ms crudo, por aquello de que soporta 16 y 32 bits y te enfocas en una u otra direccin o... Pero como el ttulo indica, esto ser una cosa para introducir al que quiere empezar a programar, incluso para el que viene de otro lenguaje, aunque seguramente, sobre todo al principio, se encontrar con conceptos demasiados bsicos. Como este curso no se publica sobre algo que ya est terminado, ir hacindolo sobre la marcha, espero tus indicaciones sobre si voy demasiado rpido o si realmente me estoy pasando en cuanto a 'simpleza'. De cualquier forma, me gustara oir tu comentario y tus impresiones, eso me animar a seguir y sobre todo a terminar. Bueno, manos a la obra. A ver como me sale el tema, (al final no he encontrado los apuntes que ya tena hechos, de cuando daba clases a nios y a no tan nios, de esto hace ya 10 aillos de nada) Lo advierto, a los que saben algo y a los que lo saben todo (o casi todo), lo que viene a continuacin es super bsico. Y pensando tambin en los que por una razn u otra no tienen unos conocimientos que a otros les parecer absurdo, s que an hay gente que no tienen ni 'repajolera' idea de lo que es una expresin, una variable y ni que decir tiene sobre las matrices, los nmeros binarios o la notacin hexadecimal... Que es una variable? En cualquier programa siempre necesitaremos hacer clculos, usar informacin, procesarla y mostrarla. En la mayora de los casos, necesitaremos un lugar temporal en el cual guardar parte de esa informacin, incluso toda. Todos los lenguajes, y el Basic no iba a ser menos, nos permiten guardar datos en la memoria, para que cuando los necesitemos, podamos tomarlos, modificarlos y volverlos a guardar para usarlos ms tarde. Si no seguimos unas normas o usamos unas reglas, de poco nos iba a servir el guardar esa informacin, si despus no podemos almacenarla en ningn sitio, pero ese ser tema de otro captulo... ahora centremosno en la memoria. La memoria? Espero que este concepto lo tengas claro, pero si no es as, ah va un poco de 'rollo': La memoria es el lugar donde el ordenador almacena de forma temporal los programas y parte de la informacin que necesita o utiliza. As pues, los lenguajes de programacin usan tambin esa memoria para guardar informacin propia del lenguaje y del programa que queramos realizar. El programa una vez que se est ejecutando puede necesitar tambin guardar informacin, aunque esta informacin slo estar disponible mientras se est ejecutando. Esas posiciones o lugares de la memoria donde los programas pueden almacenar informacin son las variables. El que se llamen de esta forma es porque podemos hacer que el contenido de ese lugar de almacenamiento varie, es como si tuviesemos una serie de cajas y en ellas pudiesemos guardar cosas, con la salvedad de que en cada caja slo puede haber una cosa a la vez; aunque tambin veremos cmo hacer que el contenido pueda variar y que varie dependiendo de lo que contena antes... Veamos un ejemplo: Imaginate que quieres guardar tu nombre en una variable, para ello tendriamos que 'guardar' el nombre en la memoria, es decir asignar a una variable un valor. En este caso nuestro nombre. Para ello el lenguaje de programacin pone a nuestra disposicin unos lugares deonde almacenar nuestro nombre, pero nos impone una serie de reglas de conducta. Si queremos guardar en una de nuestras cajas una hoja, por lo menos tendremos una caja con el tamao adecuado y que tenga una 'forma', para que el papel no vuele al menor soplo de viento. Esta es la regla bsica para poder usar esos lugares de almacenamientos (variables): Llamar a esas posiciones de memoria con un nombre. Simple, verdad? En principio, es todo el requisito necesario: que le demos un nombre al sitio en el que queremos guardar la informacin. Por tanto, si queremos guardar un nombre, (el nuestro, por ejemplo), en la memoria, podramos llamarlo nombre.Y ahora tendremos que seguir otra norma de conducta (o funcionamiento), que en este caso el lenguaje Basic nos dicta: Para guardar en una variable (posicin de memoria) algo, debes hacerlo de la siguiente manera: ---Pon el nombre con el que quieres llamar a esa parte de la memoria, ---a continuacin pones el signo igual (=) y---despus lo que quieras guardar. Por tanto para guardaren la variables nombre, tendriamos que hacer (o casi): Nombre =Pero esto poda llevar a confusin, ya que el Basic no nos dice nada sobre cmo debemos llamar (o si lo prefieres, cmo hay que escribir) el nombre de una variable, por tanto tambin podra ser una variable, (es que el Basic, a pesar de que llevo tantos aos bregando con l, no sabe que ese es mi nombre!!!). As pues, cuando queramos guardar en una variable una palabra, una frase, nombre o cualquier tipo de informacin alfabtica, tendremos que indicarlo poniendo dicha informacin dentro de comillas dobles, el ejemplo quedara as: Nombre = "" Ahora no hay confusin posible, hemos seguido lo que el Basic nos ha dicho: variable, signo igual, valor a almacenar. Si queremos guardar un nmero en una variable, la cosa es ms simple: Numero = 7 Te ests enterando? Pero, que ocurre si quisieramos repetir 7 veces a ? Podras hacer esto, multiplicar apor 7 (como no hay bastante con uno...)Paliza = "" * 7 Pero el Basic te dira que eso no est bien, no porque(yo) no sea un paliza, sino porque te dira que no coinciden los tipos (Type Mismatch) Que son los tipos? Los distintos tipos de datos. (que esfuerzo mental...)Los datos pueden ser, bsicamente, de dos tipos: Numricos: slo nmeros y Alfanumricos: cualquier cosa, letras y/o nmeros, pero es tratada como si fuesen palabras, frases, etc. Para el Basic 7 y "7" son dos tipos de datos diferentes. El primero es el nmero 7 y en el segundo caso, es el literal (o palabra) "7" As que cuando veas algo entrecomillado, piensa que no es un nmero, sino una palabra (ms vulgarmente llamada cadena de caracteres o string en ingls) Hemos visto que no podemos multiplicar una palabra (cadena) por un nmero, pero si podemos multiplicar una variable por un nmero (siempre que la variable sea numrica, por supuesto) Segn esto, el Basic debera permitir hacer esto: = 5 Paliza =* 7 El Basic tomara el 5 y lo almacenara en ena variable numrica llamada . Despus se encuentra con: Paliza =* 7 y aqu lo que hace es evaluar la expresin que est despus del signo igual, lo calcula y el resultado lo guarda en la variable que est a la izquierda del signo de asignacin (=) Expresin? Expresin es cualquier cosa que el Basic tenga que 'desglosar' para poder entenderla, incluso a veces ni eso... Por ejemplo cuando el Basic se encuentra con 5 * 2 tiene que 'evaluar' lo que significa, para poder hacer el clculo, de esta forma sabr que tenemos una operacin en la cual queremos multiplicar dos nmeros, una vez que ha evaluado nuestra intencin de multiplicar esos dos nmeros, efectuar el clculo y almacenar el resultado en... si no le decimos dnde, lo har en una memoria que tiene para esas cosas, pero si no le indicamos que debe hacer con ese resultado, nos dar un error... Si le decimos simplemente: 5 * 2 El Basic no sabr que hacer con el resultado de esta 'expresin' (que por cierto es 10) y nos dir: o te espabilas o lo tienes crudo conmigo. As que lo ms juicioso sera decirle: vale, vale, guardalo en una variable, as que: Resultado = 5 * 2 guardara un 10 en la variable Resultado.Tambin podramos decirle que nos mostrara el resultado, en lugar de guardarlo en una variable, y aqu llega nuestra primera instruccin: Print. Con ella le decimos al Basic que lo imprima (o sea que los muestre, ms adelante vermos dnde), segn lo dicho, haciendo esto: Print 5 * 2, el Basic dira que muy bien y mostrara un 10 Pero, volvamos al Paliza del , es decir al ejemplo de Paliza =* 7 Si quisieramos mostrar el valor de Paliza, tendramos que hacer algo como esto: Print Paliza, y nos mostrara 35, ya que el valor de Paliza sera 35, porque el contenido dees 5 y 5 * 7 es 35 (y sin calculadora!!!)Veamos si es cierto quevale 5. Haciendo Print , mostrar un 5. LECCION 1. Antes de seguir imaginando las cosas, vamos a verla en funcionamiento. Es decir vamos a probar que todo esto es cierto. Carga el Visual Basic (si es que an no lo has hecho. Te crear un Form nuevo, que estar vaco. Cierralo y muestra la ventana de cdigo. Mostrar la parte de las declaraciones Generales del Formulario. Si tiene escrito Option Explicit, (estar en la parte superior), borralo, ms adelante te explicar para que sirve. Ahora situate en Form (seleccionalo de la lista desplegable que est a la izquierda), te mostrar: Private Sub Form_Load() End Sub Situate en medio, es decir, en una lnea en blanco despus del Private... y escribe el ejemplo, quedara as: Private Sub Form_Load() = 5 Paliza =* 7 Print Paliza End Sub Pulsa F5, para ejecutar el programa, y vers que se escribe el 35. Bien, ya tienes una forma de mostrar datos. Ahora veamos otros ejemplos, antes debes parar el programa, para ello cierra el Form, pulsando en el botn que tiene una X, o bien pulsa en el botn detener de la barra de herramientas del VB. Situate de nuevo en el cdigo del Form_Load, escribe despus de la lnea del Print, lo siguiente: PrintPulsa de nuevo F5 y vers que ahora adems del 35, hay un 5 debajo. El valor de la variable . Pero, que ocurrira si cambiasemos el valor de ? Aade estas lneas a continuacin de la anteriores, para que quede de esta forma: Private Sub Form_Load() = 5 Paliza =* 7 Print Paliza Print= 10 PrintPrint Paliza End Sub Despus de pulsar F5, te mostrar los siguientes valores (cada nmero en una lnea), 35, 5, 10, 35 Esperabas que el ltimo fuese 70? Fijate que cuando asignamos a Paliza el contenido de , ste era 5, por tanto el Basic evalu la expresin 5 * 7 y almacen el resultado (el 35). Una vez almacenado el resultado, el Basic se olvid de dnde haba sacado ese 5. Si queremos que se 'actualice' el valor de Paliza, tendremos que indicarselo de nuevo al Basic, para que vuelva a evaluar la expresin y hacer la correspondiente asignacin. Para ello, pon en medio de los dos ltimos prints la siguiente asignacin: Paliza =* 7 Esta vez, al ejecutar el programa, mostrar un 70, que ser el nuevo contenido de Paliza.Ya para terminar, borra todo lo anterior y escribe: (por supuesto debes detener el programa...)Private Sub Form_Load() Nombre = "" Print Nombre End Sub Pulsa F5 y vers que se muestra el contenido de la variable Nombre, es decir . Prueba ahora con esto otro (es un clsico): Print "Hola Mundo"Y para rematar, y de camino ver otra posiblidad del Print, escribe en lugar del Print Nombre:Print "Hola " ; Nombre El punto y coma, se usa para indicarle al Basic que se deben mostrar las cosas una a continuacin de la otra. Ahora te habr mostrado: Hola , fijate que despus de hola y antes de cerrar las comillas hay un espacio. Nota: En todos Ios FORM_LOAD debers poner SHOW aI principio para que se muestre Io que se imprime. LECCION 2. Seguimos con este cursillo bsico. Antes de nada una pequea aclaracin, para que los ejemplos que se dieron en la leccin anterior, debers poner un Show en el form Load antes de los Prints, para que se muestre algo... sino no se ver nada. Una vez hecha esta pequea puntualizacin, vamos a la tarea. El tema de hoy ser sobre el manejo de entrada de datos y una forma un poco ms prctica de mostrar los datos, empezaremos a vernos ya con lo que es programar con Windows, es decir el manejo de eventos, o al menos el movernos dentro de los eventos y saber "controlarlos" para las cosas que queramos hacer. Con el "basic clsico", no haba problemas. Las cosas se producan de forma lineal, es decir empezaban por el principio del programa y se iban ejecutando a medida que se avanzaba por l. Salvo en las ocasiones en las que en un momento dado "saltabamos" a otro sitio, pero era porque nosotros as lo habamos programado. De una forma u otra tenamos control total sobre lo que poda ocurrir. Pero en Windows (o los entornos dominados por los eventos), la cosa no es tan sencilla. Debemos controlar todas (o casi) las posibilidades que se pueden producir... Antes vamos a dejar un par de cosillas claras. Segn como tengas configurado el entorno de desarrollo, habrs tenido problemas con los ejemplos de la leccin anterior. La razn es que el Visual Basic nos permite controlar un poco mejor el tema de las variables que queremos usar. Ese control lo da la instruccin: Option Explicit. Si ponemos esto en la parte destinada a las declaraciones de cualquier mdulo, nos obligar a declarar las variables que vamos a usar en dicho mdulo. En el ltimo ejemplo de la leccin anterior, tenamos una variable llamada Nombre, en la cual almacenamos un nombre, por tanto podramos haberle avisado a Visual Basic que reservara espacio para una variable, y para hacerlo usamos la instruccin DIM, con sta le indicamos que nos guarde un "cachillo" de la memoria para nuestro uso: Dim Nombre Tambin nos ofrece una variante con respecto al "basic clsico" y es, precisamente, el tipo de datos variant. Con este tipo podemos asignar a una variable cualquier tipo de dato. Desde un nmero hasta una cadena de caracteres, psando por cualquier tipo de objeto que Visual Basic pueda manejar (ms o menos). Los que hayan tenido experiencias anteriores, con Basic u otro lenguaje, sabrn que cada variable debe ser del tipo de datos que queramos asignarle. En VB por supuesto esto tambin es posible y recomendable. Ya vimos que los tipos de datos podan ser numricos o de caracteres. Pero dentro de los numricos, tenemos cuatro tipos bsicos: enteros, enteros largos, simples y dobles. Cada uno de ellos tienen unas capacidades determinadas, adems de ocupar ms memoria o menos, (ahora lo veremos), lo ms importante es que los nmeros enteros y entero largo slo admiten nmeros enteros (de ah sus nombres), es decir que no admiten decimales. Sin embargo los otros dos si admiten decimales. Estas capacidades puedes encontrarlas en el manual del basic o en la ayuda, lo que a mi me interesa que sepas es cmo poder indicarle al Visual Basic que reserve ese espacio de memoria para un tipo determinado. Ya te he dicho que el espacio que ocupa en memoria es diferente para cada uno de estos tipos, veamos en la siguiente tabla cmo declararlos y cuanto ocupa: TipoEspacio ocupado Tipo de declaracinEjemplo Entero2 bytesIntegerDim Numero As Integer Entero Largo4 bytesLongDim Numero As Long Simple4 bytesSingleDim Numero As Single Doble8 bytesDoubleDim Numero As Double En el caso de las variables que van a guardar nombres (cadenas de caracteres), se deben declarar como String y el espacio que ocupa ser 4 bytes ms un byte por cada caracter que tenga, en el caso de VB de 32 bits realmente ocupar 2 bytes por cada caracter que tenga. La longitud mxima de una variable del tipo String ser de aproximadamente 32.000 caracteres y la forma de declararla ser: Dim Cadena As String Una vez declarada podemos asignarle la cantidad de caracteres que queramos (sin pasarnos) y cuantas veces queramos. Hay que tener en cuenta que en cualquier variable slo se queda el ltimo valor asignado. Ya lo vimos en la leccin anterior, pero vamos a refrescarlo un poco: Dim Nmero As Integer Nmero = 5 Print Nmero Nmero = 12 Print Nmero En este ejemplo, el ltimo valor almacenado en Nmero es el 12. El 5 que tena en un principio se perdi. Pero, que tengo que hacer para sumarle una cantidad al valor almacenado en una variable? Es decir, cmo incrementar el valor de una variable numrica? La respuesta la tienes en cmo se manejan las expresiones y las asignaciones a las variables. Como ya vimos anteriormente, al asignar a una variable una expresin, primero se calcula la expresin y una vez obtenido el resultado, se asigna a la variable. Recuerdas lo que ocurra con la variable Paliza? Vamos a verlo de nuevo, pero usando otros nombres menos "cachondos" Dim N As Integer Dim M As Integer N = 10 M = N * 3 Print M El resultado de este programa sera 30, que es lo que resulta de multiplicar 10 por 3. Cuando se asigna a la variable M el valor de N (que es 10) multiplicado por 3, el VB toma el contenido de N y lo multiplica por 3. Una vez que sabe la solucin, asigna ese valor, en este caso 30) a la variable que hay a la izquierda del signo igual. Sabiendo esto, podriamos simplificar la cosa y hacer los siguiente: N = N * 3 Print N Tambin obtendriamos 30. Ya que cuando el Basic calcula la expresin de la derecha del signo igual, N vale 10, una vez obtenido el resultado del clculo lo asigna a la variable de la izquierda del signo de asignacin, sin importarle lo ms mnimo de que variables es y como en este caso hemos usado la misma, pues se queda el ltimo valor, perdindose el que originalmente estaba "guardado". Esto es til cuando necesitamos "contar" de forma secuencial, para as incrementar el valor de una variable. Ya veremos alguna "utilidad" para estos casos. Ahora vamos a ver cmo podemos manejar las cadenas de caracteres, es decir las variables de tipo String. Con estas variables ocurre lo mismo que con las numricas, pero la nica operacin que podemos realiazar es la suma. Realmente una suma en una cadena de caracteres es "pegar" dos cadenas en una sola. Por ejemplo si hacemos esto: N = 3 + 2. El valor obtenido es 5 y eso es lo que se guarda en N. Sin embargo con los strings hacer esto: Cadena = "A" + "B", se guardar "AB", es decir se unirn las dos cadenas en una sola. Para este tipo de operacin se recomienda usar mejor el signo &. Que entre otras cosas le indica al Visual Basic que lo que pretendemos hacer es unir dos cadenas, no sumarlas. Aunque "tericamente" no se pueden sumar cadenas, slo con-catenarlas, veremos cmo podemos llegar a producir "problemillas" de entendimiento entre el VB y nuestras "mentes poderosas". Como te he comentado al principio el tipo de datos Variant acepta de todo, nmeros, nombres, etc. Si no le indicamos de forma correcta al VB cual es nuestra intencin, podemos confundirle y hacer que el resultado de algo que nosotros dabamos "por hecho", al final se convierte en un pequeo caos para nuestras pobres mentes. Vamos a verlo con un par de ejemplos, en estos casos: (al no indicarle de que tipo son las variables, el Basic entiende que nuestra intencin es usar el tipo Variant) Dim Num1 Dim Num2 Num1 = 5 Num2 = 3 Num1 = Num1 + Num2 Print Num1 Que imprimir? Pruebalo y saldrs de duda. Bueno, imprimir un 8. Ahora veamos este otro ejemplo: Dim Num1 Dim Num2 Num1 = "5" Num2 = "3" Num1 = Num1 + Num2 Print Num1 Fijate que lo que vara es slo las comillas. El resultado en este caso es 53, es decir ha unido las dos cadenas. Ahora quita las comillas del 5, para dejarlo as: Dim Num1 Dim Num2 Num1 = 5 Num2 = "3" Num1 = Num1 + Num2 Print Num1 Alehop! Que ha pasado? Pues que ha impreso un 8, es decir ha "pasado" de que el tres sea una cadena de caracteres y lo ha tomado por un nmero... En esta ocasin, slo vamos a cambiar la lnea de la asignacin para dejarla de esta forma: Num1 = Num1 & Num2 El resultado ser 53. Porque le hemos indicado que una las dos cadenas, por tanto al encontrase con esta "operacin" ha considerado al nmero 5 como una cadena, en lugar de un nmero. Cambia ahora la asignacin del Num2, para que sea: Num2 = 3 Vuelve a mostrar 53, el signo & tiene unos poderes enormes... y a pesar de ser dos nmeros la nica operacin que puede realizar es la concatenacin de cadenas, por tanto el tipo Variant se convierte por arte de mgia en cadena. Pero fijate si es "fuerte" el poder de conviccin que tiene este operador, que aunque cambiemos el tipo de las variables, sigue "convenciendo" al basic que tipo de operacin debe hacer. Esto no debera ocurrir as, pero ocurre. Dim Num1 As Integer Dim Num2 As Integer Num1 = 5 Num2 = 3 Num1 = Num1 & Num2 Print Num1 Sigue mostrando 53, aunque en este caso debera producir un error, ya que un Integer no es una cadena. As que "cuidadn" con las operaciones que realizamos. Ya que si aades esta lnea: Print Num1 * 2 vers que realmente Num1 tiene guardado un nmero y el resultado ser: 106 A dnde nos lleva todo esto? A que debemos usar los signos (operadores) de forma adecuada. Y si nuestra intencin es sumar nmeros, empleemos el signo +, en caso de que queramos unir cadenas de caracteres, usaremos el & Para rematar esta segunda leccin, vamos a usar un textbox para que se puedan introducir datos y empecemos a manejar los eventos, mejor dicho empecemos a "habituarnos" a los eventos. Aade al form dos Label, un TextBox y un botn de comandos. El aspecto ser algo parecido al de la siguiente figura: Aade el siguiente cdigo y despus ejecuta el programa, ya sabes F5. Escribe algo en el cuadro de texto y pulsa en el botn. Private Sub Form_Load() Label2 = "" Text1 = "" End Sub Private Sub Command1_Click() Label2 = "Hola " & Text1 End Sub Cuando pulsas F5, se produce el evento Form_Load, por tanto se asigna al Label2 y al Text1 una cadena vaca, con lo cual borramos el contenido anterior, que es el que se muestra en la Figura. Hasta que no pulsemos el botn mostrar, no ocurrir nada y el programa estar esperando a que ocurra algo. Una vez pulsado el botn, se produce el evento Click del Command1 y se hace lo que se indica en su interior, que es tomar lo que hay en la caja de texto y unirla a la palabra Hola, para asignarla al Label2. Ahora, imaginate que quieres mostrar el nombre en maysculas. Lo nico que tendras que hacer es lo siguiente: Private Sub Command1_Click() Label2 = "Hola " & UCase(Text1) End Sub Lo que se ha hecho es decirle al VB que convierta en maysculas lo que ya est en Text1. Esa es la "utilidad" del UCase. Pero y si quisieramos que conforme se va escribiendo se vayan convirtiendo los caracteres a maysculas? Aqu entraran ms instrucciones/funciones del Visual Basic, as cmo otro de los eventos que pone a nuestra disposicin, en este caso el evento que se produce cada vez que se modifica el contenido del textbox: Change, escribe lo siguiente: Private Sub Text1_Change() Text1 = UCase(Text1) End Sub Pruebalo y vers lo que ocurre. Queda "guay" verdad? Pero no es lo que nosotros pretendiamos. Vamos a intentar remediarlo y de camino vemos nuevas instrucciones/propiedades, en este caso del TextBox. Private Sub Text1_Change() Text1 = UCase(Text1) Text1.SelStart = Len(Text1) End Sub La lnea que se ha aadido (realmente la habrs tecleado t), lo que le indica al Visual Basic es que haga lo siguiente: Calcula la longitud del contenido del Text1, (Len cuenta los caracteres de una cadena y lo devuelve como nmero), SelStart es una propiedad del TextBox que entre otras cosas, le indica la posicin en la que se insertar el siguiente caracter que se escriba o bien nos puede indicar la posicin actual del cursor. Por tanto obliga a poner el cursor, (el palico ese que parpadea y que nos indica que podemos escribir), al final de la ltima letra que contiene el Text1. Ahora ya sabes que cada vez que "cambie" el Text1, se produce un evento Change. Pero hay otra forma de hacer esto mismo y es controlando cada tecla que se pulsa. Esto lo podemos "controlar" en el evento KeyPress, el cual se produce cada vez que se pulsa una tecla. Borra el procedimiento anterior y escribe este otro: Private Sub Text1_KeyPress(KeyAscii As lnteger) Dim s As String s = UCase(Chr(KeyAscii)) KeyAscii = Asc(s) End Sub Ahora han entrado dos nuevas funciones en accin: Chr, la cual convierte un nmero en una cadena... realmente convierte un cdigo ASCII en la letra que representa (busca en la ayuda ASCII y leete lo que dice en las opciones que te muestra). Por otra parte Asc hace lo contrario, es decir convierte una letra en el cdigo ASCII. Y lo que nosotros hacemos es: convertir el cdigo de la tecla pulsada, representado por la variable KeyAscii, en una cadena, la pasamos a maysculas y despus la volvemos a asignar a la variable, para "engaar" al Visual Basic y as hacerle pensar que realmente hemos tecleado una letra en maysculas. Bueno, aqu voy a dejar la cosa, pues creo que con esto es te puedes ir "entreteniendo". LECCIN 3. Esta leccin la voy empezar con recomendaciones e instrucciones del buen hacer en Visual Basic, espero que sigas algunas, preferiblemente todas, estas normas. Ya has visto cmo maneja el Visual Basic las variables, si a esta "libertad" (aunque ms bien es libertinaje), le aadimos que no nos obliga a nada, es decir el VB nos est diciendo: "puedes usar las variables para lo que quieras, cmo quieras (o casi) y cuando quieras" Y esto en principio podra parecer una buena cosa, pero realmente es un mal hbito, que muchos de los que vens del BASIC, ya teneis formado y creo que ahora sera un buen momento para empezar a cambiar. Lo primero que debes hacer es ir al men Herramientas (Tools) y en Opciones (Options) marca la casilla que indica "Requerir declaracin de variables" (Require Variable Declaration), esto aadir a cada nuevo mdulo (FRM, BAS o CLS) la siguiente instruccin: Option Explicit, de esta forma tendrs la obligacin de declarar cada una de las variables que uses en el programa. Y tu preguntars: Para que obligar a que se declaren las variables? La respuesta es bien sencilla: para que las declares... (algunas veces me asombro de la lgica tan aplastante de mis comentarios)Bromas aparte, es recomendable que declares las variables que vayas a usar y te dira ms: no slo es bueno declarar las variables, sino que mejor an es declararlas del tipo adecuado. Ya vimos que hay diferentes tipos de variables, no slo de tipos genricos como podran ser para almacenar caracteres y nmeros, sino que dentro de las numricas hay varios tipos, y cada uno de ellos tiene una razn de ser. En mis tiempos del BASIC normalito, es decir del MS-DOS, no exista esta obligacin de declarar "forzosamente" las variables y cuando estabas escribiendo un programa (proyecto que lo llaman ahora), grande, acababas "invitablemente" usando ms variables de la cuenta porque ya no recordabas si la variable "i" o "j" estaba siendo usada a nivel global o no... (yo es que con el despiste que gasto, me vea creando las variables "ii", "j2", etc, para no "meter la pata") y esto no era lo peor, al fin y al cabo lo nico que ocurra era que estaba "desperdiciando" memoria, por no tener un control de las variables que estaba usando; lo malo era que se podan escribir errneamente los nombres de las variables de forma que al final, el programa no funcionaba bien porque al escribir un nombre de variable, habamos cambiado el nombre... era frustrante y algunas veces te volvas loco buscando el fallo... La ventaja de usar el Option Explicit, es que si escribes mal una variable, el VB te avisa... bueno, algunas veces te avisa, sobre todo cuando se encuentra con la variable "mal escrita". Aqu viene la segunda recomendacin del da: cuando ejecutes un programa, hazlo con Control+F5, de esta forma se hace una compilacin completa y "ms o menos" exhaustiva del cdigo, avisndote cuando hay algo que no "cuadra", con el VB3 no haba problemas, ya que siempre se haca la compilacin completa, pero desde el VB4 se puede pulsar F5 y hasta que no llega al procedimiento actual, no comprueba si todo lo que hay en l est correcto. As que para "curarte en salud" procura hacer la compilacin completa La tercera recomendacin no es obligatoria, siempre que sigas la que voy a dar despus, esta es uan norma que tambin he usado desde mis tiempos de MS-DOS (aunque reconozco que ltimamente no la pongo en prctica, ya que hago lo que despus comentar en la cuarta recomendacin). En todos los mdulos, antes slo eran BAS, pona al principio la siguiente lnea: DEFINT A-Z de esta forma le indicaba al BASIC que mi intencin era usar todas las variables del tipo Integer (entero), (realmente despus usaba del tipo que me daba la gana, pero mi primera intencin era no complicarme la vida con la mayora de las variables), cuando quera usar una variable diferente de Integer, le indicaba "explicitamente" de que tipo era y as me obliga a usar la mayora de ellas de este tipo que a la larga es o era el ms usado, ya que para hacer bucles (ya te explicar en un ratillo que es eso de los bucles y cmo hacerlos en VB) y otros clculos "normales", era ms que suficiente y en la mayora de los casos: ms rpido. En Basic, y por supuesto todava en Visual Basic, aunque cada vez va a menos, se puede indicar el tipo de una variable de varias formas, al declararlas con Dim, vimos que se haca de la siguiente forma: Dim unNumero As Integer Dim unNumeroLargo As Long Dim otroNumero As Single Dim masNumeros As Double Dim unNombre As String Dim multiUso As Variant Cada una de estas varibales es de un tipo distinto, las cuatro primeras numricas, la quinta para almacenar cadenas de caracteres y la ltima del tipo por defecto del VB: Variant que como su nombre indica (aunque en ingls), es Variante y puede almacenar prcticamente cualquier cosa, objetos incluidos, (ya veremos los objetos en otra ocasin). Lo del tipo por defecto, es siempre que no se haya especificado un tipo determinado para todas las variables, por ejemplo usando el DEFINT A-Z, el tipo por defecto ya no es Variant, sino Integer. Al grano, "quesnoche", a lo que iba era que adems de declarar las variables de esta forma, tambin se puede hacer de de esta otra: Dim unNumero% Dim unNumeroLargo& Dim otroNumero! Dim masNumeros# Dim unNombre$ En el caso de Variant no existe un caracter especial para indicar que es de ese tipo, as que cuando quieras usar una varible Variant, tendrs que declararla como en el primer ejemplo. An queda otro carcter para otro tipo de datos numrico, el tipo Currency que se puede declarar con @. Estre tipo ocupa 8 bytes y permite guardar nmeros de tipo moneda, es decir nmeros no enteros, pero con un nmero determinado y fijo de decimales, ahora no recuerdo, pero en la ayuda o en los manuales podrs ver la "retaila" de nmeros que cada tipo admite. Para terminar con las recomendaciones de hoy, voy a indicarte algo que debes tener en cuenta cuando declaras variables y que an los ms expertos caen en la trampa. Adems de declarar las variables con Dim, poniendo cada declaracin en una lnea, cosa que por otro lado queda bastante claro y es como suelo hacerlo, aunque ltimamente estoy volviendo a cojer malos hbitos... ser la edad? Tambin se pueden declarar ms de una variable con un mismo DIM, vamos a verlo con un ejemplo: Dim Numero As Integer, NumeroLargo As Long, otroNum As Single, Nombre As String, Numerazo As Double por supuesto tambin valdra de esta otra forma: Dim Numero%, NumeroLargo&, otroNum!, Nombre$, Numerazo# Y si me apuras, tambin de esta otra: Dim Numero%, NumeroLargo As Long, otroNum As Single, Nombre$, Numerazo# Pero sea como fuere, en todos los ejemplos se ha especificado el tipo que queremos asignar. Por supuesto tambin podremos declarar varibales de esta forma: Dim unaVariable, otraVariable, terceraVariable Pero, surge esta pregunta de que tipo son estas tres variables? (al menos se espera que te surja...)La respuesta es bien sencilla, si se ha entendido toda la "retahila" que te he soltado anteriormente: Sern del tipo Variant o del especificado con el DEFINT A-Z (es decir Integer)Voy a suponer que la tercera recomendacin no la ests poniendo en prctica, por tanto seran del tipo Variant. Pero fijate que podras caer en el error, sobre todo si has programado algo en C, de pensar que esta lnea: Dim Numero, otroNumeroInt, elTercero As Integer o esta otra: Dim Numero As Integer, otroNumeroInt, elTercero estn declarando tres nmeros Integer y no es as, lo que se est declarando sera, en el primer caso: Numero y otroNumeroInt como Variant y elTercero como entero. en el segundo caso slo Numero sera del tipo entero y las otras dos variables del tipo Variant. Sera "ideal" que fuese como aparenta, pero el VB no hace estas "virgueras", ni incluso en la versin 5. Por tanto, cuando declares variables, fijate bien de que tipo son las que ests declarando, para no llevarte sorpresas, sobre todo con los redondeos y errores de desbordamiento... Un desbordamiento se produce cuando asignamos a un nmero un valor mayor del que est capacitado para almacenar, as si un entero slo acepta valores de +/- 32767 (realmente acepta hasta -32768), al asignarle un valor de 40000, nos dir que "turur" y dar error. En cuanto a que tipo de variable usar en cada caso, tendrs que tener en cuenta que quieres hacer. Normalmente en los bucles se suelen usar variables enteras, bien Integer, si sabemos que no nos vamos a pasar de 32767, bien Long Integer que puede almacenar un valor de dos mil y pico millones... (quien los tuviera, aunque fuese en calderilla!)Vamos a ver un ejemplo (al fin algo de cdigo se escucha entre el pblico...), con este cdigo podrs comprobar la velocidad de los bucles con los distintos tipos de varibales y as poder comprobar cual es la ms adecuada. Crea un nuevo proyecto y asigna unos cuantos Labels (6 en total) y un botn. Cuando ejecutes este programilla, puedes ir tranquilamente a tomar caf, porque se tomar su tiempo... En teora nos mostrar el tiempo que emplea en hacer unos bucles con tipos diferentes de datos. Para que sea fiable, debers especificar unos valores altos, ya que con nmeros pequeos no es demasiado fiable, e incluso con nmeros altos tampoco... la cosa era poner algo de cdigo para "rematar" el captulo de hoy... En la prxima leccin explicar las intrucciones que se han usado y en algunos casos, explicar hasta el por qu de usarlas. Osea esto es lo que se dice un programa intil que adems de consumir recursos del sistema y hacernos perder el tiempo, no vale para nada... (es que despus de probarlo, me he dado cuenta de que o todos los formatos son prcticamente igual de rpidos o yo he estado "engaado" durante todo este tiempo...)Option Explicit Private Sub Command1_Click() Dim nlnt As lnteger Dim nLng As Long Dim nSng As Single Dim nDob As Double Dim nCur As Currency Dim nVar As Variant Dim timer1#, timer2 As Double Const minBucle = 1, maxBucle = 10 Command1.Caption = "Calculando..." timer1 = Timer For nlnt = minBucle To maxBucle Contar Clnt(nlnt), Label1 Next timer2 = CDbl(Timer - timer1) Label1 = "Duracin con lnteger: " & timer2 DoEvents timer1 = Timer For nLng = minBucle To maxBucle Contar Clnt(nLng), Label2 Next timer2 = CDbl(Timer - timer1) Label2 = "Duracin con Long: " & timer2 DoEvents timer1 = Timer For nSng = minBucle To maxBucle Contar Clnt(nSng), Label3 Next timer2 = CDbl(Timer - timer1) Label3 = "Duracin con Single: " & timer2 DoEvents timer1 = Timer For nDob = minBucle To maxBucle Contar Clnt(nDob), Label4 Next timer2 = CDbl(Timer - timer1) Label4 = "Duracin con Double: " & timer2 DoEvents timer1 = Timer For nCur = minBucle To maxBucle Contar Clnt(nCur), Label5 Next timer2 = CDbl(Timer - timer1) Label5 = "Duracin con Currency: " & timer2 DoEvents timer1 = Timer For nVar = minBucle To maxBucle Contar Clnt(nVar), Label6 Next timer2 = CDbl(Timer - timer1) Label6 = "Duracin con Variant: " & timer2 DoEvents Command1.Caption = "Calcular" End Sub Private Sub Contar(valor As lnteger, etiqueta As Control) Dim i As lnteger Dim unDoble As Double Const elMaximo = 1000& For i = 1 To elMaximo unDoble = unDoble + 1 etiqueta.Caption = valor * elMaximo + unDoble DoEvents Next End Sub LECCIN 4. En la segunda leccin, en el ltimo ejemplo de Num1, Num2, la asignacin: Num1 = Num1 + Num2, debera ser: Num1 = Num1 & Num2 (s que te habrs dado cuenta del detalle, sobre todo por la explicacin posterior), este "desliz" ya est corregido, as que si lo has leido despus del 30 de Junio (del 97), ya est como tena que estar. La siguiente aclaracin, es un despiste, no demasiado grande, ya que doy por hecho de que algo habrs leido sobre VB, bien los manuales, bien la Ayuda o algn libro sobre este lenguaje. Pues la cosa consiste que en la tercera leccin 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 cdigo hice este comentario: Osea esto es lo que se dice un programa intil que adems de consumir recursos del sistema y hacernos perder el tiempo, no vale para nada... (es que despus de probarlo, me he dado cuenta de que o todos los formatos son prcticamente igual de rpidos o yo he estado "engaado" durante todo este tiempo...)Y la cosa es que antes de hacer este ejemplo, yo crea que algunos tipos de datos eran ms rpidos 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 debera ser ms rpido que el resto. Y los enteros ms rpidos 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 cabezn) que soy, y en esta tabla (pulsando en el link), tienes los diferentes valores en distintos equipos y con distintas versiones de VB. Vers 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 cdigo 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 mdulo de cdigo, pulsando en Cdigo en la ventana en la que se muestra los mdulos 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 cdigo de otro sitio, simplemente con pegarlo, se va a su sitio. En el caso de querer aadir al cdigo, una funcin o procedimiento se puede hacer de varias formas, lo acabo de decir, pero lo repito un poco ms claro: 1.Directa: Escribir el cdigo directamente, con lo cual se crear un nuevo "apartado" en la lista de las funciones/ procedimientos. En caso de que no sea un evento soportado por los controles de nuestro formulario, se mostrar en la lista de la izquierda, estando seleccionada en la derecha "General" 2.Copiar/Pegar: Pues eso, si copias una funcin/procedimiento y lo pegas en la ventana de cdigo... 3.Por men de VB: Segn las distintas versiones de VB, ser un men u otro, debers especificar el nombre del procedimiento o la funcin, marcando la casilla correspondiente. En VB4/VB5 vers que aparte de los Procedimientos (Sub) y las Funciones (Function) hay tambin Propiedades (Property), estas las veremos en otra ocasin. Tambin vers que puedes declararlas Pblicas o Privadas. Esto no es posible en VB3, al menos en los procedimientos y funciones de los formularios. En otra ocasin veremos todas estas cosas y con ejemplos, que es lo que "mola". Bueno, toda esta "retahila" vena a cuento de cmo introducir cdigo en los eventos de los controles o del formulario y cmo crear nuetras propias instrucciones (esto es lo que ms me gust del QuickBasic 4.0, poder crear mis propias instrucciones (subs) y funciones). Ya es hora de coger el listado de la leccin anterior y "destriparlo". Vamos a ver cada cosa por separado, que aunque parezca que es mucho cdigo, realmente est "repetido", o casi... Option Explicit Esto nos obliga a declarar todas las variables que usemos en el mdulo, ponerlo es una recomendacin, incluso te la impondra como norma. Para que salga de forma automtica en cada nuevo mdulo, selecciona del men Tools/Advanced la opcin Declare variables required (o algo parecido, que viene a significar Requiere la declaracin de variables) Siguiendo nuestro recorrido por el cdigo, no encontramos con: Private Sub Command1_Click() Lo de Private significa que slo se puede acceder a este procedimiento desde dentro del mdulo en el que est declarado. Es decir no se puede llamar desde otro form o mdulo BAS. Sub indica que es un procedimiento, no una funcin, ni una propiedad. Los Subs actuan como intrucciones propias del lenguaje. Las funciones tambin, pero devuelven un valor, mientras que los subs no devuelven nada, lo que cogen se los quedan ellos, aunque en su momento veremos que tambin 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 mdulo. Los parntesis sin nada dentro, indica que este procedimiento no recibe parmetros; los parmetros lo veremos dentro de un "ratillo" Toda esta lnea es la descripcin del procedimiento y cuando se le llame, bien desde nuestro propio cdigo, bien porque se pulse sobre el botn, se ejecutar todo lo que est dentro de l. El final del procedimiento est marcado por End Sub. Las lneas con DIM indican que estamos declarando las variables y lo que se especifica despus del AS es el tipo de variable, los cinco primeros son de cada uno de los tipos numricos soportados (otro da veremos otro tipo cuasi-numrico), el sexto es Variant, el multi-uso, el que vale para todo. Veamos ahora que es lo que se hace con esta lnea: 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 leccin anterior que algunos tipos de variables se podan indicar mediante unos caracteres especiales, (estos tipos son los heredados de versiones anteriores al Visual Basic 2, en esa versin, se introdujo el tipo Variant), en este caso # es lo mismo que Double, por tanto se podra haber hecho tambin 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 hara la misma tarea: Dim timer1, timer2 As Double Esto funcionara 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 algn sitio, no voy a decir dnde, porque lo mismo fu un "lapsus" del autor, pero deca que de esta forma declaraba tres variables Integer: Dim i, j, k As Integer Sigamos nuestra andadura, ahora veamos esta declaracin/asignacin: 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 permanecern 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 despus 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 explicacin del "por qu" usar constantes. Adems de "esclarecer" los listados, los hace ms fciles de comprender, tambin nos permite modificar un valor en un slo sitio, con lo que ganamos en "confianza", al asegurarnos de que no omitiremos alguno de los sitios dnde 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, tendras que cambiar en seis sitios esos valores, pero al declararlos como constantes, slo cambiando el valor asignado, tenemos todo el trabajo hecho. Esto adems de ser ms fiable y legible, nos puede ahorrar algn que otro quebradero de cabeza y si adems le aadimos que no ocupan espacio extra, salvo en la tabla de smbolos, una vez compilado el programa slo se "compilarn" 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 aburriramos, slo lo har cuando lo crea conveniente o bien si lo solicitas, en este caso, no tendr ms remedio que cumplir tus deseos... Command1.Caption = "Calculando..." Cambiamos el texto mostrado en el botn, para avisarnos de que est haciendo algo... timer1 = Timer Asignamos el valor de la funcin Timer a la primera de las dos variables que usaremos para calcular el tiempo empleado por cada uno de los bucles. Esta funcin devuelve el nmero 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. Deberamos ver primero la declaracin del procedimiento Contar, para entender lo que hace la lnea que viene despus del For. Private Sub Contar(valor As Integer, etiqueta As Control) Declaramos un procedimiento privado llamado Contar (acta como una instruccin ms del VB, ya que no representa a ningn control ni evento), entre los parntesis estn declarados los dos parmetros que espera recibir en la llamada, el primero es un nmero 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 lnea: Contar CInt(nInt), Label1 Contar es el nombre del procedimiento y a continuacin se deben indicar los parmetros que espera recibir. En este caso no sera necesario CINT ya que lo que hace esta funcin es convertir el nmero que se pone dentro de los parntesis en un nmero entero y como resulta que nInt es un nmero entero... pues no hay nada que convertir! El segundo parmetro 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 aduear de Label1. Next Continua repitiendo el bucle hasta que se alcance el valor mximo, 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 despus de la lnea FOR, en caso negativo contina con la lnea siguiente al Next (realmente en la siguiente instruccin despus del Next, ya veremos esto en otra ocasin) timer2 = CDbl(Timer - timer1) Asignamos a la segunda variable que usamos para el clculo del tiempo la diferencia entre el nuevo valor de los segundos transcurridos desde la media noche (Timer) y el valor que tena timer1, es decir cuantos segundos... antes de empezar el bucle. El CDBL es una fucin que devuelve un valor Doble. Es decir hace la resta y ese valor resultante lo convierte en doble. Label1 = "Duracin con Integer: " & timer2 Esta asignacin realmente es Label1.Caption, si se omite la propiedad, Visual Basic usa la que tiene por defecto, que segn los manuales, suele ser la propiedad que se usa con ms frecuencia. En este caso el Caption, es decir lo que se muestra en la etiqueta. DoEvents Esta es una instruccin "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 confusin... relmente no es tan drstico, pero casi... DoEvents, detiene la ejecucin 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 vers lo que ocurre, o debera ocurrir... que ya a estas alturas no me sorprendera nada que se mostrara... El resto del programa es idntico a este bucle, pero usando distintas variables y las dems etiquetas. El caso es que Contar espera una variable de nmero entero y un control, en el caso del control es obvio que se estn poniendo las distintas etiquetas y en el caso del nmero se convierte a entero, porque eso es lo que espera nuestra instruccin y si no lo hacemos as, se quejar. Ya slo queda ver una lnea 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 continuacin se encargar de que se muestre ese contenido. Bueno, tambin se asigna valor * elMaximo, es decir que cuando valor valga 1, se estar mostrando 1000 + unDoble, realmente para hacer un contador se tendra 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 instruccin. Por tanto Contar se llamar tantas veces como dure el bucle en el que se encuentra. Creo que queda todo ms o menos claro y aunque este cdigo 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 an no es el momento de hacerlos. En las declaraciones generales aade esta declaracin: Dim Contando As Integer En Contar, aade lo siguiente despus del DoEvents: If Contando = 0 Then Exit For Al principio del Command1_Click, aade estas lneas: lf Contando Then Command1.Caption = "Calcular" Contando = 0 DoEvents Exit Sub End lf Contando = 1 En cada uno de los bucles, pon esto despus de llamar a Contar... If Contando = 0 Then Exit Sub Y antes del End Sub aade esto otro: Command1.Caption = "Calcular" Contando = 0 Bueno, ah dejo esto y como ejercicio podras aadir dos controles TextBox para especificar los valores de maxBucle y elMaximo, de forma que segn 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 botn. Como pista te dir que las variables usadas y/o declaradas dentro de un procedimiento son slo visibles dentro de ese procedimiento. No te quejars del "pedazo" de pista que te he dado... LECCIN 5. No voy a dar la solucin al problema/ejercicio planteado en la leccin anterior, voy a dejar que la deduzcas. Para que tengas base suficiente, te voy a contar un poco cmo funciona el Visual Basic y por extensin todas las aplicaciones de Windows. En la segunda leccin creamos un programa que mostraba un form en el que teniamos una caja de texto (TextBox), un botn (CommandButton) y dos etiquetas (Label). Cuando, despus de pulsar F5 o CRTL+F5, se ejecuta la aplicacin, de lo nico que podemos tener certeza es que se ejecutar el cdigo que se encuentra en el procedimiento Form_Load. Este procedimiento (sub) en concreto es lo que se llama un evento, y se produce cada vez que el formulario (form) se carga (load) en la memoria. Antes de entrar en detalles del porqu podemos tener la certeza de que ese cdigo se va a ejecutar, tengo que seguir con mi 'ponencia' de cmo funcionan las aplicaciones Windows. Se dice, (otros lo dicen y yo me lo creo), que Windows es un sistema o entorno operativo 'dominado' por los eventos. Esto ya lo dej caer al principio de la segunda leccin. En Windows cada vez que movemos el ratn, pulsamos una tecla, tocamos una ventana o cualquiera de los controles que estn en ellas, se produce un evento. Cuando se 'dispara', (los anglosajones usan 'fire' para indicar que se produce el evento), uno de estos eventos, Windows le dice al form, (de forma bastante rpida, aunque en algunas ocasiones no tanto como nos hubiera gustado), que se ha movido el ratn y que el ratn ha pasado por encima de tal ventana o de ese control y as con todas las cosas. La verdad, no es de extraar que de vez en cuando falle el sitema, es que no para de disparar!!! y algunos disparos se le puede escapar y... ...que chiste ms malo, verdad? Ya pensabas que el comentario ese del 'fire' era porque "el Guille se cree que est traduciendo un artculo de VB Online"... Lo que quiero dejar claro es que a diferencia de los lenguajes que funcionan en MS-DOS, en Windows no podemos 'predecir' cual ser el cdigo que se va a ejecutar. No debes 'planificar' tu programa dando por sentado que... "despus de esto el usuario 'tiene' que hacer esto otro y as yo podr hacer una comprobacin para..." NO ! Aqu (en Windows) no existe la programacin lineal, no des nunca por hecho que esto es lo que va a ocurrir..., porque casi con toda seguridad no ocurrir! Veremos cmo podemos 'controlar' que algunas cosas se hagan cuando nosotros queramos, pero esto ser slo cuando el usuario de nuestra aplicacin realice una 'accin' que estaba prevista; tambin codificaremos para que se ejecute parte del cdigo cuando el usuario no haga lo que habamos previsto que hiciera. Pero eso lo iremos viendo poco a poco... Todo programa de Windows tiene un punto de entrada; en el caso de Visual Basic, puede ser bien un formulario o bien un procedimiento de un mdulo BAS, (de debe llamarse obligatoriamente Main); los mdulos los veremos en otra ocasin. Normalmente las aplicaciones suelen tener ms de un formulario y algn que otro mdulo. Pero tenga uno o ciento, siempre hay un nico punto de entrada (o de inicio). Por regla general suele ser un formulario. En nuestro ejemplo slo tenemos un form en el proyecto, por tanto no hay duda alguna de cual ser el punto de entrada del programa. Perdona si me extiendo en esto, pero tanto si t lo sabes como si no, creo que t ahora lo sabes... (es difcil esto de escribir una cosa para tanta gente con distintos niveles...) Cuando Windows inicia el programa, 'debe' cargar el formulario en la memoria. Y desde el momento que se prepara para hacerlo, ya est con los 'tiritos' y mandando 'mensajes' a la ventana (todo formulario es una ventana), pero no slo le est avisando a la nuestra que la accin ha empezado, sino que lo hace prcticamente a los cuatro vientos; si otra aplicacin quiere enterarse de lo que ocurre en Windows, slo tiene que conectarse a la 'mensajera' de ste entorno operativo y leer las 'noticias'... pero esto ya es complicarse la vida y todava no nos la vamos a complicar tanto... o ms... (pensar alguno despus de respirar aliviado...) Lo que ahora interesa es saber que el 'evento' Form_Load se produce cuando esta ventana pasa del anonimato a la vida pblica, aunque no la veamos, estar en la memoria de Windows y se producir el primer evento del que tenemos 'certeza', por tanto este es un buen sitio para poner cdigo de inicializacin. Realmente el Form_Load no es lo primero que puede ocurrir al iniciarse un formulario, pero por ahora vamos a pensar que s; porque sino esta leccin no la termino hasta despus del verano... que me gusta darle vueltas a las cosas!!! Ahora que se ha cargado el form en la memoria... que ocurrir? Pues, si el usuario se va a tormar unas caas: nada. Slo ocurrir algo cuando interactuemos con el form, es decir, le demos razones a Windows para 'pegar tiritos'. Nuestra aplicacin, (te recuerdo que tena, entre otras cosas, un textbox y un botn), esperar a que se produzca algunas de las acciones para las que est preparada. Y la pregunta es que es lo que puede ocurrir? Para saber 'todas' las cosas que pueden ocurrir en nuestra ventana, (no recuerdo si has pulsado F5 o no), finaliza el programa y muestra la ventana de cdigo. En la parte superior de la ventana hay dos listas desplegables, la de la izquierda tiene todos los controles, (en otra ocasin veremos que no siempre es as), que tenemos en el form, incluido ste, adems de uno especial que se llama General. Pulsa en la lista de la izquierda, para que se despliegue y te mostrar esto: Estos son los cinco controles, incluyendo el form, que pueden recibir mensajes de Windows. Pulsa en cualquiera de ellos. En la lista de la decha estn todos los procedimientos (eventos) soportados por el control de la izquierda. Cada control mostrar los eventos que VB y/o Windows permite que se produzcan. Estos ocurrirn por distintos motivos, cada uno tiene su 'tarea', nos pueden avisar de que se ha pulsado el ratn, que se acaba de pulsar una tecla, que se ha modificado lo que antes haba, etc. Una llamada a la precaucin. Los eventos son 'procedimientos' y no slo se puede llegar a ellos porque se produzca una accin del usuario o del propio Windows y si me apuras, incluso de Visual Basic... Nosotros podemos 'provocarlos' cmo? simplemente haciendo una llamada al SUB que queramos o actuando en el control de manera que ocurra alguno de los eventos soportados. Por ejemplo, en el Form_Load tenemos que se asignan cadenas vacias tanto al Label2 como al Text1: Label2 = "" Text1 = "" Cuando VB asigna una cadena vaca (o cualquier otra cosa), al Label2 est borrando el contenido del 'Caption' de esta etiqueta y asignando algo nuevo, es decir lo est cambiando. En nuestro programa no ocurre nada, salvo que se borra lo que all hubiera, pero realmente se est produciendo el evento Label2_Change, porque hemos cambiado el contenido. VB sabe que no hemos escrito cdigo para manejar esta situacin, asi que... hace la vista gorda y simplemente cambia el contenido del Label2.Caption sin hacer nada ms. Pero al asignar una cadena vaca al Text1, tambin se borra el contenido y se produce un Change, slo que en este caso, al no tener Caption, lo que se borra es el Text; de todas formas sea como fuere, se produce el evento Text1_Change. Nuestro querido amigo Visual Basic, sabe que hemos escrito cdigo para este evento y sabe que tiene que hacer lo que all se dice... En este caso, nuestro cdigo se ejecuta, pero realmente no hace nada de inters o por lo menos nada que se pueda apreciar de forma visual. No voy a explicar para que sirve ese cdigo, porque ya lo hice en su da, lo que espero es que hoy lo entiendas mejor... Cmo? que no sabes de qu cdigo estoy hablando... pues del ejemplo de la segunda leccin, creo que ya lo dije al principio... a ver si prestamos ms atencin y dejamos de pensar en las vaciones... estos nios! El cdigo interesante es el que se ejecuta cuando se pulsa en el botn: Label2 = "Hola " & Text1 Aqu se asigna al Caption del Label2 lo que hay despus del signo igual, en este caso acta 'casi' como una variable. Y ya sabrs que antes de asignar un valor a una variable, se procesa todo lo que est despus del signo igual, por tanto, Visual Basic tomar el contenido del Text1, es decir lo que se haya escrito y lo unir (&) a la palabra "Hola ", una vez hecho esto, lo almacena en el Caption del Label2. Y si en lugar de guardarlo en un control label, lo asignaramos a una variable... y si en lugar de escribir nuestro nombre, escribiesemos un nmero... y si la variable en la que guardamos ese nmero se llamara, por ejemplo, maxBucle o elMaximo... Pues que tendramos una parte resuelta de la tarea esa que puse como ejercicio en la leccin anterior. Pero, este form de la segunda leccin no nos sirve. Tendremos que cargar el de la vez pasada y aadirle un par de cajas de textos y un par de etiquetas, para que indique lo que se debe introducir en cada textbox; el aspecto sera este: Pero nos encontramos con un problema: cmo puedo asignar un valor a maxBucle, si las constantes no pueden cambiar de valor? Fcil, conviertela en variable. Pero debes recordar la pista que di al final: "Las variables declaradas dentro de un procedimiento son solamente visible dentro de ese procedimiento". De este tipo de variables se dice que son locales.Alumno: Que significa esto? Guille: Que slo pueden usarse dentro del procedimiento en el que se han DIMensionado o declarado. A: Vale, "mu bonito" y que pasa? G: Esto... que no pueden usarse en otro sitio... Recuerdas la recomendacin de usar Option Explicit? Pues gracias a Option Explicit, se solucionan el 99% de los fallos 'involuntarios' con las variables... y no exagero!!! Es super-fcil escribir de forma incorrecta el nombre de una 'bariable' y no vengas con el cuento de que a t nunca te ocurre, porque no me lo voy a creer... bueno, de t si, pero no todos son tan minuciosos como t...(para que nadie se sienta ofendido/a, quiero que veas en esto que acabo de poner... la intencin que tiene, es decir que me dirijo a ms de un "ti"... ya s que no eres tan torpe como para no haberlo 'captado', pero con esta aclaracin me quedo ms tranquilo.) Segn cmo y dnde se declare una variable, su 'visibilidad' o rea de cobertura, ser diferente... tambin se puede usar la palabra mbito... es que como en las emisoras de radio se habla de la cobertura... pues... Una variable puede tener estas coberturas: --Privada o Local a nivel de procedimiento (Sub, Function, etc.) --Privada o Local a nivel de mdulo (FRM, BAS, etc.) --Pblica o Global a nivel de aplicacin (en este tipo hay una forma especial de usar las variables que veremos en otra ocasin) Explicando los dos primeros puntos. Cuando declaramos o dimensionamos una variable 'dentro de' un procedimiento, sta slo es visible en ese procedimiento; fuera de l no es conocida y cualquier uso que se intente hacer de ella, producir un error... si has sido obediente y has usado el Option Explicit. En caso de que no hayas puesto la 'obligacin' de declarar todas las variables, te llevars una sorpresa de que no tiene el valor esperado. A: JA! G: No te lo crees? Vale. Vamos a comprobarlo. Abre un proyecto nuevo, pon un textbox y un botn.. Abre la ventana de cdigo, borra el Option Explicit. En el Form_Load haz esta asignacin: Incredulo = "No me lo creo" En el Command1_Click escribe esto otro: Text1 = Incredulo Pulsa F5 y haz click en el botn... Que ha pasado? (Tengo que comprobarlo, para no meter la pata, pero se supone que el texto se borrar sin poner nada...) Bien, eso ocurre porque la variable usada en el Form_Load no tiene nada que ver con la usada en el Command1_Click. Con esto comprobamos o demostramos que podemos tener variables diferentes con el mismo nombre. La nica condicin es que no pueden estar juntas, aunque hay un truco para juntarlas sin que ellas se enteren... En este ltimo ejemplo, nuestra intencin es tener una variable que sea 'conocida' en todo el form. Cuando necesitemos variables con un mbito a nivel de mdulo, tenemos que declararla o dimensionarla en la seccin de las declaraciones generales; ya sabes, en la lista izquierda de la ventana de cdigo seleccionas General y en la de la derecha Declarations ( Declaraciones). Muestra la ventana de cdigo y en General/Declaraciones escribe: Option Explict 'retornamos a las buenas costumbres Dim Incredulo As String Pulsa F5 para ejecutar el programa, pulsa en el botn y... AHORA SI! Tenemos una variable que puede ser 'vista' en todo el form. Ya puedes usar 'Incredulo' donde quieras, ahora siempre ser la misma variable y contendr lo ltimo que se le haya asignado. A partir de la versin 4 del VB, entra en juego una nueva palabra, 'Private', que suele usarse en las declaraciones de las variables a nivel de mdulo, de esta forma es ms fcil entender la intencin de la misma; por tanto la declaracin anterior podemos hacerla tambin as: Private Incredulo As String Hay veces, sobre todo si ya has programado antes en MS-DOS, que usamos variables como a, b, c, i, j, k...etc., (al menos yo estoy acostumbrado a llamar i, j, k a las variables que uso en los bucles FOR), cuando hago un bucle dentro de un procedimiento uso i como variable ndice, (o variable 'contadora'), pero que ocurre si esta 'costumbre' quiero aplicarla en varios procedimientos? Pues que dimensiono una variable i en cada uno de ellos y aqu no ha pasado nada!!! Usar el mismo nombre de variable en distrintos procedimientos Como indica el encabezado de este nuevo prrafo, cosa que ya he comentado antes, podemos tener distintas variables con el mismo nombre en distintos procedimientos; para ello, slo hay que dimensionarlas y el VB las almacenar en distintas posiciones de la memoria para que no se 'mezclen'. En la leccin anterior, teniamos un procedimiento llamado Contar que se usaba para eso, contar... En este ejemplo vamos a usar un sub tambin llamado contar, para ver en accin todo esto que estoy diciendo. Situate en la parte General/Declarations de la ventana de cdigo y escribe o "copia/pega" lo siguiente: Private Sub Contar() Dim i As lnteger For i = 1 To 2 Print "i en contar= "; i Next End Sub Ahora en el Form_Load, escribe esto otro: Dim i As lnteger Show For i = 1 To 3 Print "i en el Form_Load= "; i Contar Next Ejecuta el programa y ... Has visto lo que ocurre... A pesar de que ambas variables tienen el mismo nombre, son diferentes. La variable i del Form_Load no es la misma que la variable i de Contar. Cuando usamos variables locales es como si cambiasemos el nombre y se llamaran NombreProcedimiento_Variable. S que puede ser una forma 'rebuscada' de explicarlo, pero asi te haces una idea. Todas las variables declaradas en un procedimiento, slo son visibles en ese procedimiento. Si has usado QuickBasic o el compilador Basic de Microsoft (que usaba el QuickBasic Extended QBX), esto ya exista y tambin exista la forma de hacer que una variable declarada en un procedimiento, fuese visible fuera de l; para ello declarabas la variable como Shared (compartida); pero en VB eso NO EXISTE. La nica forma de compartir una variable es declarndola en la seccin General de las declaraciones. Prueba ahora esto. Sustituye el procedimiento Contar por este otro: Private Sub Contar(j As lnteger) Dim i As lnteger For i = 1 To j Print "i en contar= "; i Next End Sub Aqu hacemos que Contar reciba un parmetro y el valor que recibe lo usamos como el lmite final del bucle For, es decir contar desde UNO hasta el valor de j. Sustituye la llamada a Contar del Form_Load por esta: Contar i Le damos a Contar el parmetro i. Por tanto cada vez que se llame a este procedimiento le estamos diciendo que i es el valor mximo que tomar el bucle For que tiene dentro. Cmo reaccionar? Se confundir? ... No, no voy a dejarlo para la siguiente leccin, es tan obvio que lo voy a explicar ahora mismo: Al procedimiento Contar le da igual que se use una varibale llamada i o cualquier otra, incluso un nmero. Lo nico que necesita y espera, es recibir un valor numrico (del tipo Integer) y lo asignar a la variable j. Por tanto no ocurrir nada extrao. Ejecuta el programa y fijate en lo que ocurre. S que lo has deducido, eso est bien... vas aprendiendo... 8-) Cmo? Que t an no lo has captado? Pues dimelo...Otra cosa sera pretender usar una variable declarada a nivel de mdulo, dentro del procedimiento, que tuviese el mismo nombre. Si te has quedado con la copla', tu mismo sabrs la respuesta... Efectivamente! Si dentro de un procedimiento tenemos una variable dimensionada con el mismo nombre de una declarada a nivel de mdulo o a nivel global, (para usarla en cualquier sitio de la aplicacin), tendr 'preferencia' la variable local... sta 'tapar', ocultar o como prefieras decirlo a cualquier otra variable del mismo nombre... En la prxima leccin veremos ms casos y cosas de las variables. Comprobaremos cmo usarlas a nivel Global. Pero por ahora vamos a terminar con el programa que tenamos planteado en la leccin anterior: Aunque relamente deberas saber cmo solucionarlo... Lo que seguramente no sabrs, es cmo hacer que estas variables tomen el valor... De acuerdo, lo explicar. Carga el ejemplo de la cuarta leccin. Hay varias soluciones a este problema; una sera usar variables locales, esta decisin no 'justifica' el 'pedazo' de pista que te di... pero esto es lo que hay. La lnea Const minBucle = 1, maxBucle = 10. Debe quedar asi: Const minBucle = 1 Dim maxBucle As lnteger Esto har que maxBucle deje de ser una constante y pase a ser una variable, con lo cual podremos asignarle cualquier valor. Pero, cmo le asignamos el valor? Vamos a dar por sentado que lo que se escriba en el Text1 ser el valor que debe tener maxBucle; entonces lo nico que haremos es asignar a maxBucle lo que se escriba en el Text1... Vale, pero dnde?Pues... por ejemplo, despus de la declaracin, asi que en la siguiente lnea al Dim maxBucle... escribe los siguiente: maxBucle = Text1 Esto en teora no dara problemas, al menos en condiciones normales, ya que el contenido de un textbox es del tipo Variant y ya vimos que un Variant puede almacenar cualquier cosa, por tanto si es un nmero 'intentar' convertir al tipo de la variable que recibir el valor. Esto no siempre funciona, sobre todo si el contenido del Text1 no es numrico. Por ahora vamos a hacerlo simple, si el usuario (en este caso t), escribe algo no numrico lo vamos a considerar CERO... o casi... Cambia la asignacin anterior por esta otra... ALTO !!! Antes de hacerlo, pruebalo e intenta escribir una palabra en lugar de un nmero... que ocurre? Pues que VB no se complica la vida y te dice que 'nones'... (realmente dice Type Mismatch... Error de Tipos, es decir que lo que has escrito no es capaz de convertirlo a Integer)... as que escribe esto otro: maxBucle = Val(Text1) Con esto lo que hacemos es convertir el contenido del Text1 a un VALor numrico y lo asignamos en la variable... Problemas? Que el valor sea mayor del que se puede guardar en un Integer, pero eso ya no es asunto de esta leccin... Ahora nos queda convertir elMaximo en variable y asignarle el valor que hay en el Text2. Efectivamente! hacemos lo mismo, slo que esta vez dentro del procedimiento Contar, por tanto la declaracin Const elMaximo = 1000&, la tienes que quitar y poner estas dos lneas: Dim elMaximo As Integer elMaximo = Val(Text2) Aqu el nico inconveniente es que esta asignacin se hace cada vez que se entra en este procedimiento... y eso, amigo mio, no es un buen estilo de programacin... Sobrecargamos de forma innecesaria al procesador... ten en cuenta que la conversin a nmero y la asignacin se ejecuta cada vez que se entra en Contar!!! Lo mejor para este caso sera declarar elMaximo como variable a nivel de mdulo. Por tanto, borra el Dim elMaximo... del sub Contar y colocalo en la parte de las declaraciones generales del form. Ahora... dnde asignamos el valor para evitar la sobre-carga? Ya que tenemos la variable a nivel de mdulo, sta ser 'vista' en todos los procedimientos del formulario, por tanto lo lgico sera hacerlo en el Command1_Click, ya que cuando nos interesa a nosotros saber cuanto tenemos que contar es precisamente cuando pulsamos en el botn... Pero... dnde exactamente?, despus de Contando = 1 Bien, ahora est la cosa mejor... haz tus pruebas y si an no lo tienes claro... preguntame.Prcticas y ejercicios Quieres algo para practicar? Este ejercicio se lo pona a mis alumnos, cuando daba clases de BASIC, hace ya unos 10 aos o ms... y consista en pedir el nombre, pedir la edad y mostrar el nombre tantas veces como aos tengamos... Claro que con el BASIC del MS-DOS era ms directo y se sabia cuando se debia empezar a mostrar el nombre, para solventar esto, se mostrar el nombre 'edad' veces cuando se pulse en un botn. El aspecto del form sera algo as: No creo que sea complicado, as que vamos a complicarlo un poco ms: Mostrar el nombre 'edad' veces, dentro de un label, para ello el label deber ocupar la parte izquierda del form. Y una tercera versin, sera lo mismo que esta ltima, pero cada vez que se muestre el nombre se haga en una lnea diferente. La pista: En la segunda leccin vimos de pasada el CHR. Pues decirte que si aadimos a una variable un CHR(13), lo que hacemos es aadirle un retorno de carro, es decir lo que venga despus se mostrar en la siguiente lnea... siempre que se 'concatene'. Tambin existe una constante definida en VB4 o superior que es vbCrLf, esto es un retorno de carro (Cr) y un cambio de lnea (Lf) Solucin de los ejercicios de la leccin 5. Solucin al primero, preguntar el nombre, preguntar la edad y mostrar el nombre "edad" veces: Tenemos dos TextBoxes: Text1 y Text2, un botn: Command1, el cdigo sera: Private Sub Command1_Click() Dim i As lnteger Dim j As lnteger Dim Nombre As String j = Val(Text2) Nombre = Text1 For i = 1 To j Print Nombre Next End Sub El segundo es un poco ms complicado, pero no tanto, espero. Slo hay que asignar el nombre al Label, suponiendo que fuese Label3, sera algo como esto: Private Sub Command1_Click() Dim i As lnteger Dim j As lnteger Dim Nombre As String j = Val(Text2) Nombre = Text1 For i = 1 To j Label3 = Label3 & Nombre Next End Sub Por ltimo, para que cada nombre se muestre en una lnea diferente, hay que aadirle a continuacin un retorno de carro y cambio de lnea, en VB4 hay una cosntante definida para ello: vbCrLf, en el VB3 habra que declararla de esta forma: Dim vbCrLf As String vbCrLf = Chr$(13) & Chr$(10) Este sera el cdigo: Private Sub Command1_Click() Dim i As lnteger Dim j As lnteger Dim Nombre As String j = Val(Text2) Nombre = Text1 For i = 1 To j Label3 = Label3 & Nombre & vbCrLf Next End Sub LECCION 6. Como hemos visto en el apndice de la leccin anterior, la instruccin IF... THEN... nos permite tomar decisiones segn el valor de una variable o el resultado de una expresin. En esta leccin veremos como sacarle rendimiento a esta instruccin. Pero antes de entrar en detalles, veamos cmo podemos decirle al Basic que haga las cosas. En realidad vamos a ver la forma en que se le puede decir que las haga... Forma de especificar las instrucciones en Visual Basic Las instrucciones en Basic no tienen porqu estar cada una en una lnea. Se pueden escribir varias instrucciones en la misma lnea, pero separndo cada una de ellas con el signo : (dos puntos). Cuando VB encuentra los dos puntos, deja de 'interpretar' la instruccin y pasa a la accin, una vez traducido a su lenguaje interno, toma lo que hay despus del signo : y sigue su camino en busca de ms instrucciones o el final de la lnea. Veamoslo de forma prctica: Nombre = "Pepe" : Print Nombre Esta lnea tiene dos instrucciones: una asignacin y una instruccin Print. Podemos poner cuantas instrucciones queramos, separadas con los dos puntos. Pero, (siempre hay un pero), si una de las instrucciones es el IF/THEN la cosa puede cambiar... Ya vimos que IF comprueba la expresin que viene a continuacin, si es cierta, ENTONCES procesa lo que haya despus de THEN. En caso de ser en la misma lnea, interpretar todas las instrucciones que estn a continuacin; en caso de ser un bloque IF... THEN... END IF, ejecutar todo lo que est dentro de ese bloque. Ahora bien, si la expresin es falsa pasa a la siguiente lnea, tanto si es o no un bloque. En el caso del bloque la siguiente lnea a interpretar ser la que est despus de END IF. En los tiempos del BASIC interpretado de MS-DOS, era habitual encontrar las lneas con varias instrucciones separadas por dos puntos. En mi caso, cuando empec a usar el QuickBasic 2.0 y al poder usar bloques IF... THEN... END IF, fui dejando a un lado el "mogolln" de instrucciones en la misma lnea... Ahora prcticamente y salvo contadas excepaciones, escribo cada instruccin en una lnea. Despus de este pequeo respiro, veamos cmo estara formada una lnea de VB para usar con un IF... THEN... [instrucciones:] IF THEN A continuacin de THEN podemos incluir cuantas instrucciones queramos, separadas por dos puntos. Estas slo se ejecutarn cuando la expresin sea cierta. Si el resultado de la expresin es falso, se obvia 'todo' lo que hay despus de THEN y se pasa a la siguiente lnea. Espero que lo hayas asimilado y que no te indigestes con lo siguiente... Pero, (...), existe otra instruccin que PUEDE acompaar al IF... THEN... y es para los casos en los cuales el resultado de la expresin sea FALSO. Si, ya s que dije que cuando es falso se pasa a la siguiente lnea, pero eso es cuando no se usa la clusula ELSE. Con sta, la definicin de la instruccin "tomadora de decisiones" quedara as: IF THEN ELSE Tanto en como en pondremos tantas instrucciones como queramos, (separadas por dos puntos). Pero no te recomiendo que lo hagas, es preferible, al menos para darle "claridad" a nuestro cdigo, usar el bloque: lF THEN ELSE END lF S que esto puede ocupar ms lneas de cdigo, pero nuestro "coco" lo agradecer, ya que es ms fcil de comprender, sino veamos un ejemplo: lF numero > limite THEN Print "tu nmero es grande" ELSEPrint "OK, McKey!" END lF Ahora veamoslo en una sla lnea: IF numero > limite THEN Print "tu nmero es grande" ELSE Print "OK, McKey!" En este ejemplo, an queda claro, pero lo podramos complicar con ms instrucciones para ambos casos, es decir, para cuando la expresin es cierta y tambin cuando es falsa. En los tiempos del BASIC que venan incorporados con los ordenadores, cada lnea del programa haba que numerarla, ya que todo lo que se escriba sin nmero de lnea, se ejecutaba inmediatamente; al igual que ocurre con lo que se escribe en la ventana Inmediate del Visual Basic. Los nmeros de lneas se usaban, adems de porque era obligatorio, para cambiar el orden de ejecucin, sobre todo despus de una comparacin. De esta forma, an sin tener bloques IF/THEN/ELSE/END IF, se podan simular. Cmo se lograba? Usando una instruccin que muchos creen que es "indecente, antisocial, etc" La estrella del Basic: (redoble de tambores) "GOTO" A partir de hoy, ms de un purista de la programacin no me dirigir la palabra... pero no me importa... Se ha "denostado" (injuriado) con exageracin el uso de esta instruccin. Realmente es una instruccin de "bifurcacin", es decir, sirve para "IR A" otro sitio de nuestro programa. Su uso ha sido el ms criticado de los NO PARTIDARIOS del Basic y siempre han basado sus crticas en el exagerado uso del GOTO en todos los programas Basic. Pero aclaremos que C tambin tiene esta instruccin y que cualquier programa en cdigo mquina (ensamblador) est "plagado" de JMP que para el caso es lo mismo que el sufrido GOTO, realmente una instruccin GOTO nmero_linea se convierte en JMP nmero_linea. No voy a recomendar el uso del GOTO, para nada, ya que hoy da es innecesario su uso. Antes no tenamos ms remedio, porque el BASIC no dispona de instrucciones para poder estructurar el cdigo. Pero sera una tontera querer hacer creer que no existe esta instruccin. Sabiendo que est y cmo podemos evitarla, es preferible a decir que no existe y si por casualidad la descubres... a que la uses. Por tanto, insisto en mi recomendacin, (de esta forma los PURISTAS volvern a dirigirme la palabra), NO USES EL GOTO, ni an cuando creas que no tienes ms remedio... aunque, aqu entre nosotros, algunas veces es ms cmodo usarlo... pero que no se entere nadie... Este es un programa de los de antes, sirve para mostrar en pantalla los nmeros del 1 al 10 y sin usar el FOR/NEXT 10 A = 1 20 Print A 30 A = A + 1 40 lF A 10 Then Print A;"no es mayor que 10" End lf 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 despus se hace Not 0 que da como resultado -1 (verdadero), por tanto se cumple la condicin. Ya vimos que el valor devuelto por una variable se puede usar en una comparacin, si es cero se toma como falso y si es distinto de cero, como verdadero. Prueba ahora esto: A=0lf Not A Then Print A;"es cero" Else Print A;"es distinto de cero" End lf Tambin 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=5lf Not A Then Print A;"es cero" ElsePrint A;"es distinto de cero" End lf 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, slo decirte que la responsable de todo es la notacin binaria... los ceros y unos que dicen que es el lenguaje nativo de los cacharros estos... talvez ms adelante tratemos un poco de la notacin binaria, pero no por ahora... recuerdo que en mis tiempos del GwBasic la usaba bastante, incluso tena rutinas para "representar" en ceros y unos un nmero... Private Function Dec2Bin(sNumDec As String) As String 'Recibe una cadena que ser un nmero decimal 'Devuelve ese nmero representado por ceros y unos ' Dim i As lnteger 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 lf lngNum And 2 ^ i Then sTmp = sTmp & "1" Else sTmp = sTmp & "0" End lf 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 slo puede ser 0 1, no se complica demasiado la vida. Prueba a escribir el valor 0 y el valor -1 y conviertelo a notacin binaria, fijate lo que el Visual Basic normalmente ve. Prueba con el tema de la notacin binaria, as sabrs realmente cmo funciona todo esto de las comparaciones (por dentro). Lo que nunca falla es completar la expresin, por ejemplo si haces esto: lf Not A0 Then Print A;"es CERO" ElsePrint A;"NO es CERO" End lf Esto siempre funcionar de la forma esperada. Pero sera ms fcil, o al menos ms inteligible, hacerlo as: lf A=0 Then Print A;"es CERO" ElsePrint A;"NO es CERO" End lf Es que algunas veces se puede uno complicar la vida ms de lo necesario... Cuando quieras comprobar un valor devuelto por cualquier expresin, puedes hacerlo asignndolo a una variable o bien mostrando el valor: Print Not A Cuando se usa AND pra evaluar varias partes de una expresin 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 lgico, algunas veces puede llevar a confusin e incluso producir efectos no deseados en el programa. Prueba con esta nueva versin de la funcin Existe. En un form debes poner una etiqueta Label1. Private Function Existe(Archivo As String) As lnteger Existe = Len(Dir$(Archivo)) lf Existe Then Label1 = Archivo & " Si existe" Else Label1 = Archivo & " No existe" End lf 'Esto es ms corto, pero talvez menos evidente: 'Label1 = Archivo & llf(Existe, " Si", " No") & " existe" DoEvents End Function Private Sub Form_Load() Dim A As lnteger, Nombre As String Show Label1 = "" Nombre = "C:\Autoexec.BlN" A=5 lf 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 lf End Sub En el ejemplo comprobars que a pesar de que la segunda parte de la comparacin 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 expresin a pesar de que la primera A>10 es FALSA. Imaginate que en lugar de ser una funcin rpida, hubiese sido otra cosa que tardara un poquito ms de la cuenta... Para casos como estos, (la verdad es que no son demasiado habituales), deberas hacerlo as: Private Sub Form_Load() Dim A As lnteger, Nombre As String Show Label1 = "" Nombre = "C:\Autoexec.BlN" A = 5 lf A > 10 Then lf Existe(Nombre) Then Print A; "mayor de 10 y " & Nombre & " existe" Else Print A; "es mayor de 10 pero " & Nombre & " no existe" End lf Else Print A; "no es mayor de 10 o " & Nombre & " no existe" End lf End Sub Talvez sea ms largo y haya que usar ms cdigo, pero en ocasiones es ms "resultn". Usando este nuevo "estilo", slo se comprobar si existe el archivo cuando A sea mayor que diez. Lo que debes sacar en claro de todo esto es que despus de un THEN puedes "anidar" ms expresiones IF...THEN...ELSE. Incluso se puede usar en una sla lnea, slo que el resultado "visual" del cdigo no es tan "presentable"... lf 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 podramos usar el caracter _ que se puede usar en VB para separar lneas largas, pero es como si estuviese toda en la misma lnea, as que la lnea anterior, se quedara as: lf 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 slo esttico y para VB todo se trata de una misma lnea, por tanto tendr un lmite de caracteres posibles a usar, el lmite que VB le ponga, que creo que es 1024... pero no me hagas demasiado caso... Antes he mencionado la palabra "anidacin", sta se usa para indicar que una serie de instrucciones estn dentro de otras. En este caso hemos anidado dos IF... THEN, pero lo ms 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 podrn continuar los de fuera. En el ejemplo, por cada repeticin 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 impresin de que el programa se ha quedado "colgado", prueba a poner otro bucle dentro del j y cambia los valores mximo 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 tambin en los bucles, podramos necesitar que el Visual Basic nos mostrara alguna indicacin de que est "ocupado", por ejemplo cambiando la forma del cursor del ratn, 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 despus de asignar el valor para el reloj de arena. De esta forma permitimos que Windows procese sus mensajes (recuerdas?) y as tiene ocasin de cambiar el puntero del ratn. LECCIN 8. Ya estamos de nuevo por aqu, esta vez he procurado ser un poco ms rpido para que no pierdas el hilo... (realmente he sido demasido rpido, pero no te acostumbres) El problema de escribir las lecciones, no es porque no sepa que poner... a este nivel an se bastantes cosas... ejem! Lo que ocurre es que normalmente suelo hacerlo en papel... quien lo dira verdad? Y es porque no tengo ordenador en mi "piso" y all es dnde aprovecho, por aquello de la tranquilidad, para concentrarme en las cuatro chorradillas que voy a decir... despus toca pasarlo a "limpio" y como no soy demasiado diestro en esto de escribir a mquina, hice rabona cuando tena clases de mecanografa, pues algunas veces tardo ms de la cuenta. Pero como ahora estoy en unas vacaciones "virtuales", he aprovechado y le he mangado el porttil a mi jefe, con la excusa de que se lo voy a limpiar de "basura" y todo ese rollo. Vale, no me enrollo ms con mis cosillas y vamos a pasar a un tema que, por su extensin, seguramente lo voy a dar en dos lecciones. Empezamos. Ahora hay que ponerse "formal"... Ya has visto todo el tema de las variables y sabes para que sirven, (al menos as debera ser, ya que nadie me ha preguntado sobre el tema), pero hay veces que necesitamos ms. Imaginate que quieres saber cuantas veces por hora te rascas la cabeza intentando comprender lo que hay en mis pginas... Podramos tener unas cuantas variables, una por cada hora del da, con nombres como: Hora1, Hora2, etc. y cuando te arrasques a las 22 horas, haras esto: Hora22 = Hora22 + 1 Con lo que aumentas en uno el contenido de la variable Hora22... y tu dirs... que problema hay? Ninguno, pero es que se me ha ocurrido contarte esto como podra haberte contado otra cosa. Pero imaginate que quieres sumar las veces que te has rascado la cabeza en todo el da, podras hacer: VecesDia = Hora1 + Hora2 + ...+ Hora24 Tampoco hay problema, sumamos todas las variables (24 en este caso) y guardamos el total en la variable VecesDia. Pero la cosa se va complicando, verdad? No lo crees? Pues toma un poco ms de complicacin: Cmo haras para saber la hora en que ms veces te has rascado la cabeza? No te doy la solucin... Es demasiado largo y seguramente hasta complicado como para ponerlo como ejemplo para que salgas de tu incredulidad... Ahora bien, si quieres hacerlo, hazlo, pero despus no me preguntes si est bien o no... sera una prdida de tiempo, ya que, como vas a ver dentro de muy pocas lneas, hay una forma de hacerlo bastante ms simple. Toda esta retahila, es para explicarte la forma con que el Basic, y otros lenguajes, nos facilita la vida en tareas de este tipo... realmente no creo que haya nadie que tenga una utilidad de este tipo, ya que no es til esto de saber cuantas veces nos rascamos la cabeza por no comprender algo... ni an cuando ese algo sea lo que yo escribo... Un poco de historia (la ma) La primera vez que me top con los ARRAYS (de eso va esta leccin), fu con un programa de dados, en mi querido VIC-20. Lo copi de un libro ingls que tena 50 juegos para el Vic-20, saba que funcionaba, pero no saba cmo... Durante un montn de tiempo, a lo mejor fu una o dos semanas, es que antes los das duraban ms que ahora, us mtodos parecidos, sin saber porqu funcionaba... slo saba que funcionaba y simplemente lo aceptaba. Despus cay en mis manos un libro, esta vez en espaol, y me puse a leer la parte que explicaba esto de las "matrices", antes no eran arrays... la verdad es que lo le como 20 veces o ms... y pareca que nunca iba a lograr asimilarlo, es que soy bastante duro de mollera y antes, que era ms joven, calculo que unas 14 veces ms joven que ahora, tena la cabeza ms dur