31 mayo 2007

¡Se dan clases de verano!

Debido a la necesidad que impera con respecto a la capacitación en el uso de la computadora, no puedo quedarme viendo que México necesita de personas capacitadas, así que estoy ofreciendo este verano cursos de computación.

Si quieres, te puedo enseñar a usar los programas que enlisto o bien podemos trabajar en un proyecto (o sea, las clases ayudan a aprender y a resolver un trabajo). Los programas en las que te puedo ayudar son estos:
  • Adobe Premiere (edición de video)
  • Adobe Photoshop (edición o creación de imágenes de mapas de bits)
  • Adobe ImageReady (prepara imágenes de mapas de bits para su uso en el internet)
  • Adobe Ilustrador (dibujo vectorizado)
  • Adobe Acrobat (manejo de archivos portátiles, PDF)
  • Adobe Flash (animaciones y páginas web)
  • Adobe Dreamweaver (páginas web)
  • Adobe GoLive (páginas web)
  • Adobe InDesign (diseño editorial)
  • Microsoft Office (software de productividad): Word, Excel, Powerpoint, Access.
  • Programación en C, C++, SQL, Visual Basic 6.0, Visual Basic .net, Visual Basic 2005, Pascal, etc.
Si te interesa ponerte al corriente en clases de computación, necesitas aprender diseño gráfico o programación, o simplemente saber usar el Office, avísame. Déjame un comentario en este blog o mándame un correo.

23 mayo 2007

¿Y qué objeto tiene imprimir?

En esa era postmoderna llena de circuitos electrónicos y bits de información que hostigan información por las vías digitales de la comunicación moderna, ¿todavía es importante tener documentos impresos? ¿Qué no se había acabado eso cuando se petatearon los dinosaurios y esa onda? ¿Acaso me mintieron cuando me dijeron que el internet y las bases de datos movían información sin necesidad de papel?

Ciertamente los documentos han perdido importancia con el advenimiento de las maravillas digitales, sin embargo los documentos impresos son todavía imprescindibles. Se usa para los documentos realmente importantes (como el pasaporte, acta de nacimiento, etc.), de las que se tiene que asegurar que le llegue a las personas (se sorprenderían las veces que a la gente nunca le llegan los correos los documentos que mando por i-meil... échenle la culpa al i-meil...) o autorizar cosas (cheques, permisos, etc.) o que necesiten acuse de recibido (como la boleta de calificaciones de la primaria).

Para dejar a un lado tanto choro mareador, los documentos impresos son importantes y son fundamentales para los sistemas que usan bases de datos. Siempre se necesitan usar reportes impresos. Siempre.

