domingo, 19 de enero de 2014

El entorno Visual Basic I

Por ser uno de los primeros entornos de Microsoft usados para la construcción de archivos ejecutables confeccionados para Windows 95 (el primer sistema operativo de interfaz visual que dejó atrás la interfaz basada en textos de líneas de comandos), Visual Basic merece una consideración especial como el punto de partida de varios conceptos que se irían incorporando en versiones posteriores del mismo Visual Basic así como otros entornos usados para desarrollar programas ejecutables bajo un sistema operativo Windows. Históricamente, el punto de partida previo lo fue el BASIC tradicional, basado en una programación BASIC llevada a cabo ante una pantalla usando líneas de comandos, con cada instrucción separada de la otra mediante una nueva línea de texto precedida por un número entero asignado a cada instrucción (como lo que se vió en detalle en la entrada “El lenguaje BASIC”). Eran los tiempos en los que una computadora era tan cara que nadie podía tener una computadora asignada individualmente para sí todo el tiempo; inclusive en las universidades de mayor prestigio había que conformarse con una sola computadora accesible en tiempo compartido (time sharing) a través de varias terminales repartiéndose entre todas ellas el tiempo de la computadora. Cuando hicieron su aparición las computadoras caseras diseñadas por la empresa IBM bajo convenciones de arquitectura y expandibilidad fijadas por IBM, la primera versión del lenguaje BASIC usada en tales computadoras fue GW-BASIC (conocida por muchos como simplemente como BASICA o BASIC para computadoras personales). No era posible crear programas binarios ejecutables con GW-BASIC, ya que se trataba de un programa interpretador. Se codificaba primero el programa, tras lo cual había que poner en marcha el programa interpretador para que éste pudiera interpretar las instrucciones elaboradas en lenguaje de alto nivel convirtiendo cada instrucción, una por una, a código que era ejecutado de inmediato. Eventualmente hubo una evolución con la aparición de QBasic que a su vez fue un subconjunto de QuickBASIC. QBasic seguía requiriendo la presencia de un programa interpretador para poder convertir una a una las instrucciones de un programa codificado en BASIC, pero implementó una versión refinada del lenguaje que incorporó un concepto nuevo en aquél entonces llamado programación estructurada, prescindiendo de los números de línea que precedían cada línea de instrucción en BASIC e inclusive de los enunciados GOTO y GOSUB que dejaron de ser necesarios con la aparición del BASIC estructurado. La diferencia entre QBasic y QuickBASIC es que éste último no era un programa interpretador sino un programa compilador, capaz de poder producir archivos ejecutables bajo un sistema operativo MS-DOS o PC-DOS que funcionaba con una ventana de líneas de comandos de texto.

Curiosamente, el primer Visual Basic para Windows, Visual Basic 1.0, que hizo su aparición en 1990 no era un entorno diseñado para construír programas ejecutables en un sistema operativo Windows, porque el primer sistema operativo verdadero Windows no haría su aparición sino hasta 1995. Los programas producidos en Visual Basic 1.0 funcionaban bajo lo que era Windows 1.0, una mera interfaz visual, y cuando esto ocurrió había dos tipos de Visual Basic, uno llamado Visual Basic para DOS con la finalidad de ser usado en la ventana clásica de líneas de comandos, y otro llamado Visual Basic para Windows con la finalidad de ser usado en la interfaz visual de Windows. Tras esto hizo su aparición en 1992 Visual Basic 2.0 en dos versiones, la versión Estándard (la cual en realidad era para proporcionar una forma económica de entrenamiento a quienes querían aprender a programar en el nuevo entorno) y la versión Profesional. En 1993 hicieron su aparición las versiones Estándard y Profesional para la interfaz visual Windows 3.0, la cual a su vez era una interfaz mucho muy mejorada sobre las versiones anteriores que adquirió su máximo perfeccionamiento con Windows 3.1. Y finalmente, para 1995, el año en el que Windows dejó de ser una mera interfaz visual invocable desde una línea de comandos para convertirse en un verdadero sistema operativo capaz de tomar el control de la máquina desde el momento en el que es encendida, se introdujo Visual Basic 4.0 en tres versiones, la versión Estándard, la versión Profesional, y la versión Empresa (Enterprise).

Con la aparición de Visual Basic 5.0 en las tres versiones (Estándard, Profesional, Empresa) terminó de llevarse a cabo la transición definitiva de Visual Basic hacia los sistemas operativos Windows, resultando en sistemas operativos tan robustos y estables como Windows 98 capaz de manejar programas ejecutables elaborados para procesadores CPU capaces de manejar programas de 32 bits (en contraste con los programas ejecutables de 16 bits que se podían manejar bajo la interfaz visual Windows 3.x).

La construcción de Visual Basic fue el resultado de un enorme esfuerzo continuado y una inversión enorme en horas-hombre en tiempo de codificación (estamos hablando de cientos y cientos de miles de horas-hombre), y usualmente se podría haber esperado que cada nueva versión de Visual Basic tuviera un precio de mercado casi prohibitivo de varios miles de dólares. Sin embargo, Microsoft le puso un precio de apenas unos cuantos cientos de dólares a cada una de estas versiones de Visual Basic, muy por debajo de lo que se esperaría de una empresa como Microsoft. ¿Por qué? En realidad, esta estrategia tenía siempre en mente al usuario final. La gente no compra computadoras caseras o tabletas electrónicas para jugar con algún sistema operativo, lo hace para poder recurrir a aplicaciones prácticas tales como programas de diseño gráfico o la elaboración de archivos digitales de sonido para la venta y distribución masiva de piezas musicales en el mercado. La única manera en la cual podía haber una buena cantidad de programadores capaces de poder construír programas ejecutables capaces de correr en los sistemas operativos Windows era ofertando casi a precio de ganga los medios requeridos (como Visual Basic) para poder construír programas ejecutables capaces de poder funcionar en los sistemas operativos Windows. Una escasez de este tipo de talentos habría sido el mayor obstáculo en la diseminación de los sistemas operativos Windows, y Microsoft no estaba dispuesta a correr ese riesgo, financiando desde el principio el aprendizaje y el uso de entornos como Visual Basic capaces de poder producir programas ejecutables que puedan funcionar en los sistemas operativos Windows, que es a fin de cuentas en donde la empresa Microsoft obtiene sus mayores ganancias. Puesto de otro modo, al hacer una labor de caridad para con los miles de profesionistas interesados en aprender a programar en Visual Basic en realidad Microsoft estuvo haciendo una labor de caridad para consigo misma, y al haber transcurrido la primera década del nuevo milenio esto no ha cambiado.

