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!
Publicar un comentario
Related Posts Plugin for WordPress, Blogger...