Hay muchas estrategias para imprimir desde Visual Basic 6.0. Han desarrollado programas externos que se "pegan" a VB (como el Crystal Reports), crear formas con arreglos de controles (como labels) y usar la función PrintForm, y otras mil maneras diferentes (bueno, pue' que exageré un poco con las mil maneras, pero seguramente llegan a 999, jeje). Hoy voy a explicar la manera de usar el objeto Printer para crear documentos impresos.

El objeto Printer tiene todos los métodos y propiedades necesarias para imprimir (la explicación "oficial" del objeto Printer, sus propiedades, métodos, eventos y demás monerías, lo puedes encontrar aquí). Haz de cuenta que dibujas sobre una hoja (le pones círculos, logos, líneas, texto, etc.) y cuando ya está listo, le dices que imprima la hoja. El objeto se refiere a la impresora instalada por defáult. Si quieres acceder a otra impresora que haya instalado en el sistema, se hace uso de la colección Printers. Haz de cuenta que una colección es un arreglo de objetos, en este caso, un arreglo de objetos Printer.

Para que veas como funciona esto, preparé un programa explicatorio que da las explicaciones necesarias para explicar cómo se puede usar el objeto Printer en una aplicación de manera explicada. ¿Me explico?

Este programa consta de tres ventanas: la principal desde donde se imprime, otra que te permite configurar la impresora y la última nunca se ve, pero contiene la foto de Wally que vamos a usar más adelante. Al ejecutar el programa se ve esta pantalla:


Aquí apareden varas cajas de texto donde le usuario puede escribir lo que se le pega la gana (siempre y cuando no sean pelangochadas ni vituperios espantosos). A un lado hay una cajita donde el usuario puede "tachar" la caja a un lado de la línea que quiere ver en negritas. Hasta a bajo hay otras tres "cajitas". Una te imprime un círculo en la hoja, otra dibuja un rectángulo y el tercero dibuja la imagen de mi buen amigo (y casi casi mi doble) Wally (conocido también como Waldo en otros lugares). Como es solo un ejemplo, dibujé el círculo donde se me pegó la gana, al igual que el rectángulo y el lugar donde pongo la foto de Wally. En un caso real, usa el mismo código, pero acomoda las cosas donde se vean estéticamente placenteras. Este es el ejemplo de una ventana con datos:


En este caso, escirbe un renglón en negritas y otros dos en texto normal. También le especifiqué que dibujara el círculo, el recftángulo y que pusiera la foto de mi buen amigo Wally. Al darle click al botón que tiene la impresora volando con una carpeta atrás, genera una hoja como ésta:


Yo sé que no es nada del otro mundo, pero es suficiente para demostrar como funciona esta onda. Esto se imprime a la impresora que el usuario tiene especificada como predeterminada. Pero, ¿qué sucede si quiere cambiar de impresora? Una solución sería decirle al usuario que se decida y ponga como predeterminada la impresora que quiere usar y si lo quiere imprimir en otra, que vaya al Panel de Control - Impresoras o directamente a la opción Impresoras y faxes del menú de Windows y establezca la impresora defáult y le mueva a las opciones. Sería una solución, pero te verías demasiado chafa y probablemente te manden por un tubo debido a tu poca pericia informática (digo, es un enfado entrar a configurar las impresoras cada vez que quieras moverle algo a la impresora... que hueva).

Una mejor solución, de hecho la que usan todos los programas que te permiten imprimir, sería darle una ventana donde pueda configurar la impresora (o cambiar de impresora). Para esto es la segunda ventana, misma que aparece cuando el usuario le pica al botón que tiene una impresora sobre una mano extendida. Esta es la segunda ventana:


En el primer combo box, lo inicializo con los nombres de todas las impresoras instaladas en el sistema, abajito muestro el número de copias que va a imprimir, luego puede elegir el tamaño del papel (yo le dejé las opciones de carta y oficio, pero se pueden programar otros tamaños), la calidad de impresión y te muestra la orientación del papel. Abajo están dos botones y, como eres un empollón (bueno, tal vez no tanto), podrás deducir que el botón que tiene la palomita verde cierra la ventana guardando los cambios y el que tiene la espantosa X roja, sirve para cerrar la ventana sin guardar los cambios hechos.

Ahora que ya vista como funciona, vámonos al código. Vamos empezando con la primera ventana. Solamente voy a poner aquí el código que sea interesante para lo relacionado a la impresión (o sea, no esperes que explique el código para cerrar la ventanita o terminar el programa).

Al presionar el botón que imprime el documento, se ejecuta el siguiente código:


Comienzo con la instrucción On Error que le dice a VB 6.0 que si se traba con alguna bronca, se vaya a la etiqueta llamada "fin" que puse al final. O sea que en cuantro encuentre un problemita o problemón (cosa que esperamos nunca suceda), va a interrumpir el proceso de impresión, imprimiendo solo aquello que alcanzó a hacer antes del error. Se quedará en la memoria de la impresora lo que intentó hacer hasta el error.

Después de asegurarnos que no hay problema en caso que algo falle, me fijo si el usuario quiere dibujar un círculo sobre la hoja. En mi caso, el Checkbox que me indica si quiere el círculo se llama chkCircle. Si es así, uso la función Circle del objeto Printer para dibujarlo. Lo único que le tengo que dar son las coordenadas del centro del círculo y el radio del mismo. Tiene otros parámetros que se pueden especificar para hacer semicírculos, llenarlos de color, etc. , pero por lo pronto con estos bastan. Recuerda que es solo un ejemplo, ya te toca a ti experimentar un poco más. Después uso las propiedades CurrentX y CurrentY para posicionarme en esas coordenadas sobre la hoja y en esa posición escribo el texto Círculo mediante la función Print que sirve para escribir texto sobre la hoja. Puedes ver estas ligas para infomación acerca del uso de la función Circle y de las propiedades CurrentX y CurrentY (esta documentación está en inglés, pero no creo que tengas problemas en agarrar la onda).

Después hago algo muy similar con el rectángulo, solo que aquí el CheckBox se llama chkRect, y se usa la función Line, aunque está hecho para dibujar líneas al especificar las coordenadas donde comienza y donde termina, al final le escribí el parámetro B que indica que es una caja (box). Dejé dos paréntesis porque el parámetro que sigue de las coordenadas es la del color de la línea, que en mi caso no quería modificar. Para más informes acerca del uso de la función Line, haz click aquí.

Para dibujar una imagen, que es la condición que sigue, puedo usar el contenido de un PictureBox que ponga sobre una ventana. En mi caso tengo una tercera ventana en mi proyecto que nunca es vista por el usuario que sirve para este fin. La forma se llama frmImagen que tiene un PictureBox con la foto de Wally (llamado picWally). Entonces cargo la forma a la memoria (Load frmImagen), dibujo la foto en la hoja (Printer.PaintPicture frmImagen.picWally 600,900) y quito la ventana de la memoria (Unload frmImagen). La función PaintPicture recibe como parámetros las coordenadas donde se va a dibujar la imagen. Tiene mil otros parámetros para hacer chuchulucos y monerías diversas y si quieres verlo más a fondo, haz click aquí. La ventana frmImagen en la vista diseño, es esta:

Después de todo este alboroto, toca escribir las líneas de texto. Para esto mis cajas de texto son un arreglo de Textboxes, llamados txtTextLine, que consta de 10 elementos. También tengo los Checkboxes que me indican si la línea va en negritas en otro arreglo llamado chkNegritas, también de 10 elementos. Entonces compiezo un ciclo, controlado por la variable i, que va de 0 a 10 para recorrer las cajas de texto y cajas de opción. Inicializo la posición de Y (para los posicionarse en los renglones) en 1300 para que comience desde allí. Mientras i sea menor a 10 y haya algún texto en la caja de texto (valga la redundancia), establece la posición en X en 500 (todos los renglones comienzan donde mismo, en mi ejemplo) y se fija si va en negritas o no. Si lo quiere más negrote, establece la propiedad FontBold en verdadero. Luego escribe el texto, como ya se explicó antes, con la función Print, incremento i y pongo en falso la propiedad FontBold para que no siga escribiendo en negritas. Y el ciclo se repite, y repite, y repite, y repite...

Al terminar de imprimir las líneas de texto, uso la función EndDoc que sirve para decir que ya terminó el trabajo y que escupa la hoja que ya dibujé. Si se tienen que imprimir muchas hojas, puedes usar la función NewPage que escupe una hoja y te deja otra "en blanco" para que sigas dibujando.

Hasta allí todo parece felicidad y alegría. Lo que nos falta ver ahora es la manera de que aparezca la ventana que permite elegir y configurar las impresoras. Al cargar la ventana a la memoria, lleno un ComboBox con las impresoras instalados en la compu del usuario y lleno los otros controles. Es muy sencillo, así que ni lo explico (bueno, lo explicaré abajo del código). Este es el código:


Comienzo con un ciclo desde 0 hasta el número de impresoras instaladas menos uno. ¿Por qué le resto uno? Porque consideramos la primera impresora instalada como la número cero. La propiedad DeviceName es una cadena con el nombre de la impresora (por ejemplo, "HP LaserJet 1200"). El siguiente ciclo me sirve para establecer la impresora default como la impresora seleccionada en el ComboBox (cboPrinters). Para lograr esto, hago un ciclo recorriendo la lista de impresoras (de la colección Printers) hasta encontrar el que tiene el mismo nombre (DeviceName) que el de la impresora predeterminada (el objeto Printer es la impresora predeterminada).

Después de esto, inicializo mis ComboBoxes de tamaño y calidad en 0 (para asegurar que hay algún elemento seleccionado y no me de broncas después), muestro el número de copias que tiene especificada (usando la propiedad Copies) y la orientación del papel. Para la orientación del papel, usa la constante vbPRORPortrait la cual es simplemente un número que guarda la propiedad Orientation. ¡Listo! Ya está.

Ahora vamos a guardar la configuración. Este es el código del botón que acepta los valores y cierra la ventana (es lo que sucede cuando presionan el botón cmdPrint_Click):


Esta está sencillo. Establezo que Printer sea igual a la impresora seleccionada (Set Printer = Printers(cboPrinters.ListIndex)), cambio el tamaño de papel al que eligieron (Printer.PaperSize = Right(cboTmno.List(cboTmno.ListIndex), 1)). Para especificar la calidad, uso un Case y según el elemento elegido, le establezco la calidad (con el vbPRPQDraft, vbPRPQLow, vbPRPQMedium y vbPRPQHigh). Al final cierro la ventana (Unload Me). ¡Listo!

Creo que es todo. Les dejé ligas a páginas que tienen las referencias a todo lo habido y por haber. Si hay dudas, mándame un emilio y deja un mensaje aquí. ¡Hasta la próxima!

07 mayo 2007

Primer concurso multimediático: Convocatoria definitiva y final

Extendimos el plazo de entrega, hemos conseguido muchos premios más (iPods, curso de edición de video o diseño digital de $2350, bocinas home theater para compu, 2 celulares Nokia 5300 y estamos en espera de otras sorpresas...).



Sólo falta que te inscribas. ¡Te espero el 24/Mayo con tu proyecto!

02 mayo 2007

Textos, textos y más textos...

Algo que es útil y que te puede sacar de apuros muchas veces son los archivos de texto. Tal vez creas que son cosa del pasado, hoy en pleno siglo XXI con mil DBMSes chiroliros en el mercado, ¿y usar archivos de texto? Así es. Son muy usados todavía, por ejemplo, los archivos ini, inf y bat de Windows son archivos de texto, así como archivos de código fuente en lenguaje C (.c), C++ (.cpp), Visual Basic.net, Visual Basic 6.0 (.frm, .bas, etc.), etc.

Claro que no sirven para resolver todo tipo de problemas, para eso están los DBMS como Oracle o MySQL. Pero para generar reportes, guardar configuración o mandar datos a Excel, es eficiente. Como es útil, vamos a ver cómo manipular archivos de texto con Visual Basic 6.0.

Hice un pequeño proyecto que ejemplifica el uso de archivos de texto que puedes bajar aquí (todavía no sirve la liga, pero pronto lo podrás descargar). El programa tiene varias funciones: deja que el usuario escriba lo que sea en 24 cajas de texto, los almacena como archivos de texto "normales" o en formato CSV para abrirlos en Excel, abre archivos de texto y los elimina.

Para comenzar con el código, yo, en mi caso particular, decidí hacer un módulo que contiene una variable global (FileName) que almacena el nombre de archivo que se está manipulando (o sea, el que se quiere abrir, guardar o eliminar) y también almacena una función, FileWindow, que se encarga de abrir la ventana que deja que veas las unidades, carpetas y archivos para que selecciones el archivo a manipular y llena la variable global FileName con el resultado (así otras ventanas saben el nombre del archivo y la carpeta en donde se encuentra). Esto me ahorra código porque casi todas las funciones necesitan usar una ventana similar para almacenar, guardar o eliminar. No es absolutamente necesario hacerlo de esta manera, pero funciona. Aquí les muestro el código de el módulo.


Como puedes ver, solo carga la ventana frmFile, le cambia el Caption y lo muestra. Esta es la ventana frmFile primero en la vista diseño y luego al ejecutarlo y pedirle que abra un archivo):