Estrictamente hablando, no se puede definir a Visual Basic como un mero lenguaje de programación, en virtud de que no se trata de algo en lo cual con el solo elaborar un listado de instrucciones en un lenguaje de alto nivel se pueda producir un programa capaz de ejecutar alguna aplicación útil. Se trata de un entorno, el cual incluye desde luego un lenguaje para el desarrollo de procedimientos, pero que además se encarga de muchos otros detalles que serían extremadamente laboriosos de especificarle a la máquina, tales como el simple hecho de dibujar en la pantalla una simple ventana de diálogo especificando los colores que se desean para cada pixel (elemento de imagen, cada uno de los puntitos de colores verde, rojo y azul que se iluminan en la pantalla) así como la colocación exacta de los textos así como la interacción de la ventana con el sistema operativo. Pudimos darnos cuenta en las entradas “Construcción de una computadora con chips” y “El lenguaje EDTASM para el μP 6809 II ” de la cantidad de código que se requiere en lenguaje de bajo nivel (ensamblador) para dibujar apenas unas cuantas cosas simples en un monitor de colores de baja resolución, y podemos imaginarnos la cantidad de código que se requerirá para poder producir algo más sofisticado. Un solo hombre puede ser capaz de programarlo todo, pero para ello requeriría cientos de vidas consecutivas, si no es que miles.

El repaso dado arriba a la forma en la cual ha ido evolucionando el lenguaje BASIC sirve para asentar un hecho importante: pese a lo mucho que se hable de la obsolescencia que amenaza a quienes no se mantienen actualizados, al menos en lo que a la programación de computadoras se refiere esto no es del todo cierto, ya que en cada nueva versión mejorada de cierto entorno o de cierto lenguaje se trata de incorporar y retener lo que ya se tiene previamente (por ejemplo, ciertas convenciones en la sintaxis de las instrucciones) por el simple hecho de que nadie está en disposición de aprender algo totalmente nuevo si tiene que volver a comenzar de cero. Es así como quienes ya sabían elaborar programas en QBasic pudieron incorporar mucho de lo que ya sabían a Visual Basic 1.0, y quienes ya habían estado trabajando con Visual Basic 2.0 podían incorporar mucho de lo ya aprendido a la versión Visual Basic 4.0.

Habiendo repasado los orígenes históricos de Visual Basic, procederemos a entrar en mayores detalles de los que fueron cubiertos de modo introductorio en la entrada “La programación visual” para la cual se usó a Visual Basic como paradigma. Lo que se irá viendo a continuación estará basado en lo que aparece en común en varias de las etapas de Visual Basic desde Visual Basic 1.0 hasta Visual Basic 5.0 versión Profesional (sin tratar de ir más lejos), en virtud de que esto proporciona una etapa de transición intermedia con lo que hoy se tiene. Tómese en cuenta que cuando hizo su aparición Visual Basic 2.0, ya estaban en venta las computadoras de escritorio con procesadores CPU capaces de poder manejar programas de 16 bits. La introducción de Windows 98 elaborada para aprovechar la disponibilidad de procesadores CPU capaces de poder manejar programas de 32 bits requirió una ampliación de las capacidades de Visual Basic para poder instalarse y correr en este tipo de máquinas. Ya con Windows 8 el común denominador eran procesadores de 64 bits. Afortunadamente, desde el punto de vista de la sintaxis de los entornos Visual Basic que han ido apareciendo, el programador no se tiene que quebrar la cabeza preocupándose por los detalles finos requeridos al ir actualizando un proyecto elaborado en Visual Basic conforme van aumentando las capacidades del hardware, de lo único que se tiene que preocupar es por estar al tanto del tipo de máquinas que pueden ejecutar los programas de aplicación que está elaborando bajo cierta versión de Visual Basic, e informarle al usuario del tipo de máquina que se requerirá para correr los programas que está elaborando.

Hemos visto ya previamente cómo se genera un proyecto en Visual Basic, y hemos comprobado que la construcción visual de una aplicación es en realidad un asunto que ha sido simplificado al máximo por los desarrolladores del entorno. Veremos en mayor detalle lo que tiene que ver con los procedimientos requeridos para llevar a cabo una secuencia de instrucciones. Aquellos lectores que han experimentado alguna vez con QuickBASIC reconocerán muchas cosas en común con lo que veremos aquí.

Empezaremos definiendo los tipos de datos que se pueden manejar dentro de un procedimiento propio de una aplicación generada por Visual Basic. El código en Visual Basic está organizado en secciones compactas conocidas como procedimientos Sub y procedimientos Function. Un procedimiento, cualquiera, lleva a cabo una tarea específica y tiene su propio nombre en una aplicación. Una llamada es cualquier enunciado o expresión que trae consigo la ejecución de un procedimiento.

Un procedimiento Sub, conocido simplemente como un procedimiento, es un bloque de código encapsulado entre los enunciados Sub y End Sub, pudiéndose utilizar liberalmente la comilla sencilla (apóstrofe) al principio de cada línea, tanto dentro como fuera del procedimiento, para la inserción de comentarios descriptivos que faciliten la labor del programador haciendo sus programas más legibles:

   ' Estructura general de un procedimiento Sub en Visual Basic

   Sub NombreDelProcedimiento(Argumentos)

      ' Bloque de enunciados (instrucciones)

   End Sub

En este punto se tiene que resaltar que, como en cualquier otro lenguaje de programación formal, Visual Basic tiene un conjunto de palabras clave reservadas (reserved keywords). Todas las palabras clave reservadas en Visual Basic empiezan con una letra mayúscula siendo el resto de las letras minúsculas (Sub, End, For, Next, If, Then, Open, Select, Case, Index, Integer, Get, Put, Or, And, Not, etcétera).

