Imprimiendo
La impresión en OpenOffice.org es sumamente sencilla, pero debes de tomar en cuenta los elementos que están implicados en ella, por ejemplo: el área de impresión, la impresora disponible, el estilo de página establecido, entre otros elementos que veremos en este capítulo.
El método usado para imprimir es print y se usa de la siguiente manera.
Sub Imprimiendo1() Dim mOpc() ThisComponent.Print( mOpc() ) End Sub
Observa que simple, pero !cuidado¡ La línea anterior podría enviarte a imprimir una gran cantidad de hojas, dependiendo de la configuración actual que tengas, úsala con cuidado pero mejor aun, controla todas las opciones de impresión que aprenderemos aquí.
Para mostrar el nombre de la impresora activa, usamos.
Sub Imprimiendo2() Dim mDI() 'Mostramos el nombre de la impresora activa mDI = ThisComponent.getPrinter() MsgBox mDI(0).Value End Sub
El nombre mostrado dependerá del nombre registrado de tu impresora en tu sistema operativo, para cambiar la impresora a usar, usamos.
Sub Imprimiendo3() 'Matriz para el descriptor de impresión Dim mDI(2) As New com.sun.star.beans.PropertyValue Dim mOpc() 'Cambiamos la impresora para imprimir mDI(0).Name = "Name" mDI(0).Value = "HP_PSC_2200" 'Cambiamos la orientación 0 = Vertical, 1 = Horizontal mDI(1).Name = "PaperOrientation" mDI(1).Value = 1 'Establecemos las opciones de la impresora ThisComponent.setPrinter( mDI ) 'Enviamos a imprimir ThisComponent.Print( mOpc() ) End Sub
Si la impresora no esta registrada con dicho nombre, el lenguaje no te dará ni mostrará un error, así que asegúrate de usar el nombre correcto. Si bien podemos cambiar la orientación del papel para imprimir desde este descriptor, mi recomendación es que solo uses el descriptor de impresión para cambiar de impresora, y todas las demás opciones las establezcas en un estilo de página donde tenemos más riqueza de opciones y parámetros.
En las opciones de impresión tienes algunas características para controlar la cantidad de copias, el orden y las páginas que deseamos imprimir.
Sub Imprimiendo4() 'Matriz para las opciones de impresión Dim mOpc(2) As New com.sun.star.beans.PropertyValue Dim mDI(2) As New com.sun.star.beans.PropertyValue mDI(0).Name = "Name" mDI(0).Value = "HP_LaserJet" mDI(1).Name = "PaperOrientation" mDI(1).Value = com.sun.star.view.PaperOrientation.PORTRAIT mDI(2).Name = "PaperFormat" mDI(2).Value = com.sun.star.view.PaperFormat.LETTER ThisComponent.setPrinter( mDI ) 'El número de copias mOpc(0).Name = "CopyCount" mOpc(0).Value = 1 'Si se imprimen en juegos mOpc(1).Name = "Collate" mOpc(1).Value = True 'Las páginas a imprimir mOpc(2).Name = "Pages" mOpc(2).Value = "1" 'Enviamos a imprimir ThisComponent.Print( mOpc() ) End Sub
De estas opciones, la propiedad Pages, tiene las siguientes variantes para establecer las hojas que deseamos imprimir del documento:
Para | Pages |
---|---|
Una sola página | 1 |
Varias páginas | 3,8,12 |
Un rango de páginas | 5-10 |
Combinación de las anteriores | 4,7,10-15 |
Asegúrate de pasarle el valor a esta propiedad como una cadena de texto, es decir, entre comillas y el valor de la propiedad CopyCount, como un valor entero, si no, te dará un error al querer establecer las opciones de impresión.
Observa que en descriptor de impresión, hemos establecido el formato del papel, para nuestro ejemplo en tamaño carta (LETTER), de nuevo, si no tienes problemas con tu impresión, el tamaño del papel es mejor establecerlo en el estilo de página, en mi experiencia, algunas impresoras rebeldes, se niegan a tomar el formato de papel establecido en el formato de página, por ello, se tiene que establecer en el descriptor de impresión, te sugiero hacer tus pruebas respectivas y si no es necesario, solo establece el tamaño en el estilo de página. Los valores que puede tomar esta propiedad son.
com.sun.star.view.PaperFormat | Valor | Valor en Interfaz |
---|---|---|
com.sun.star.view.PaperFormat.A3 | 0 | A3 |
com.sun.star.view.PaperFormat.A4 | 1 | A4 |
com.sun.star.view.PaperFormat.A5 | 2 | A5 |
com.sun.star.view.PaperFormat.B5 | 3 | B5 |
com.sun.star.view.PaperFormat.LETTER | 4 | Carta |
com.sun.star.view.PaperFormat.LEGAL | 5 | Oficio |
com.sun.star.view.PaperFormat.TABLOID | 6 | Doble carta |
com.sun.star.view.PaperFormat.USER | 7 | Usuario |
Nota que hasta ahora, hemos usado el objeto ThisComponent, es decir, el objeto desde donde se llama a la macro, el método Print esta presente desde cualquier archivo de Calc, por lo que puedes invocarlo desde cualquiera. En las hojas de calculo, tenemos la posibilidad de definir áreas de impresión, que no son más que rangos de celdas con un nombre, pero con algunas características que los hacen especiales, por ejemplo, la posibilidad de repetir una o varias filas o columnas en cada hoja de la impresión. Las opciones de las áreas de impresión que aprenderemos a usar y manipular, son las mismas presentes en el menú Formato > Imprimir Rangos ->. Para obtener las áreas de impresión actuales usamos.
Sub Imprimiendo5() Dim mAI() Dim sMensaje As String mAI = ThisComponent.getCurrentController.getActiveSheet.getPrintAreas() sMensaje = "La hoja activa tiene " & Format( UBound( mAI() ) + 1 ) & " áreas de impresión" MsgBox sMensaje End Sub
Observa que estamos obteniendo (getPrintAreas) las áreas de impresión desde la hoja activa pues este método esta implementado en las hojas del archivo, este método te devolverá una matriz con todos las áreas de impresión establecidas en la hoja desde donde se invoque, cada elemento de esta matriz, tendrá la estructura de la dirección de un rango de celdas, visto múltiples veces a lo largo de este libro, definido por com.sun.star.table.CellRangeAddress.
En el siguiente ejemplo mostramos la dirección de cada área de impresión si las hay.
Sub Imprimiendo6() Dim mAI() Dim sMensaje As String Dim co1 As Integer mAI = ThisComponent.getCurrentController.getActiveSheet.getPrintAreas() If UBound( mAI() ) > -1 Then For co1 = LBound(mAI) To UBound(mAI) sMensaje = DireccionRango( mAI(co1) ) MsgBox sMensaje Next Else MsgBox "No hay área de impresión definidas en la hoja activa" End If End Sub Function DireccionRango( DirRango As Object) As String Dim sTmp As String Dim oRango As Object oRango = ThisComponent.getCurrentController.getActiveSheet.getCellRangeByPosition( _ DirRango.StartColumn, DirRango.StartRow, DirRango.EndColumn, DirRango.EndRow) sTmp = oRango.getSpreadsheet.getName() & "." & _ oRango.getColumns().getByIndex(0).getName() & _ oRango.getRangeAddress.StartRow + 1 & ":" & _ oRango.getColumns().getByIndex(oRango.getColumns().getCount()-1).getName() & _ oRango.getRangeAddress.EndRow + 1 DireccionRango = sTmp End Function
Si no tienes ningún área de impresión definida, Calc tomará todas las hojas con datos como disponibles para impresión, mi recomendación es que siempre establezcas tus áreas de impresión, esto te permite tener siempre el control de lo que se imprimirá, además de poder combinar áreas de diferentes hojas que al ser impresas quedan como si de un solo estilo se tratara. Para borrar las áreas de impresión de una hoja, usamos.
Sub Imprimiendo7() Dim mAI() 'Borramos todas las áreas de impresión de la hoja activa ThisComponent.getCurrentController.getActiveSheet.setPrintAreas( mAI() ) End Sub
Observa como simplemente pasándole una matriz vacía, todas las áreas de impresión serán borrados, nota que ahora estamos usando el método setPrintAreas, si la hoja no tiene ningún área actual, este método no te dará error. Como supongo lo habrás deducido, para agregar áreas de impresión, solo tenemos que llenar dicha matriz con direcciones de rango validos como en el siguiente ejemplo.
Sub Imprimiendo8() Dim mAI(1) As New com.sun.star.table.CellRangeAddress 'Rango A1:E5 mAI(0).Sheet = 0 mAI(0).StartColumn = 0 mAI(0).StartRow = 0 mAI(0).EndColumn = 4 mAI(0).EndRow = 4 'Rango K11:P16 mAI(1).Sheet = 1 mAI(1).StartColumn = 10 mAI(1).StartRow = 10 mAI(1).EndColumn = 15 mAI(1).EndRow = 15 'Agregamos las áreas de impresión ThisComponent.getCurrentController.getActiveSheet.setPrintAreas( mAI() ) End Sub
Si, ya lo notaste, hice un poco de trampita, nota que en el primer rango, en la propiedad Sheet, puse 0 y en el segundo rango, en esta misma propiedad puse 1, esto no afecta el destino de las áreas de impresión, pues estas se agregarán a la hoja desde donde es invocado el método setPrintAreas, que, para nuestro ejemplo, es la hoja activa, no esta de más recordarte que los valores de inicio y fin, tanto de columna como de fila, deben estar dentro de rangos válidos y en el orden correcto. Esta forma de agregar áreas de impresión, te sustituye las existentes, pero como ya sabes manejar matrices, tu tarea es modificar la macro para agregar nuevas sin borrar las existentes.
Ahora, vamos a establecer las filas que queremos repetir en cada hoja de impresión.
Sub Imprimiendo9() Dim oHojaActiva As Object Dim mAI(0) As New com.sun.star.table.CellRangeAddress Dim oFilR As New com.sun.star.table.CellRangeAddress oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() mAI(0).Sheet = 0 mAI(0).StartColumn = 0 mAI(0).StartRow = 0 mAI(0).EndColumn = 3 mAI(0).EndRow = 18 oHojaActiva.setPrintAreas( mAI() ) 'Le decimos que queremos títulos de fila a repetir oHojaActiva.setPrintTitleRows(True) 'Establecemos el rango de filas oFilR.StartRow = 2 OFilR.EndRow = 3 'Las establecemos oHojaActiva.setTitleRows( oFilR ) End Sub
Nota que solo hacemos uso de la fila de inicio y fin, las demás propiedades de la estructura CellRangeAddress, no serán tomadas en cuenta, asegúrate de establecer un rango de filas valido. Cuando haces uso del método setTitleRows, en teoría, automáticamente, la propiedad setPrintTitleRows, se establece en verdadero (True), pero no esta de más que lo establezcas primero, también, si estableces setPrintTitleRows, en verdadero (True), pero no estableces un rango con setTitleRows, de forma predeterminada, se establecerá la fila 1 como titulo a repetir, del mismo modo, si estableces en setTitleRows, una estructura vacía, la fila 1 será establecida.
Para repetir las columnas es similar.
Sub Imprimiendo10() Dim oHojaActiva As Object Dim oColR As New com.sun.star.table.CellRangeAddress oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 'Le decimos que queremos titulos de columna a repetir oHojaActiva.setPrintTitleColumns(True) 'Establecemos el rango de Columnas A:B oColR.StartColumn = 0 OColR.EndColumn = 1 'Las establecemos oHojaActiva.setTitleColumns( oColR ) End Sub
Estos métodos tienen las mismas consideraciones vistas para las filas, si vas a repetir filas y columnas, puedes hacer uso de una sola estructura CellRangeAddress, los métodos respectivos omitirán las propiedades no necesarias para ellos, como en el siguiente ejemplo.
Sub Imprimiendo11() Dim oHojaActiva As Object Dim oTitulosR As New com.sun.star.table.CellRangeAddress oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() oTitulosR.StartColumn = 1 oTitulosR.EndColumn = 1 oTitulosR.StartRow = 2 oTitulosR.EndRow = 2 'Los establecemos oHojaActiva.setTitleColumns( oTitulosR ) oHojaActiva.setTitleRows( oTitulosR ) End Sub
Si vas al menú Insertar > Salto Manual ->, veras que tienes dos opciones, Salto de fila y Salto de columna, tú puedes establecer la fila o columna que desees como un salto de página manual, es decir, estas forzando un salto de página, veamos como hacerlo.
Sub Imprimiendo12() Dim oHojaActiva As Object oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 'Establecemos la fila 5 como salto de página oHojaActiva.getRows.getByIndex(4).IsStartOfNewPage = True 'Verificamos que se haya establecido If oHojaActiva.getRows.getByIndex(4).IsManualPageBreak Then MsgBox "La fila es un salto de página" End If End Sub
Nota como estamos accediendo a una fila (la 5) y la establecemos como inicio de una nueva página con la propiedad; IsStartOfNewPage, al establecer esta propiedad en verdadero (True), estamos insertando un salto de página manualmente, lo cual verificamos con la propiedad; IsManualPageBreak, por supuesto, para quitarlo, solo tienes que establecerla en falso (False).
Sub Imprimiendo13() Dim oHojaActiva As Object oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 'Quitamos el salto de página oHojaActiva.getRows.getByIndex(4).IsStartOfNewPage = False 'Lo verificamos If Not oHojaActiva.getRows.getByIndex(4).IsManualPageBreak Then MsgBox "La fila NO es un salto de página" End If End Sub
Lo mismo para las columnas.
Sub Imprimiendo14() Dim oHojaActiva As Object oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 'Establecemos un salto de página de columna oHojaActiva.getColumns.getByIndex(2).IsStartOfNewPage = True 'Lo verificamos If oHojaActiva.getColumns.getByIndex(2).IsManualPageBreak Then MsgBox "La columna es un salto de página" End If End Sub Sub Imprimiendo15() Dim oHojaActiva As Object oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 'Quitamos un salto de página de columna oHojaActiva.getColumns.getByIndex(2).IsStartOfNewPage = False 'Lo verificamos If Not oHojaActiva.getColumns.getByIndex(2).IsManualPageBreak Then MsgBox "La columna NO es un salto de página" End If End Sub
En las hojas de Calc, tenemos dos tipos de saltos de página, los automáticos y los manuales, los primeros se insertan automáticamente, de acuerdo; al formato de la página y su contenido, los segundos los establecemos nosotros, con el siguiente ejemplo, mostramos todos los saltos de página, tanto de fila como de columna que tenga la hoja activa e informamos si es manual o no.
Sub Imprimiendo16() Dim oHojaActiva As Object Dim mSP() Dim co1 As Integer oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 'Obtenemos todos los saltos de página, por filas, de la hoja activa mSP = oHojaActiva.getRowPageBreaks() 'Mostramos los salto de fila For co1 = LBound( mSP ) To UBound( mSP ) MsgBox "El salto de página esta en la línea: " & mSP(co1).Position + 1 & Chr(13) & _ "Es salto manual: " & mSP(co1).ManualBreak Next co1 'Ahora los de columna mSP = oHojaActiva.getColumnPageBreaks() For co1 = LBound( mSP ) To UBound( mSP ) MsgBox "El salto de página esta en la columna: " & mSP(co1).Position + 1 & Chr(13) & _ "Es salto manual: " & mSP(co1).ManualBreak Next co1 End Sub
Cuidado, la macro anterior puede llegar a mostrarte decenas de saltos de página, esto puede pasar cuando tienes datos y borras todas las áreas de impresión, de forma predeterminada, se agregan saltos de página en toda la hoja, de nuevo, la recomendación es siempre establecer tus áreas de impresión de forma explicita.
Puedes quitar todos, los saltos de páginas, tanto de fila como de columna, con el siguiente método.
Sub Imprimiendo17() Dim oHojaActiva As Object oHojaActiva = ThisComponent.getCurrentController.getActiveSheet() 'Quitamos TODOS los saltos de páginas manuales oHojaActiva.removeAllManualPageBreaks() End Sub
El siguiente ejemplo, te inserta un salto de página cada 2 filas en la selección actual, procura no tener una selección muy grande y sobre todo no mandar a imprimir que te podrían salir muchas hojas, ve el resultado en tu vista preliminar.
Sub Imprimiendo18() Dim oSel As Object Dim co1 As Integer oSel = ThisComponent.getCurrentSelection() 'Insertamos un salto de página cada dos filas For co1 = 2 To oSel.getRows.getCount() - 1 Step 2 oSel.getRows.getByIndex(co1).IsStartOfNewPage = True Next End Sub
Por ultimo, para ver tu vista previa, usa el siguiente método, que no me gusta pero por ahora es la única forma que conozco.
Sub Imprimiendo19() Dim oDocF As Object Dim oDH As Object oDocF = ThisComponent.getCurrentController.Frame oDH = createUnoService("com.sun.star.frame.DispatchHelper") 'Mostramos la vista previa oDH.executeDispatch(oDocF, ".uno:PrintPreview", "", 0, Array()) End Sub
En versiones anteriores de OOo, cuando enviabas a imprimir, de forma predeterminada, se enviaba todas las hojas del documento, ahora, solo se envían las hojas seleccionadas, claro, esto siempre lo puedes cambiar desde el cuadro de dialogo imprimir en el menú Archivo > Imprimir..., Para seleccionar varias hojas a imprimir, solo tienes que seleccionar un rango de cada una de ellas, puede ser solo una celda, y agregarlos a un contenedor de rangos que ya aprendimos a usar, y seleccionarlos, al seleccionar rangos de diferentes hojas, como consecuencia, se seleccionan las hojas que los contienen, después, podemos enviar a imprimir como en el siguiente ejemplo.
Sub Imprimiendo20() Dim oDoc As Object Dim oHojas As Object Dim mOpc() Dim oRangos As Object oDoc = ThisComponent oHojas = oDoc.getSheets() 'Creamos el contender para los rangos oRangos = oDoc.createInstance("com.sun.star.sheet.SheetCellRanges") 'Agregamos la primer celda de cada hoja, puede ser cualquier celda oRangos.addRangeAddress( oHojas.getByIndex(6).getCellRangeByName("A1").getRangeAddress() ,False ) oRangos.addRangeAddress( oHojas.getByIndex(7).getCellRangeByName("A1").getRangeAddress() ,False ) oRangos.addRangeAddress( oHojas.getByIndex(8).getCellRangeByName("A1").getRangeAddress() ,False ) 'Al seleccionar las celdas de diferentes hojas, estamos seleccionando dichas hojas oDoc.getCurrentController.select( oRangos ) 'Enviamos a imprimir oDoc.print( mOpc() ) End Sub
La recomendación general, es que siempre establezcas tus áreas de impresión correctamente, así como el estilo de página con la configuración deseada, con lo cual, la impresión se facilitará enormemente.
Si tienes dudas acerca de lo aquí explicado, tienes algún problema con AOO, o quieres ampliar la información, no dudes en dirigirte al Foro Oficial en español de Apache OpenOffice para Macros y API UNO |