Ok. Aquí escribo todo el código que contiene esta ventana. Básicamente son eventos que controlan los controles (valga la rebuznancia) del drive (Drive1), de la lista de carpetas (Dir1) y la lista de archivos (File1). El otro código usa la caja de texto que tiene el nombre del archivo (txtFile) y lo asigna a mi variable global (FileName, que ya expliqué anteriormente). Este es:


Ok. Hasta allí nos hemos ocupado de detallitos vanos y ruines que solamente nos sirven para ahorrarnos código más adelante. Ahora vamos a hablar del código que trabaja con los archivos de texto. Para esto, vamos a ver el código de la ventana principal que se encarga de guardar archivos de texto "normalazos" (es que hay otro botón que los guarda en formato CSV para su uso en Excel), lo que sucede cuando presionan un botón llamado cmdSave. Aquí pongo el código y abajo lo explico.

Comienzo declarando dos variables: i que controla un ciclo que graba las líneas de texto al archivo e Imprimir, una cadena que almacena lo que se va a escribir en el archivo, un renglón a la vez.
Después de las declaraciones, usa la función FileWindow, explicado anteriormente, para desplegar la ventana que permite buscar en unidades de disco, carpetas, etc. para especificar la carpeta y nombre del archivo a guardar. Si el usuario no presionó el boton Cancelar de esa ventana que pide los detalles del archivo (frmFile), o sea que el nombre del archivo (FileName) no es igual a una cadena vacía (porque el código del botón cancelar de frmFile le asigna una cadena vacía, "", a FileName), comienzo toda la onda.