En un procedimiento Sub, la lista optativa de Argumentos es una lista ordenada de variables que recibirán valores de argumentos proporcionados al procedimiento al momento de efectuarse una llamada. Las variables en una lista de argumentos tienen que estar separadas mediante comas. El tipo de cada variable depende de la manera en la cual se haya definido la variable. Todas las versiones del entorno Visual Basic definen cinco tipos de datos numéricos: Integer(entero), Long (entero largo), Single (punto flotante de precisión sencilla), Double (punto flotante de doble precisión) y Currency (este último usado para transacciones financieras en las que es importante llevar una contabilidad lo más preciso posible), con las siguientes características:


Tipos de datos numéricos en Visual Basic
 Nombre   Sufijo de
variable
 Extensión  Valor bajo  Valor alto 
 Integer % 2 bytes -32768 32767
 Long & 4 bytes  -2147483648   2147483647 
 Single ! 4 bytes  -3.37E+38   3.37E+38
 Double # 8 bytes  -1.67D+308   1.67D+308
 Currency  @ 8 bytes  -9.22E+14  9.22E+14


Estrictamente hablando, los rangos dados arriba, válidos para versiones de Visual Basic capaces de correr en computadoras equipadas con CPUs que pueden llevar a cabo el procesamiento de palabras binarias de 32 bits, no cubren todo lo que supondríamos que cubre cada rango, ya que existen brechas por la manera en la que se definen y se manejan en formato binario los números especificados en varios de los tipos. En el caso de números tipo Single, los cuales son almacenados como números de 32 bits (4 bytes), los valores posibles para representar un número tipo Single son:

   Para valores negativos:
      -3.402823E38 hasta -1.401298E-45

   0 (cero)

   Para valores positivos:
      1.401298-E45 hasta 3.402823E38

Y en el caso de los números tipo Double, los cuales son almacenados como números de 64 bits (8 bytes), los valores posibles para representar un número de doble precisión tipo Double son:

   Para valores negativos:
      -1.79769313486232E308 hasta -4.94065645841247E-324

   0 (cero)

   Para valores positivos:
      4.94065645841247E-324 hasta 1.79769313486232E308

Las brechas no deben ser motivo de preocupación, porque Visual Basic revierte automáticamente de la notación científica (usando exponentes) a la notación ordinaria (usando únicamente dígitos numéricos) cuando se pueden manejar los números sin necesidad de una parte exponencial (carece de sentido representar un número como 45.98 recurriendo a notación científica con exponente).

Los números de punto flotante de precisión Single son almacenados en la memoria RAM usando el formato conocido como IEEE 32-bit floating point; cada valor de punto flotante single consta de tres partes: el signo, el exponente y la mantisa. El signo consume un bit, el exponente consume 8 bits, y la mantisa consume los 23 bits restantes. Por otro lado, los números de punto flotante de precisión Double son almacenados en la memoria RAM usando el formato conocido como IEEE 64-bit floating point; cada valor de punto flotante doble también consta de tres partes: el signo, el exponente y la mantisa. El signo consume un bit, el exponente consume 11 bits, y la mantisa consume los 52 bits restantes.

Es importante tener en cuenta definiciones y limitaciones como las que se han dado arriba, ya que al proporcionar números en aritmética de punto flotante a un programa elaborado en Visual Basic así es como tenemos que escribir los números cuando estamos recurriendo a notación científica. Si queremos, por ejemplo, proporcionar a Visual Basic el número:

-0.56×10-23

entonces, si es un número de precisión sencilla (Single) tenemos que escribirlo como:

-0.56E-23

¿Y cómo interpretará Visual Basic un número como el siguiente?:

1.28D47

Pues lo interpretará como:

1.28×1047

Pero además lo interpretará como un número de precisión doble (Double) por el simple hecho de haberse usado el símbolo “D” en lugar del símbolo “E” al especificarse el exponencial.

Además de los anteriores tipos de datos, numéricos, Visual Basic define dos formas del tipo String (hilera de caracteres alfanuméricos), de longitud variable y de longitud fija.

