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 |