Para manipular un archivo se tiene que abrir. Para eso me sirve la instrucción Open. Cuando abres un archivo tienes que decirle que archivo y que quieres hacer con él. Es igual que invitar a una chava a salir: tienes que decidir a qué chava (escribir el nombre del archivo) y decirle que quieres hacer con ella (por ejemplo, llevarla al cine, a cenar, a barrer y trapear tu cuarto, etc.), si no, las cosas no funcionan. Es por esto que escribo Open seguido del nombre completo del archivo (o sea con todo y la ruta de carpetas) y al final le escribo el uso que quiero hacer con el archivo. Como aquí quiero escribir datos al archivo, o sea darle salida a mis datos, le digo For Output.

Visual Basic tiene mucha confianza al trabajar con archivos, algo similar a lo que sucede en tu casa o con tus amigos. Tienes tanta confianza que no te llaman por tu nombre sino por un apodo. Visual Basic hace lo mismo: para referirse a un archivo a la que quiere escribir, o desde donde quiere leer datos, no lo hace por el nombre del archivo sino por un número del 1 al 9. Es por eso que al final de la instrucción Open le agregue el As #1. De esta manera, al usar instrucciones que manipulan al archivo (Close, Print, etc.) indico que todo va a funcionar con el archivo número 1. Para resumir, la sintáxis completa de la instrucción Open queda así:

Open nombre_del_archivo For uso As número

Después de abrir el archivo, uso un ciclo For para controlar el número de renglones que voy a escribir al archivo. Para hacerlo fácil y rápido uso una característica que tiene Visual Basic 6.0 y pierde en la versión .NET. Esto es el uso de arreglos de controles. Hice 3 arreglos de textboxes (txtTexto1, txtTexto2 y txtTexto3) cada uno con 8 elementos.

Con el contenido de las cajas de texto, armo la cadena que voy a escribir al archivo (Imprimir). Si no es una cadena vacía, o sea que escribieron algo en cualquier caja de texto de ese renglón, uso la función Print para escribir la cadena Imprimir al archivo.

En primer lugar, le tengo que decir el archivo al que quiero escribir la cadena (por medio del número, en nuestro caso 1) y la cadena que quiero escribir (en este caso, la cadena Imprimir). Por eso la instrucción queda como Print #1, Imprimir.

Después de escribir un renglón al archivo, vuelve a arrancar el ciclo y vuelve a hacer lo mismo. Al final de toda la escribidera, tengo que cerrar el archivo, con Close #1, o sea, cierra el archivo al que hace referencia el número 1.

El código que almacena un archivo CSV para su uso en Excel usa un código casi idéntico. Al principio se asegura de que la extensión sea CSV y todo lo demás es casi lo mismo, excepto que inserta comas entre las cadenas.

Los archivos CSV (Comma Separated Values) son archivos de texto que puede importarse directamente a Excel. Lo único que los hace diferentes es que cada renglón del archivo de tesxto corresponde a una fila de excel y los valores de las celdas se escriben seaprados por una coma, o sea que la coma separa los valores que van en las diferentes celdas de la fila. Para mayor información acerca de archivos CSV, dale click aquí.

Este es, por fin y después de tanto rollo, el código que genera los archivos CSV (esto se ejecuta cuando le das click al botón cmdExcel):


Solo hace un pequeño cambio para poder leer datos del archivo. Este es el código que abre un archivo de texto y vacía su contenido en otra ventana (frmRead) en una caja de texto (txtFileCont). Este es el código:


Lo que hago aquí es sencillo. Declaro una cadena que va a almacenar las líneas que voy leyendo del archivo (Cadena), luego uso mi función FileWindow para pedir el archivo que se va a abrir. Si el usuario da un nombre de archivo, abro el archivo para lectura. Esto se hace sustituyendo el For Output que usábamos para escribir al archivo, por For Input que indica que voy a leer datos del archivo. Y, en lugar de usar el Print para escribir al archivo, uso el Input. En mi caso leo un caracter a la vez para no errarle. La sintáxis es Input(no_de_caracteres_a_leer, no_de_archivo). Fácil, ¿no?

Como estoy leyendo caracter por caracter, lo hago dentro de un ciclo. Voy adjuntando los caracteres que voy leyendo a la caja de texto de la ventana donde voy a desplegar el contenido del archivo (frmRead.txtFileCont). Esto se repite hasta que llegue al final del archivo, cosa que pruebo usando la función EOF(no_de_archivo).

Otra operación que se realiza con frecuencia es eliminar gente, perdón, registros (bueno también se mata a mucha gente, pero ese es otra historia que no tiene que ver con archivos de texto). Para esto existe la instrucción linda y tierna Kill seguida por el nombre del archivo a eliminar. Esto se puede observar en este código que se ejecuta cuando se presiona el botón eliminar (cmdKill):


Creo que eso es todo. Lo único que no expliqué fue la ventana de "Acerca de..." (lo puse por pura vanidad). ¡Hasta la próxima!
Related Posts Plugin for WordPress, Blogger...