Una variable es un nombre que representa el valor de un dato que representa cierto tipo específico. Cuando apareció por vez primera Visual Basic, y tomando una inspiración en el lenguaje C, se definió el tipo de una variable anexando como un sufijo al final del nombre de la variable uno de los caracteres de tipo definidos en la tabla anterior (%, &, !, # y @ para los cinco tipos numéricos, ó $ para el caso de una hilera de caracteres). A modo de ejemplo:

   i% es una variable que representa un entero
   A$ es una variable que representa una hilera
   X! es una variable que representa un número de punto flotante

Sin embargo, en versiones posteriores de Visual Basic, dejó de ser necesario hacer tales simbolizaciones, al ser posible declarar una variable al principio de un procedimiento especificando su tipo.

Declarar una variable consiste en decirle de antemano a un programa lo que tiene que saber acerca de dicha variable, esto es, su tipo. Para declarar una variable usamos la palabra reservada de dimensionamiento Dim de la siguiente manera:

Dim Nombre As Tipo

en donde Nombre es el nombre dado a la variable. Como muestra de ello, se presentan los siguientes ejemplos de declaraciones de variables:

   Dim Contador As Integer

   Dim Temperatura As Single

Otra forma de hacerlo es la siguiente:

   Dim Contador%

   Dim Temperatura!

Esta segunda manera de hacerlo es menos deseable porque (dependiendo de la versión usada de Visual Basic) requiere que el sufijo vaya pegado a la variable en todos los lugares en donde aparezca en el código del programa.

Podemos juntar las declaraciones de tipo en una sola línea como se muestra a continuación:

Dim Distancia As Double, i%, Estudiantes As Integer, Msg$

Las variables que son declaradas mediante el enunciado Dim dentro de un procedimiento existen mientras el procedimiento esté siendo ejecutado. Cuando el procedimiento concluye, el valor de la variable desaparece. Además, el valor de una variable en un procedimiento es local a ese procedimiento, esto es, no se puede accesar una variable dentro de un procedimiento desde otro procedimiento. Esto le permite al programador usar los mismos nombres de variables en distintos procedimientos sin tener que preocuparse por conflictos o cambios accidentales. El nombre de una variable debe empezar con una letra, no debe exceder 255 caracteres, no puede contener un período (punto) incrustado ni un caracter de declaración de tipo, y debe ser única dentro del mismo alcance interno del procedimiento.

Con la introducción de Visual Basic 2.0 hizo su aparición el tipo de dato Variant que puede ser usado indistintamente para almacenar varios tipos de datos (integer, long, double, hileras de texto, etcétera). La ventaja de este tipo de dato es que no es necesario convertir un dato de un tipo a otro mediante código adicional, Visual Basic lleva a cabo la conversión de manera automática. Por ejemplo:

   Dim X As Variant
   X = "28"
   X = X - 15
   X = "U" & X

La primera línea suele ser escrita prescindiendo del especificador de tipo As:

   Dim X

aprovechando el hecho de que, en forma predeterminada (default) Visual Basic proclama a una variable como Variant si no se especifica su tipo. Repasando la secuencia de instrucciones conforme se van ejecutando en forma ordenada de arriba hacia abajo, vemos que en la segunda línea, y en virtud de las dobles comillas, se asigna una hilera de dos caracteres, la hilera "28", a la variable X, que con ello es ya una variable de hilera (String). En la tercera línea, para poder llevar a cabo la operación aritmética indicada, Visual Basic hace automáticamente la conversión de X de una variable de hilera a una variable con un valor numérico igual al entero 28, siendo entonces una variable de tipo número entero (Integer) que tras la operación aritmética tendrá almacenado el número entero 7. Y en la cuarta línea, para poder llevar a cabo la operación de concatenación (encadenamiento) de dos hileras (en virtud del operador de concatenación de hileras &) Visual Basic convierte a X en una variable de hilera, llevando a cabo la concatenación y almacenando el resultado final, que vendría siendo en este caso la hilera "U7", en la variable de hilera X.

La desventaja en el uso del tipo de dato Variant es un consumo extra en el tiempo de procesamiento así como en los recursos de memoria RAM que requiere el programa de aplicación al no poderse asignar y optimizar los recursos de memoria desde un principio, aunque con la cantidad abundante de memoria RAM disponible al inicio del tercer milenio, esto tal vez no será un problema en la gran mayoría de los casos.

Podemos “matar varios pájaros de un tiro” y declarar varias variables en una sola línea con un enunciado como el siguiente:

Dim Contador, Msg, Precision, X, Y

Al no usar la palabra clave As en esta línea, la variable Contador es tomada en forma predeterminada por Visual Basic como de tipo Variant, y posteriormente (de acuerdo a como se use la variable en el resto del procedimiento) podrá ser tomada quizá como un número entero. Del mismo modo, la variable Msg tal vez sea interpretada como una variable de hilera, dependiendo del contexto en el cual se use dicha variable. La variable Precision tal vez sea tomada como un número decimal en punto flotante, también dependiendo del uso que se le dé en el programa.

No solo es posible declarar variables en Visual Basic. También podemos declarar constantes mediante la palabra reservada Const, seguida de la palabra que simbolizará al valor constante, haciéndose tras esto la asignación con el operador de igualdad. Resulta curioso que las palabras lógicas de True (Verdadero) y False (Falso) no estuvieran predefinidas cuando hizo su primera aparición Visual Basic con Visual Basic 1.0, y el mismo programador tenía que definirlas mediante los siguientes enunciados (obsérvese el uso del operador de negación lógica Not que invierte el valor lógico de False):

   Const False = 0

   Const True = Not False

Esta omisión fue corregida en versiones posteriores de Visual Basic en las cuales se incluyó dentro de su repertorio de palabras reservadas las palabras False y True. De cualquier modo, para un programador hispano que quiera “castellanizar” su código, lo siguiente es perfectamente válido:

   Const Falso = 0

   Const True = Not Falso

Podemos, si así lo deseamos, agregar un carácter de declaración de tipo al nombre de la constante para indicar el tipo de dato de la constante, por ejemplo:

   Const MAXDIM% = 250

   Const Ciudad$ = "CiudadJuarez"

Sin embargo, no es indispensable tanto detalle, ya que si se omite como sufijo el carácter de declaración de tipo en el nombre de la constante, Visual Basic le asigna a la constante el tipo de dato apropiado de acuerdo a lo que es asignado en la expresión del enunciado Const.

Además de los procedimientos Sub, también se pueden definir procedimientos Function los cuales, como su nombre sugiere, son capaces de efectuar alguna función, recibiendo uno o varios argumentos, llevando a cabo algunas labores de cómputo sobre dichos argumentos, y regresando algún resultado final. Y esta es la diferencia entre un procedimiento Sub y un procedimiento Function, un procedimiento Function siempre regresa algún valor en contraste con el procedimiento Sub que no se espera que haga tal cosa. Un procedimiento Function tiene la siguiente estructura general en Visual Basic:

   ' Estructura general de un procedimiento Function en Visual Basic

   Function Nombre(Argumentos) As TipoRetorno

      ' Bloque de enunciados (instrucciones)

      Nombre = ValorRetorno

   End Function

en donde Nombre es el nombre que se le dá a la función, TipoRetorno especifica la manera en la cual la función regresará al programa principal el tipo de dato de lo que ha sido evaluado, y ValorRetorno es la respuesta en sí (que puede ser un número entero, un número en aritmética de punto flotante, o una hilera) que produce la función. Una función definida en Visual Basic puede hacer exactamente lo mismo que lo que hace una función matemática en la notación usual que se acostumbra usar en álgebra, como en el caso de la función senoidal:

Seno(45°) = 0.707106781

Dada la enorme utilidad de ciertas funciones matemáticas, no debe causar extrañeza que Visual Basic posea de antemano en su vocabulario de palabras reservadas los nombres de ciertas funciones matemáticas usadas con mucha frecuencia (en el caso de las funciones trigonométricas, los ángulos tienen que ser especificados en radianes):


Funciones matematicas predefinidas
en Visual Basic
 Función  Evaluación efectuada
 Sqr(X)  Obtencion de la raíz cuadrada
 de un número X
 Sin(A)  Obtencion del seno de un
 ángulo A dado en radianes
 Cos(A)  Obtencion del coseno de un
 ángulo A dado en radianes
 Tan(A)  Obtencion de la tangente de un
 ángulo A dado en radianes
 Atn(X)  Obtencion del arcotangente de
 un número X
 Abs(X)  Obtencion del valor absoluto
 de un número X
 Log(X)  Se regresa el logaritmo natural
 de un número X
 Exp(X)  Se regresa e (el número base
 de los logaritmos naturales)
 elevado a la potencia X
 Rnd(X)  Se regresa un número aleatorio
 comprendido entre 0 y X


En la entrada “La programación visual” ya se describió la manera en la cual se puede utilizar una caja de mensaje para proporcionar de manera sencilla algún mensaje al usuario recurriendo a la palabra reservada MsgBox. Del mismo modo, si el usuario va a proporcionar un solo dato durante la ejecución de cierto procedimiento, se puede recurrir a una caja de entrada para cuya creación se utiliza la palabra reservada InputBox() proporcionándole el argumento que será usado como dato de entrada. Esto nos permite elaborar en Visual Basic un programa sencillo que le pida al usuario un ángulo y que le devuelva mediante la función Sin() el seno de dicho ángulo. Para ello, primero abrimos un proyecto de la manera usual con una forma como la siguiente titulada Form1 (las dimensiones que se le den a la forma no son relevantes para lo que llevaremos a cabo):




Haciendo clic con el cursor del Mouse posicionado dentro de la forma, Visual Basic abre la ventana en la cual se puede escribir la secuencia de acciones que llevará a cabo el procedimiento que corresponde al evento Click() cuando el usuario final haga clic dentro de la ventana. Esto nos permite especificar lo siguiente como el procedimiento para la forma:




En la primera línea de código del procedimiento Sub para la forma, declaramos cuatro variables, Grados, Msg, Pi y Radianes. Las cuatro empiezan declaradas como variables del tipo Variant, y como Visual Basic no tiene aún forma de saber cuál es el tipo que corresponde a cada variable es necesario que se ejecuten las líneas posteriores de código para que se vaya definiendo “sobre la marcha” el tipo que corresponde a cada variable. En la segunda línea de código se lleva a cabo una operación aritmética invocando la función predefinida (por Visual Basic) Atn() para evaluar el arcotangente de 1 (lo cual produce la constante matemática universal Pi dividida entre 4) multiplicando el resultado por 4 para obtener así el valor de la constante matemática universal Pi que es asignado a la variable Pi del mismo nombre en el programa. Esto tendrá como propósito el poder permitirle al usuario llevar a cabo la evaluación trigonométrica posterior del seno de un ángulo proporcionando directamente el ángulo en grados y evitarle así el esfuerzo de tener que convertir el ángulo a radianes para usarlo tal y como lo requiere la función Visual Basic Sin(). La tercera línea se encarga de crear una caja de entrada con InputBox que le pedirá al usuario un número que representará un ángulo en grados, el cual es asignado a la variable Grados. La cuarta línea convierte los grados proporcionados por el usuario a radianes mediante una operación matemática, asignándole a la variable Radianes el valor calculado. En la quinta hilera se forma una operación de concatenación que unirá la hilera de texto "El seno de " (obsérvese el espacio en blanco al final dentro de las dobles comillas) al número almacenado bajo la variable Grados. Nótese que, a estas alturas, Visual Basic ya sabe cuál es el tipo de dato que le tiene que asignar a cada variable, y sabe cuánto espacio tiene que reservar en la memoria RAM de la máquina para llevar a cabo las operaciones requeridas. En la sexta línea se lleva a cabo una nueva operación de concatenación, anexándole a la variable de hilera Msg la hilera " es " (obsérvense los espacios en blanco) y actualizando la variable de hilera a una nueva hilera de texto. En la séptima línea se lleva a cabo una operación matemática recogiendo de la memoria RAM el número almacenado bajo la variable Radianes y usando la función predeterminada Sin() para evaluar el seno de dicho número, el cual es concatenado en la misma línea a la hilera de texto que hay en Msg para formar una nueva hilera de texto que dá la respuesta completa al usuario, respuesta que le es proporcionada con la instrucción puesta en la octava línea que se encarga de abrir una caja de mensaje.

En una típica línea del menú de Visual Basic, de entre las opciones:

File  Edit  View  Run  Debug  Options  Window  Help

seleccionamos con el Mouse la opción Run para que se lleve a cabo la ejecución del programa de aplicación que acabamos de construír, dentro de la cual encontraremos como única sub-opción disponible la opción Start (Iniciar) con la cual se pone en marcha el programa. Cuando esto ocurre, aparece una ventana tal y como la vería el usuario final del programa:




El programador observará que aparece también de manera automática otra ventana como la siguiente titulada Debug Window para la forma Form1.frm, la cual es proporcionada en forma predeterminada por Visual Basic para ayudarle al programador a llevar a cabo una localización y depuración de los errores que se vayan encontrando conforme avanza la ejecución del programa:




En esta ventana irán apareciendo, de arriba hacia abajo, mensajes pertinentes a los errores que vayan saliendo así como sugerencias para la remoción de dichos errores que pueden ir desde simples errores ortográficos que hacen que la sintaxis pierda su significado hasta errores de programación más serios que pueden conducir a predicamentos y dilemas tales como los bucles perpetuos de los cuales no hay salida.

Mientras el programa está corriendo bajo Run, haciendo clic con el cursor del Mouse puesto dentro de la ventana que ve el usuario final aparecerá, tal y como se había especificado en las instrucciones del procedimiento para la forma, una caja de entrada que con el texto “Dame un angulo en grados.” le pedirá al usuario que escriba un número en grados dentro del espacio que tiene el cursor parpadeante. Obsérvese que Visual Basic pone de manera automática dos botones, OK y Cancel; se trata de los mismos botones que verá el usuario final cuando use el programa de aplicación:




Si escribimos un número como 45 y hacemos clic en el botón de OK puesto dentro de la caja de entrada, se abrirá otra ventana como la siguiente en la cual con una caja de mensaje se le proporciona al usuario la respuesta que pide:




Una vez que estamos satisfechos con los resultados, oprimimos el botón de OK en la caja de mensaje, con lo cual se activa la línea del menú de Visual Basic, permitiéndonos ir a la opción Run en donde hay ya tres sub-opciones, Break, End y Restart. Mientras que la sub-opción Restart nos permite comenzar de nuevo, la sub-opción End nos permite concluír la ejecución simulada de la aplicación y regresar a la plantilla general del proyecto. Podemos refinar el programa un poco más dándole un título sugestivo a la forma, por ejemplo “Calculadora de seno de angulo”. En la línea del menú de Visual Basic, bajo la opción File (archivo) hay varias opciones entre las cuales se encuentra la sub-opción “Save Project As...” que nos permite guardar el proyecto tal y como se tiene antes de concluír la sesión. El proyecto puede ser guardado por Visual Basic como un archivo anexando una extensión como MAK o como VBP (dependiendo de la versión usada de Visual Basic) al nombre que el programador le dé a su proyecto (como CALCSEN); y ésta es la manera en la cual podemos reconocer los archivos dentro de una carpeta que corresponden a proyectos elaborados bajo Visual Basic. La otra sub-opción llamada “Make EXE File...” es la que utilizamos para convertir el proyecto en un archivo final ejecutable, el archivo que será invocado por un usuario que quiera recurrir a su calculadora para evaluar el seno de un ángulo, y al cual le podemos dar un nombre como CALCSEN.EXE o cualquier otra cosa que se nos venga a la mente. El usuario de la calculadora jamás verá lo que está operando detrás de los escenarios, ello sólo lo sabe el creador del programa de aplicación, e inclusive ni siquiera el programador está al tanto de todo lo que ocurre detrás de los escenarios cuando se desciende hasta el nivel del lenguaje de máquina, habido el hecho de que para reunir todo el código requerido para que un programa como éste pueda funcionar bajo un sistema operativo como Windows se requiere una cantidad enorme de instrucciones en lenguaje de máquina con una cantidad igualmente grande de subrutinas que tienen que ser invocadas de las cuales, no el programador de aplicaciones sino el programador de sistemas estará mejor familiarizado.

En varias de las versiones de Visual Basic, aunque se proporciona una función trigonométrica predefinida para la evaluación del arcotangente (tangente inversa) de un número, no se proporciona nada para la evaluación del arcoseno (seno inverso) de un número ni del arcocoseno (coseno inverso) de un número. ¿Qué hacer en una situación así? El programador puede definir por cuenta propia estas funciones basándose en las que ya se tienen predefinidas:

  Seno inverso: Arcsin(A) = Atan(X / Sqr(-A * A + 1))

  Coseno inverso: Arccos(A) = Atan(X / Sqr(-A * A + 1)) + 1.5708

Si en vez de usar cajas de entrada y cajas de mensaje para obtener datos del usuario y regresarle al usuario los datos ya procesados usamos botones de comandos, podemos construír una calculadora un poco más sofisticada, una calculadora científica, por ejemplo. Todo lo que hay que recordar es que a cada botón le corresponde un procedimiento distinto que es puesto en marcha. Así, cada uno de los botones numéricos desde el 0 al 9 irá almacenando en una variable de hilera creciente un número como 658497 que será sumado a otro número como 132452, usándose la tecla de “+” y la tecla de igualdad “=”, cada una con su propio procedimiento, para efectuar las operaciones. Y de hecho, casi todas las versiones de Visual Basic incluyen el archivo CALC.MAK que proporciona todos los componentes (forma, botones de comando, procedimientos) para poder construír una calculadora como la siguiente:




PROYECTO: Construír, usando un entorno de programación como Visual Basic o cualquier otro entorno que se pueda procurar, una calculadora que sea capaz de poder calcular la raíz cuadrada de un número. (Sugerencia: procúrese un entorno de programación que ya tenga predefinida una función para evaluar la raíz cuadrada de un número).

Además de las funciones matemáticas predefinidas dentro de Visual Basic, hay otras funciones predefinidas para el manejo de hileras de texto, las cuales permiten llevar a cabo (por ejemplo) un proceso de búsqueda de ciertas palabras dentro de un documento de texto (esta es precisamente la manera en la cual trabajan los buscadores de palabras clave dentro de un procesador de palabras o una página Web mediante alguna opción de menú como Find). Estas son, a saber:


Funciones de hilera predefinidas en Visual Basic
 Función  Evaluación efectuada
 Asc(hilera  Se regresa un valor numérico
 igual al equivalente en ASCII
 del primer caracter alfanumérico
 que hay en una hilera
 Chr(Ascii)  Se regresa el caracter que
 corresponde al valor numérico
 Ascii proporcionado a la función 
 Len(hilera)  Se regresa el número de
 caracteres que forman una hilera 
 Left(hilera,N)  Se regresan como una subhilera
 los N caracteres que están más
 a la izquierda de una hilera
 Right(hilera,N)  Se regresan como una subhilera
 los N caracteres que están más
 a la derecha de una hilera
 Mid$(hilera,S,L)   Se regresa una subhilera de
 longitud L que forma parte de
 de una hilera mayor a partir
 de la posición S en la hilera
 InsStr(N,str1,str2  Se regresa la posición de la
 primera ocurrencia de una hilera
 str1 dentro de otra hilera mayor
 str2 a partir de la posición N
 del texto


En el siguiente código, elaborado siguiendo pasos parecidos a los que se tomaron en la elaboración del programa anterior para obtener el seno de un ángulo proporcionado en grados, y usando la función Asc() de Visual Basic, construiremos un programa que nos pueda proporcionar el equivalente en código ASCII (véase el anexo puesto al final de esta obra titulado “El código ASCII”) de los 26 caracteres del alfabeto inglés:

   Sub Form_Click ()

      Dim I As Integer
      Dim Msg As String

      For I = Asc("A") To Asc("Z")
         Msg = Msg & I & " "
      Next I

      MsgBox Msg

   End Sub

Si corremos este programa simulado bajo Visual Basic, obtendremos algo como lo que se muestra a continuación:




De este modo, el equivalente ASCII del caracter “A” es 65, el equivalente ASCII del caracter “D” es 68, y así sucesivamente. Obsérvese algo muy importante en el programa que se acaba de dar. Para poder obtener el resultado mostrado, fue necesario recurrir al siguiente bucle repetitivo:

      For I = Asc("A") To Asc("Z")
         Msg = Msg & I & " "
      Next I

ya que de no haber hecho tal cosa habríamos tenido que escribir 27 porciones semejantes de código (variando únicamente el caracter proporcionado como argumento, primero “A”, después “B”, y así sucesivamente). El uso de bucles puede disminuír considerablemente el tamaño de los programas permitiéndole al programador lograr lo mismo escribiendo mucho menos. El bucle usado es un enunciado del tipo For cuya sintaxis posee la siguiente estructura:

   For contador=inicio Step incremento

      ' Bloque de enunciados (instrucciones)

   Next contador

Cuando el contador va aumentando de uno en uno (en lugar de incrementos de dos en dos, por ejemplo), podemos prescindir del condicionante Step al tomarlo Visual Basic de manera predeterminada como 1; esto fue precisamente lo que se hizo en el programa que acabamos de ver.

Podemos anidar un bucle repetitivo dentro de otro bucle cuantas veces sea necesario para lograr algún propósito:

   For I = 0 To 20
      For J = 0 To 10
         For K = 0 To 35
              .......
         Next K
      Next J
   Next I

Si hacemos la siguiente modificación ligera al anterior programa incorporando la función Asc() para convertir a un caracter alfabético cada numeral ASCII que se va generando:

   Sub Form_Click ()

      Dim I As Integer
      Dim Msg As String

      For I = Asc("A") To Asc("Z")
         Msg = Msg & Chr(I) & " "
      Next I

      MsgBox Msg

   End Sub

al probar el programa obtendremos la siguiente caja de mensaje:




Habrá ocasiones en las cuales no solo no será posible invocar alguna función predefinida previamente dentro de Visual Basic o una combinación de funciones predefinidas, sino que inclusive será necesario entrar a fondo en el diseño de algún procedimiento para poder llevar a cabo la evaluación que se desea. Un ejemplo de ello es la extracción de la raíz cúbica de un número. Visual Basic proporciona la función predefinida Sqr() para la extracción de raíces cuadradas, pero no proporciona función alguna para la extracción de raíces cúbicas. En un caso así, será necesario implementar algún algoritmo para poder llevar a cabo la evaluación. Suponiendo que poseamos conocimientos en los fundamentos del Análisis Numérico, o que tengamos amistad con un matemático que esté en buena disposición de compartir algunos de sus secretos con nosotros, la elaboración del procedimiento requerirá no solo evaluaciones aritméticas sino tal vez la repetición continuada de una serie bien definida de pasos, o sea la implementación de un bucle, usando además algún enunciado de control para estar efectuando comparaciones conforme nos acercamos al resultado deseado. En la entrada titulada “Algoritmos computacionales” ya vimos algunas maneras en las cuales se puede obtener la raíz cúbica de un número, pero todas ellas requieren la repetición de un bucle mientras se va afinando el resultado y nos vamos aproximando a la respuesta correcta. Procediendo de la misma manera en la cual se construyó en Visual Basic una calculadora del seno de un ángulo expresado en grados, podemos hacer lo mismo excepto que el código del procedimiento de la forma será el siguiente:




El algoritmo en realidad no tiene nada de sofisticado, ya que está basado en comenzar promediando el valor del número proporcionado por el usuario, que es asignado en el procedimiento a X2, con el valor de cero asignado inicialmente a X1 por el programador, asignando el promedio aritmético así obtenido a la variable X. Se multiplica la variable X, que es la raíz cúbica tentativa, por sí misma dos veces, dando con ello el cubo del número X que es comparado con el Valor proporcionado por el usuario. Se continúa con varias aproximaciones recurriendo a un bucle, hasta que se obtiene la raíz cúbica del número proporcionado por el usuario, dentro de la precisión numérica especificada por la variable Precision. Si se echa a andar bajo Visual Basic este proyecto bajo una ejecución simulada, al hacer clic con el Mouse dentro de la ventana que se abre se obtiene la siguiente caja de entrada (el número 2744 es puesto por el usuario):




Al oprimir el botón OK, aparece la respuesta en una caja de mensaje como la siguiente:




Revisando las líneas del código del procedimiento de la forma dado arriba, podemos ver una línea que en realidad consta de dos instrucciones separadas por el típico colon (:) que se acostumbra usar en BASIC para meter varias instrucciones consecutivas dentro de la misma línea:

X1 = 0: X2 = Valor

En la primera instrucción se le asigna el valor cero a la variable X1, mientras que en la segunda instrucción se le asigna a X2 el número proporcionado por el usuario que es puesto inicialmente en la variable Valor a través de la caja de entrada.

Pero lo más interesante en el programa dado arriba para el cálculo de raíces cúbicas son en primer lugar un bucle basado en el bucle básico:

   Do Until condición

      ' Bloque de enunciados (instrucciones)

   Loop

y en segundo lugar el enunciado de control If... Then... Else de la forma:

   If condición Then

      ' Bloque de enunciados 1(instrucciones)

   Else

      ' Bloque de enunciados 2(instrucciones)

   End If

usado para una ejecución condicional basada en la evaluación de una expresión. En la estructura de decisión If... Then... Else, si la condición es verdadera (True) entonces se ejecuta el primer bloque de enunciados que sigue a Then, y si no lo es, se ejecuta el segundo bloque de enunciados que sigue a Else. En lugar de que haya dos opciones de código para ser ejecutado, podemos usar esta estructura de decisión en su forma más sencilla para que se ejecute una sola porción de código (sin dar otra alternativa) en caso de que se cumpla la condición:

   If condición Then:

      ' Bloque de enunciados (instrucciones)

   End If

A diferencia de esta estructura de decisión, hay otras estructuras de decisión en las cuales cierta porción de código se vuelve a repetir una y otra vez hasta que se cumpla (o se deje de cumplir) cierta condición; se trata de los bucles.

A continuación se tiene un programa que recurre a un bucle Do... Loop básico que mantiene a la computadora en un bucle perpetuo hasta que el usuario no proporcione al programa (a través de la caja de entrada) un número entero que esté dentro del rango deseado (0 y 9):

   Sub Form_Load ()

      Dim Responder

      Do
         Responder = InputBox("Dame un numero entre 0 y 9.")
         If Responder > 1 And Responder < 9 Then
            Exit Do
         End If
      Loop

   End Sub

Si se ejecuta el programa anterior, de la ventana principal se obtiene la siguiente caja de entrada:




Obsérvese que en la línea del anterior programa se utiliza la palabra clave Exit en la siguiente modalidad:

Exit Do

Esta instrucción, cuando se llega a ejecutar, ocasiona una salida incondicional de un bucle.

El bucle Do... Loop básico tiene algunas variantes. En el programa que se dió arriba para el cálculo de la raíz cúbica de un número, la variante es:

   Do Until condición

      ' Bloque de enunciados (instrucciones)

   Loop

Un bucle de este tipo se estará ejecutando una y otra vez hasta que la condición haya adquirido un valor lógico verdadero (True), o sea hasta que la condición se cumpla. Por otro lado, un bucle Do que posea la siguiente estructura:

   Do While condición

      ' Bloque de enunciados (instrucciones)

   Loop

se estará ejecutando una y otra vez mientras la condición se siga cumpliendo. En el momento en el que no se cumpla la condición, el bucle se rompe.

Otra variante de bucles es la siguiente:

   Do

      ' Bloque de enunciados (instrucciones)

   Until condición

Un bucle de este tipo se estará ejecutando una y otra vez hasta que la condición haya adquirido un valor lógico verdadero (True), o sea hasta que la condición se cumpla, y cuando ello ocurre se sale del bucle.

En realidad, los bucles dados arriba no difieren en nada de los bucles que ya se han visto anteriormente. Los conceptos generales son los mismos e independientes del lenguaje o el entorno que se use, lo único que cambia son los comandos y la sintaxis usada para especificar la ejecución.

Como un pegoste de tiempos pasados, varias versiones de Visual Basic han ido incorporando el enunciado clásico para ordenar un salto incondicional hacia otra parte del programa, el comando GoTo. A continuación tenemos un ejemplo del uso de dicho comando que requiere la especificación de alguna etiqueta hacia la cual se pueda efectuar el salto incondicional:

   Sub Form_Click ()

      Dim Num

      Num = InputBox("Escribe un numero")
 
      GoSub Rutina

      GoTo SiguienteParte

      Rutina:

         Num = Num / 2

         Return

      SiguienteParte:

         MsgBox "La mitad del numero es " & Num

   End Sub

La ejecución del programa es sencilla. Aparece una caja de entrada pidiendo un número, y al hacer clic en el botón de OK se proporciona la mitad del número. En la ejecución del programa, después de que el número pedido en la caja de entrada es asignado a la variable Num, el comando Go Sub provoca un salto a la subrutina marcada con la etiqueta Rutina, en la que se divide el número entre 2, regresándose con la palabra Return la ejecución del programa a la siguiente instrucción que sigue al llamado GoSub que es una instrucción de salto incondicional GoTo a la etiqueta SiguienteParte. Esta parte del código es la que se encarga de abrir la caja de mensaje que imprime el resultado. Obsérvese que el código señalado por GoTo no tiene instrucción de retorno. Y estos son los riesgos que se corren con los programas que incorporan la instrucción de salto incondicional GoTo que puede resultar fatal en un programa con varios saltos incondicionales que pueden llevar a quién sabe donde (por ejemplo, un bucle perpetuo no anticipado). El uso de este tipo de comando, proscrito en la programación estructurada, debe ser evitado a toda costa, y la experiencia ha demostrado que siempre puede ser reemplazado con código equivalente que use enunciados estructurados de control (Do...Loop, For...Next, If...Then...Else, Select Case).

La estructura de decisión If... Then... Else puede ser ampliada del siguiente modo para ofrecer no dos sino tres o más alternativas de ejecución de código:

   If condición Then

      ' Bloque de enunciados 1(instrucciones)

   ElseIf condición 2

      ' Bloque de enunciados 2(instrucciones)

   ElseIf condición 3

      ' Bloque de enunciados 3 (instrucciones)

   Else

      'Bloque de enunciados 4 (instrucciones)

   End If

Esta estructura selecciona únicamente uno de los cuatro bloques de código. Si se encuentra una condición verdadera, el bloque correspondiente de código es ejecutado y el resto de las instrucciones son ignoradas.

Hay otra estructura de decisión que permite seleccionar una de varias alternativas de código ejecutable dependiendo del cumplimiento de cierta condición. Se trata de la estructura Select Case:

   Select Case valor de prueba

      Case valor 1

         ' Bloque 1

      Case valor 2

         ' Bloque 2

      Case valor 3

         ' Bloque 3

      Case Else

         ' Bloque 4

      End Select

Esta estructura de decisión busca un apareamiento entre el valor de prueba y los valores especificados para cada caso. Si se encuentra algo igual, se ejecuta el código correspondiente. Si no se encuentra algo igual, el bloque Case Else se ejecuta.

En lo que hemos visto arriba, se han manejado números decimales. Sin embargo, ocasionalmente (cuando se está elaborando un programa) resulta conveniente usar números hexadecimales (base 16) o números octales (base 8). Visual Basic representa los números hexadecimales prefijándoles &H, y representa los números octales prefijándoles &O, como se detalla en los siguientes ejemplos:


 Decimal  Octal  Hexadecimal 
9  &O11 &H9
15  &O17 &HF
16  &O20 &H10
20  &O24 &H14
255  &O377  &HFF


En el código de un procedimiento, Visual Basic utiliza el “salto de línea” (o retorno de carro) al final de una línea para identificar y procesar una instrucción completa. A diferencia de otros lenguajes (como el lenguaje C), no podemos continuar una instrucción muy larga poniendo parte de la instrucción en una línea y el resto de la instrucción en otra línea. Toda la instrucción tiene que ser puesta en la misma línea. Conforme se van desarrollando programas más elaborados y complejos, esta restricción puede ser un obstáculo para la elaboración de programas legibles. Pensando en esto, Visual Basic permite empezar una instrucción en una línea y continuarla en la siguiente línea siempre y cuando al final de cada línea se anexe un caracter de continuación de línea que consiste de un signo de subrayado (guión bajo) precedido de un espacio en blanco. Un ejemplo de cómo romper una instrucción en cuatro líneas es el siguiente:

   Data1.RecordSource =  _
   "SELECT * FROM Titles.Publishers" _
   & "WHERE Publishers.PubId = Titles.PubId" _
   & "AND Publishers.State = 'CA'"

Si no se usa el caracter de continuacion de linea al continuar una instrucción extensa en otra(s) línea(s), Visual Basic marcará un error al tratar de ejecutarse el código, y se negará a convertir el programa en una aplicación ejecutable.