INICIO EN VISUAL BASIC
A WEB 100% MEXICANA
________________________________________________
________________________________________________
UTILIZACIÓN DE IMPRESORAS
Permite obtener por la impresora gráficos y texto similares a los que se pueden obtener por la pantalla, aunque con algunas diferencias de cierta importancia. Existen dos formas de imprimir: la primera mediante el métodoPrintForm, y la segunda utilizando el objeto Printer, que es un objeto similar al objeto PictureBox. Ambos métodos tienen puntos fuertes y débiles que se comentarán a continuación.
Método PrintForm
El método PrintForm permite imprimir un formulario con sus controles y con los resultados de los métodos gráficosPSet(, Line y Circle) y del método Print. Para ello la propiedad AutoRedraw del formulario tiene que estar puesta a True, y los métodos citados tienen que estar llamados desde un evento distinto del Paint. Lo único que no se dibuja del formulario es la barra de título. Este sistema de impresión es muy sencillo de utilizar, pero tiene el inconveniente de que el resultado se imprime con la misma resolución de la pantalla (entre 50 y 100 puntos por pulgada), no aprovechando por tanto la mayor resolución que suelen tener las impresoras (300, 600 ó más puntos por pulgada).
Objeto Printer
Este segundo sistema tiene la ventaja de que permite aprovechar plenamente la resolución de la impresora, pero no permite dibujar controles sino sólo los métodos gráficos habituales PSet,( Line y Circle), el métodoPrint y un método no visto hasta ahora que esPaintPicture.
Para Visual Basic la impresora es un objeto gráfico más, similar a los formularios y a las cajas gráficasPictureBox. Como tal objeto gráfico tiene sus propiedades generales DrawStyle(, BackColor, ForeColor, etc.), además de otras propiedades específicas de la impresora, como DeviceName, DriverName, Orientation, Copies, etc. Para más información puede utilizarse el Help, buscando Printer object. En principio se utiliza la impresora por defecto del PC, pero Visual Basic mantiene una Printers Collection, que es algo así como un array de impresoras disponibles. A partir de esta Printers Collection se puede cambiar a la impresora que se desee. El objeto Printer tiene un método llamado EndDoc para enviar realmente a la impresora el resultado de los métodos gráficos. El métodoPaintPicture permite incorporar el contenido de ficheros gráficosa un formulario, PictureBox o Printer. Su forma general es:
object.PaintPicture pictProp X, Y, Width, Height
donde pictProp indica el gráfico (coincide con la propiedadPicture de PictureBox), X e Y indican las coordenadas de inserción y los dos últimos parámetros las dimensiones (opcionales).
CONTROLES FILELIST, DIRLIST Y DRIVELIST
Uno de los problemas que hay que resolver para leer o escribir en ficheros de disco es ser capaces de localizar interactivamente los correspondientes ficheros, de modo análogo a como se realiza con los comandos File/Open o File/Save As de Word, Excel o de cualquier otra aplicación. Este tipo de operaciones se pueden hacer mucho más fácilmente con los Common Dialog Controls ya vistos anteriormente ,aconsejando por lo tanto su uso. A pesar de ello, aquí se van a explicar los controles específicos de que dispone Visual Basic.
Visual Basic dispone de tres controles que facilitan el recorrer el árbol de ficheros y de directorios, localizando o creando interactivamente un fichero determinado. Estos controles son el FileListBox (para ficheros), el DirListBox (para directorios) y el DriveListBox (para unidades de disco). Estos tres controles, junto con unas etiquetas que los identifican. Los dos primeros son listas, mientras que el tercero es una caja de tipo ComboBox.
En principio estos controles, cuando se colocan en un formulario tal como se muestra en la imagen, estándesconectados. Quiere esto decir que al cambiar la unidad de disco (drive) no se muestran en la caja dirListBox los directorios correspondientes a la nueva unidad de disco. Por otra parte, al cambiar de directorio tendrán que cambiar de modo acorde los ficheros en la caja fileListBox. La dificultad de conectar estas cajas no es grande, pero sí hay que saber cómo se hace pues depende de propiedades de estas cajas que no aparecen en la ventana de propiedades (ventana Properties) en modo de diseño, y que sólo están accesibles en modo de ejecución. De entre estas propiedades las más importantes son las siguientes:
La DriveListBox tiene una propiedad llamada Drive que recoge la unidad seleccionada por el usuario (puede ser una unidad física como el disco c:\ o una unidad lógica asignada por el usuario a otro disco o directorio en un servidor o en otro ordenador de la red).
La propiedad path de la caja DirListBox determina el drive seleccionado y por tanto qué directorios se muestran en dicha caja. Finalmente, una propiedad también llamada path de la caja FileListBox determina el directorio que contiene los ficheros mostrados. Para enlazar correctamente las cajas de discos, directorios y ficheros se puede utilizar el evento Change, de tal forma que cada vez que el usuario cambia la unidad de disco se cambia el path del directorio y cada vez que se cambia el directorio se cambia el path de los ficheros. Esto puede hacerse con el código siguiente:
Private Sub dirPrueba_Change() filPrueba.Path = dirPrueba.Path
End Sub
Private Sub drvPrueba_Change() dirPrueba.Path = drvPrueba.Drive
End Sub
La caja FileListBox tiene una propiedad llamada FileName que contiene el nombre del fichero seleccionado por el usuario. Para tener el path completo del fichero basta anteponerle la propiedad Path de la fileListBox, que incluye el directorio y el drive, y la barra invertida (\). Si el usuario introduce FileName incluyendo el path, Visual Basic actualiza también de modo automático la propiedadPath de FileListBox. El usuario se debe preocupar de utilizar el evento Change para actualizar el Path de la caja DirListBox y la propiedad Drive de DriveListBox. Otra propiedad importante es la propiedad Pattern, que indica los tipos de ficheros que se mostrarán en la caja. El valor por defecto es“*.*” , lo cual hace que se muestren todos los ficheros. Si su valor fuese “*.doc” sólo se mostrarían los ficheros con esta extensión. La propiedad Pattern admite varias opciones separadas por untos y coma (“*.doc; *.dot” ).
TIPOS DE FICHEROS
Tanto en Windows como en Visual Basic existen, principalmente, dos tipos de archivos:
1. Ficheros ASCII o ficheros de texto. Contienen caracteres codificados según el código ASCII y se pueden leer con cualquier editor de texto como Notepad. Suelen tener extensión *.txt o *.bat, pero también otras como*.m para los programas de Matlab, *.c para los ficheros fuente de C, *.cpp para los ficheros fuente de C++ y *.java para los de Java.
2. Ficheros binarios: Son ficheros imagen de los datos o programas tal como están en la memoria del ordenador. No son legibles directamente por el usuario. Tienen la ventaja de que ocupan menos espacio en disco y que no se pierde tiempo y precisión cambiándolos a formato ASCII al escribirlos y al leerlos en el disco.
Con Visual Basic se pueden leer tanto ficheros ASCII como ficheros binarios. Además el acceso a un fichero puede ser de tres formas principales.
1. Acceso secuencial. Se leen y escriben los datos como si se tratara de un libro: siempre a continuación del anterior y sin posibilidad de volver atrás o saltar datos. Si se quiere acceder a un dato que está hacia la mitad de un fichero, habrá que pasar primero por todos los datos anteriores. Los ficheros de texto tienen acceso secuencial.
2. Acceso aleatorio (random): Permiten acceder directamente a un dato sin tener que pasar por todos los demás, y pueden acceder a la información en cualquier orden. Tienen la limitación de que los datos están almacenados en unas unidades o bloques que se llamanregistros, y que todos los registros que se almacenan en un fichero deben ser del mismo tamaño. Los ficheros de acceso aleatorio son ficheros binarios.
3. Acceso binario. Son como los de acceso aleatorio, pero el acceso no se hace por registros sino por bytes.
Antes de poder leer o escribir en un fichero hay que abrirlo por medio de la sentencia Open. En esta sentencia hay que especificar qué tipo de acceso se desea tener, distinguiendo también si es para lectura (input), escritura (output) o escritura añadida (append).
LECTURA Y ESCRITURA EN FICHEROS SECUENCIALES
Apertura y cierre de ficheros
Para poder leer o escribir en un fichero antes debe ser abierto con la sentencia Open, es la siguiente:
Open filename For modo As # fileNo
donde:
filename es el nombre del fichero a abrir. Será una variable string o un nombre entre dobles comillas (“ ”).
modo Para acceso secuencial existen tres posibilidades: Input para leer, Output para escribir al comienzo de un fichero y Append para escribir al final de un fichero ya existente. Si se intenta abrir en modo Input un fichero que no existe, se produce un error. Si se abre para escritura en modo Output un fichero que no existe se crea, y si ya existía se borra su contenido y se comienza a escribir desde el principio. El modo Append es similar al modo Output, pero respeta siempre el contenido previo del fichero escribiendo a continuación de lo último que haya sido escrito anteriormente.
fileNo es un número entero (o una variable con un valor entero) que se asigna a cada fichero que se abre. En todas las operaciones sucesivas de lectura y/o escritura se hará referencia a este fichero por medio de este número. No puede haber dos ficheros abiertos con el mismo número. Visual Basic dispone de una función llamada FreeFile que devuelve un número no ocupado por ningún fichero. A continuación puede verse un ejemplo de fichero abierto para lectura:
Open "C:\usuarios\PRUEBA1.txt" For Input as #1
Después de terminar de leer o escribir en un fichero hay que cerrarlo. Para ello, se utilizara el comando Close, que tiene la siguiente forma:
Close # fileNo
donde el fileNo es el número que se la había asignado al abrirlo con la instrucción Open.
Lectura y escritura de datos
Sentencia Input
Existen varias formas de leer en un fichero de acceso secuencial. Por ejemplo, para leer el valor de una o más variables se utiliza la sentenciaInput:
Input # fileNo, varName1, varName2, varName3, ...
donde el fileNo es el número asignado al archivo al abrirlo y varName1, varName2, ... son los nombres de las variables donde se guardarán los valores leídos en el fichero. Debe haber una correspondencia entre el orden y los tipos de las variables en la lista, con los datos almacenados en el fichero. No se pueden leer directamente vectores, matrices o estructuras. Si los datos del disco han de ser escritos por el propio programa, conviene utilizar la sentencia write (mejor que Print) para garantizar que los valores están convenientemente separados. La sentencia Write se verá posteriormente.
Función Line Input y función Input
La función Line Input # lee una línea completa del archivo y devuelve su contenido como valor de retorno. Su forma general es:
varString = Line Input #fileNo
Conviene recordar que en los ficheros de texto se suele utilizar el carácterreturn (o Intro) para delimitar las distintas líneas. Este es el carácter ASCII nº 13, que por no ser un carácter imprimible se representa en Visual Basic como chr(13). En muchas ocasiones (como herencia del MS-DOS) se utiliza como delimitador de líneas una combinación de los caracteres return y linefeed, representada en Visual Basic como chr(13)+chr(10). En la cadena de caracteres que devuelve Line no se incluye el carácter de terminación de la línea.
Para leer todas las líneas de un fichero se utiliza un bucle for o while. Visual Basic dispone de la función EOF (End of File) que devuelve True cuando se ha llegado al final del fichero. Véase el siguiente ejemplo:
Do While Not EOF(fileNo)
miLinea = Line Input #fileNo
...
Loop
También se puede utilizar la función Input, que tiene la siguiente forma general:
varString = Input(nchars, #fileNo)
donde nchars es el número de caracteres que se quieren leer y varString es la variable donde se almacenan los caracteres leídos por la función. Esta función lee y devuelve todos los caracteres que encuentra, incluidos los intro y linefeed. Para ayudar a utilizar esta función existe la función LOF (fileNo), que devuelve el nº total de caracteres del fichero. Por ejemplo, para leer todo el contenido de un fichero y escribirlo en una caja de texto se puede utilizar:
txtCaja.text = Input(LOF(fileNo), #fileNo)
Función Print #
Para escribir el valor de unas ciertas variables en un fichero previamente abierto en modo Output o Append se utiliza la instrucción Print #, que tiene la siguiente forma:
Print #fileNo, var1, var2, var2, ...
donde var1, var2,... pueden ser variables, expresiones que dan un resultado numérico o alfanumérico, o cadenas de caracteres entre dobles comillas, tales como“El valor de x es...” . Considérese el siguiente ejemplo:
Print #1, "El valor de la variable I es: ", I
donde I es una variable con un cierto valor que se escribe a continuación de la cadena. Las reglas para determinar el formato de la función Print # son las mismas que las del método Print visto previamente.
Función Write #
A diferencia de Print #, la función Write # introduce comas entre las variables y/o cadenas de caracteres de la lista, además encierra entre dobles comillas las cadenas de caracteres antes de escribirlas en el fichero. La función Write # introduce un carácternewline, esto es, un return o un return+linefeed después del último carácter de las lista de variables. Los ficheros escritos con Write # son siempre legibles con Input #, cosa que no se puede decir de Print #. Véase el siguiente ejemplo:
’ Se abre el fichero para escritura
Open "C:\Temp\TestFile.txt" For Output As #1
Write #1, "Hello World", 234 ’ Datos separados por comas
MyBool = False: MyDate = #2/12/1969# ’ Valores de tipo boolean y Date
Write #1, MyBool; " is a Boolean value"
Write #1, MyDate; " is a date"
Close #1 ’ Se cierra el fichero
El fichero TestFile.txt guardado en C:\Temp contendrá:
"Hello World",234
#FALSE#," is a Boolean value" #1969-02-12#," is a date"
FICHEROS DE ACCESO ALEATORIO
Los ficheros de acceso aleatorio se caracterizan porque en ellos se puede leer en cualquier orden. Los ficheros de acceso aleatorio son ficheros binarios. Cuando se abre un fichero se debe escribir For Random, al especificar el modo de apertura (si el fichero se abre For Binary el acceso es similar, pero no por registros sino por bytes; este modo es mucho menos utilizado).
Abrir y cerrar archivos de acceso aleatorio
Estos archivos se abren también con la sentencia Open, pero con modo Random. Al final se añade la sentencia Len=longitudRegistro, en bytes. Véase el siguiente ejemplo:
fileNo = FreeFile size = Len(unObjeto)
Open filename For Random as #fileNo Len = size
donde filename es una variable que almacena el nombre del archivo. Se recuerda que la función FreeFile devuelve un número entero válido (esto es que no está siendo utilizado) para poder abrir un fichero. El último parámetro informa de la longitud de los registros (todos deben tener la misma longitud). Visual Basic dispone de la función Len(objetoName), que permite calcular la dimensión en bytes de cualquier objeto perteneciente a una clase o estructura. De ordinario los ficheros de acceso directo se utilizan para leer o escribir de una vez todo un bloque de datos. Este bloque suele ser un objeto de una estructura, con varias variables miembro. Los ficheros abiertos para acceso directo se cierran con Close, igual que los secuenciales.
Leer y escribir en una archivo de acceso aleatorio. Funciones Get y Put
Se utilizan las funciones Get y Put. Su sintaxis es la siguiente:
Get #fileNo, registroNo, variableObjeto
Put #fileNo, registroNo, variableObjeto
La instrucción Get lee un registro del fichero y almacena los datos leídos en una variable, que puede ser un objeto de una determinada clase o estructura. La instrucción Put escribe el contenido de la variable en la posición determinada del fichero. Si se omite el número de registro se lee (escribe) a continuación del registro leído (escrito) anteriormente. Véase el siguiente ejemplo:
FileNo=FreeFile
size=Len(unObjeto)
Open filename for Random as #fileNo Len=size Get #fileNo, 3, size
Con este ejemplo, se ha abierto el fichero filename de la misma forma que se realizó en el ejemplo anterior, pero ahora, además se ha leído un registro de longitudsize, y más en concreto, el tercer registro. Si se quisiera modificar el valor de este registro, no habría más que asignarle el valor que se quisiera, para a continuación introducirlo en el fichero mediante la sentencia siguiente:
Put #fileNo, 3, size
FICHEROS DE ACCESO BINARIO
La técnica a emplear es básicamente la misma que con los ficheros de acceso aleatorio, con la salvedad de que en lugar de manejar registros, en los ficheros de acceso binario se trabaja con bytes. Véase el siguiente ejemplo:
FileNo=FreeFile
Open filename for Binary as #fileNo Get #1, 4, dato
dato = 7
Put #1, 4, dato Close #1
En el anterior ejemplo se puede observar como primero se introduce en la variable dato el valor del cuarto byte del fichero filename, para posteriormente asignarle el valor 7, e introducirlo de nuevo en el cuarto byte de filename.
ANEXO A: CONSIDERACIONES ADICIONALES SOBRE DATOS Y VARIABLES
En este Anexo se incluyen algunas consideraciones de interés para personas que no han programado antes en otros lenguajes. A continuación se explican las posibilidades y la forma de almacenar los distintos tipos de variables. CARACTERES Y CÓDIGO ASCII Las variables string (cadenas de caracteres) contienen un conjunto de caracteres que se almacenan en bytes de memoria. Cada carácter es almacenado en un byte (8 bits). En un bit se pueden almacenar dos valores (0 y 1); con dos bits se pueden almacenar 22 = 4 valores (00, 01, 10, 11 en binario; 0, 1 2, 3 en decimal). Con 8 bits se podrán almacenar 28 = 256 valores diferentes (normalmente entre 0 y 255; con ciertos compiladores entre -128 y 127). En realidad, cada letra se guarda en un solo byte como un número entero, el correspondiente a esa letra en el código ASCII (una correspondencia entre números enteros y caracteres, ampliamente utilizada en informática), que se muestra en la Tabla para los caracteres estándar (existe un código ASCII extendido que utiliza los 256 valores y que contiene caracteres especiales y caracteres específicos de los alfabetos de diversos países, como por ejemplo las vocales acentuadas y la letra ñ para el castellano).
Codigo ASCII estandar
Esta tabla se utiliza de la siguiente forma. La primera cifra (las dos primeras cifras, en el caso de los números mayores o iguales que 100) del número ASCII correspondiente a un carácter determinado figura en la primera columna de la Tabla y la última cifra en la primera fila de dicha Tabla. Sabiendo la fila y la columna en la que está un determinado carácter puede componerse el número ASCII correspondiente. Por ejemplo, la letra A está en la fila 6 y la columna 5. Su número ASCII es por tanto el 65. El carácter % está en la fila 3 y la columna 7, por lo que su representación ASCII será el 37. Obsérvese que el código ASCII asocia números consecutivos con las letras mayúsculas y minúsculas ordenadas alfabéticamente. Esto simplifica notablemente ciertas operaciones de ordenación alfabética de nombres. Nótese que todas las mayúsculas tienen código ASCII anterior a cualquier minúscula.
En la Tabla aparecen muchos caracteres no imprimibles (todos aquellos que se expresan con 2 ó 3 letras). Por ejemplo, el ht es el tabulador horizontal, el nl es el carácternueva línea, etc.
En realidad la Versión de Visual Basic no utiliza para representar caracteres el código ASCII sino el Unicode, que utiliza dos bytes por carácter, con lo cual tiene capacidad para representar 65536 caracteres, pudiéndose adaptar a las lenguas orientales. Para los caracteres latinos el byte más significativo coincide con el del código ASCII, mientras que el segundo byte está a cero.
NÚMEROS ENTEROS
Los números enteros se guardan en 1, 2 ó 4 bytes.
• Con 8 bits (1 byte) se podrían guardar 28 números: desde 0 hasta 255.
• Con 16 bits (2 bytes) se podrían guardar 216 números: desde 0 hasta 65.535. Si se reserva un bit para el signo se tendrían 215 números: desde -32768 hasta 32767
• Con 32 bits (4 bytes) se podrían guardar 232 números: desde 0 hasta 4.294.967.295. Si se reserva un bit para el signo se tendrían 231: desde -2.147.483.648 hasta 2.147.483.647
NÚMEROS REALES
En muchas aplicaciones hacen falta variables reales, capaces de representar magnitudes que contengan una parte entera y una parte fraccionaria o decimal. Estas variables se llaman también de punto flotante. De ordinario, en base 10 y con notación científica, estas variables se representan por medio de la mantisa, que es un número mayor o igual que 0.1 y menor que 1.0, y un exponente que representa la potencia de 10 por la que hay que multiplicar la mantisa para obtener el número considerado. Por ejemplo, el número se representa como 0.3141592654101. Tanto la mantisa como el exponente pueden ser positivos y negativos.
Variables tipo Single
Los computadores trabajan en base 2. Por eso un número con decimales de tipo Single se almacena en 4 bytes (32 bits), utilizando 24 bits para la mantisa (1 para el signo y 23 para el valor) y 8 bits para el exponente (1 para el signo y 7 para el valor). Es interesante ver qué clase de números de punto flotante pueden representarse de esta forma. En este caso hay que distinguir el rango de la precisión . La precisión hace referencia al número de cifras con las que se representa la mantisa: con 23 bits el número más grande que se puede representar es,
223 = 8.388.608
lo cual quiere decir que se pueden representar todos los números decimales de 6 cifras y la mayor parte –aunque no todos– de los de 7 cifras (por ejemplo, el número 9.213.456 no se puede representar con 23 bits). Por eso se dice que las variables tipo Single tienen entre 6 y 7 cifras decimales equivalentes de precisión.
Respecto al exponente de dos por el que hay que multiplicar la mantisa en base 2, con 7 bits el número más grande que se puede representar es 127. Elrango vendrá definido por la potencia,
2127 = 1.7014 • 1038
lo cual indica el orden de magnitud del número más grande representable de esta forma.
En el caso de los números Single (4 bytes) el rango es: desde -3.402823E38 a -1.401298E-45 para los valores negativos y desde 1.401298E-45 a 3.402823E38 para los valores positivos.
Variables tipo Double
Así pues, las variables tipo Single tienen un rango y –sobre todo– una precisión muy limitada, insuficiente para la mayor parte de los cálculos técnicos y científicos. Este problema se soluciona con el tipo Double, que utiliza 8 bytes (64 bits) para almacenar una variable. Se utilizan 53 bits para la mantisa (1 para el signo y 52 para el valor) y 11 para el exponente (1 para el signo y 10 para el valor). La precisión es en este caso,
252 = 4.503.599.627.370.496
lo cual representa entre 15 y 16 cifras decimales equivalentes. Con respecto al rango, con un exponente de 10 bits el número más grande que se puede representar será del orden de 2 elevado a 2 elevado a 10 (que es 1024):
21024 = 1.7977 • 10308
Si se considera el caso de los números declarados como Double (8 bytes) el rango va desde
-1.79769313486232E308 a -4.94065645841247E-324 para los valores negativos y desde 4.94065645841247E-324 a 1.79769313486232E308 para los valores positivos.
SISTEMA BINARIO, OCTAL, DECIMAL Y HEXADECIMAL
A contnuación se presentan los primeros números naturales expresados en distintos sistemas de numeración (bases 10, 2, 8 y 16). Para expresar los números en base 16 se utilizan las seis primeras letras del abecedario (A, B, C, D, E y F) para representar los números decimales 10, 11, 12, 13, 14 y 15. La calculadora que se incluye como accesorio en Windows ofrece posibilidades de expresar un número en distintos sistemas de numeración.
Fin.