OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

Printinting a range
Goto page 1, 2  Next
 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API
View previous topic :: View next topic  
Author Message
Francesco
Guest





PostPosted: Mon Feb 23, 2004 5:14 am    Post subject: Printinting a range Reply with quote

How can I print a range from a macro?

I checked all references suggested by DannyB in

http://www.oooforum.org/forum/viewtopic.php?t=6040

but every solution I tried failed. I think I need a plain sub, ready to work.

Pity the poor newby.

Thanks .
Back to top
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Mon Feb 23, 2004 5:38 am    Post subject: Reply with quote

Here is a working example, adapted from this article....
Writer Examples
http://www.oooforum.org/forum/viewtopic.php?t=6049

I just took the code from my previous article, rearranged it a bit to generate the following.

Code:

Sub Main
   ' Create new writer document.
   oDoc = StarDesktop.loadComponentFromURL( "private:factory/swriter", "_blank", 0, Array() )
   
   
   ' Get the text of the document.
   oText = oDoc.getText()
   ' Get a cursor that can move over or to any part of the text.
   oCursor = oText.createTextCursor()
   
   
   ' Create ten pages of content.
   For nPage = 1 To 10
      ' Insert text into current paragraph.
      oText.insertString( oCursor, "This is page " & CSTR( nPage ) & ".", False )
      ' Give this paragraph a style.
      oCursor.ParaStyleName = "Heading 2"
      IF nPage > 1 Then
         ' If we are beyond the 1st page, then make the first new paragraph
         '  have a page break ahead of it.
         oCursor.BreakType = com.sun.star.style.BreakType.PAGE_BEFORE
      EndIf
      ' Start a new paragraph.
      oText.insertControlCharacter( oCursor, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False )
      
      
      ' Now insert 20 lines of text.
      For nLine = 1 To 20
         oText.insertString( oCursor, "This is line " & CSTR( nLine ) & ".", False )
         oText.insertControlCharacter( oCursor, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False )
      Next
   Next
   
   

   oDoc.print( _
      Array( _
         MakePropertyValue( "CopyCount", 1 ),_
         MakePropertyValue( "Pages", "1-4;7" ) ) )

End Sub


' The MakePropertyValue() function is defined here...
'   http://www.oooforum.org/forum/viewtopic.php?t=5108
'
Function MakePropertyValue( Optional cName As String, Optional uValue ) As com.sun.star.beans.PropertyValue
   oPropertyValue = createUnoStruct( "com.sun.star.beans.PropertyValue" )
   If Not IsMissing( cName ) Then
      oPropertyValue.Name = cName
   EndIf
   If Not IsMissing( uValue ) Then
      oPropertyValue.Value = uValue
   EndIf
   MakePropertyValue() = oPropertyValue
End Function



What this example does....
1. It creates a new Writer document.
2. Fills it with 10 pages of content. (Each page is 1 header line, + 20 numbered lines of content.)
3. Prints pages 1 thru 4, and page 7.

You didn't mention what kind of document you are trying to print?: So I'm assuming Writer. But the print code above
Code:
oDoc.print( _
      Array( _
         MakePropertyValue( "CopyCount", 1 ),_
         MakePropertyValue( "Pages", "1-4;7" ) ) )

should work the same for any document, Calc, Draw, Impress, Math, etc.

Hope that helps.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
Francesco
Guest





PostPosted: Mon Feb 23, 2004 6:39 am    Post subject: Reply with quote

Thanks DanniB, for your patience and constant help.

I already checked the code and the article you sent to me, but it didn’t help too much. As said I am a newbie, and I’ll remain such. I could not get out what I need, from your example, and from other codes I found on this forum.

My company is migrating to OOO, and I am trying to convert to OOO some jobs previously done by Excel.

All what I need is a routine to print, for example, range “A1:C50” from “Sheet1”, than another range from another sheet, and so on for a few times. Shouldn’t be that long.

The code I get registering macro, works, but I’d like something that doesn’t switch every time the active sheet.

Thanks again.

Francesco
Back to top
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Mon Feb 23, 2004 8:19 am    Post subject: Reply with quote

I can record a macro to print cells A1:B5. Printing the selection works.

Playing back the macro does NOT print just the selection. It prints everything. Are you actually able to record a macro that prints only selected cells, and then play it back, and have it print ONLY the selected cells?

If it would work, then here is how I would write the code...
Code:
Sub Main
   ' Get the current Calc document.
   oDoc = ThisComponent
   
   ' Get one of the document's Controllers.
   oDocCtrl = oDoc.getCurrentController()
   
   ' Get the document's frame from the controller.
   oDocFrame = oDocCtrl.getFrame()
   
   ' Get the collection of all sheets on this document.
   oSheets = oDoc.getSheets()
   ' Get the first sheet.  (Either by index or by name.)
   oSheet1 = oSheets.getByIndex( 0 )
'   oSheet1 = oSheets.getByName( "Sheet1" )
   
   ' Get a range of cells from the sheet.
   oRange = oSheet1.getCellRangeByName( "A1:B5" )

   ' Ask the controller to select that range of cells.
   oDocCtrl.select( oRange )

   oDispatchHelper = createUnoService( "com.sun.star.frame.DispatchHelper" )
   oDispatchHelper.executeDispatch( oDocFrame, ".uno:Print", "", 0,_
      Array(_
         MakePropertyValue( "Copies", 1 ),_
         MakePropertyValue( "Selection", True ),_
         MakePropertyValue( "Collate", False ) ) )
End Sub


' The MakePropertyValue() function is defined here...
'   http://www.oooforum.org/forum/viewtopic.php?t=5108
'
Function MakePropertyValue( Optional cName As String, Optional uValue ) As com.sun.star.beans.PropertyValue
   oPropertyValue = createUnoStruct( "com.sun.star.beans.PropertyValue" )
   If Not IsMissing( cName ) Then
      oPropertyValue.Name = cName
   EndIf
   If Not IsMissing( uValue ) Then
      oPropertyValue.Value = uValue
   EndIf
   MakePropertyValue() = oPropertyValue
End Function



Here is what the Macro Recorder generates...
Code:
sub Main
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "ToPoint"
args1(0).Value = "$A$1:$B$6"

dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args1())

rem ----------------------------------------------------------------------
dim args2(2) as new com.sun.star.beans.PropertyValue
args2(0).Name = "Copies"
args2(0).Value = 1
args2(1).Name = "Selection"
args2(1).Value = true
args2(2).Name = "Collate"
args2(2).Value = false

dispatcher.executeDispatch(document, ".uno:Print", "", 0, args2())


end sub

_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
Francesco
Guest





PostPosted: Mon Feb 23, 2004 9:43 am    Post subject: Reply with quote

Hi DanniB

Actually, my macro worked (printed ONLY the selected area), yours, both, printed the whole sheet. Since my macro was simply a recorded one, it seemed to me impossible that it worked differently from the second one you sent, so after some experimenting, I spot out the difference. If you activate another macro (in my case there was a “go-to-sheet” macro), soon after the “print-range” macro, the printout is restricted only to the selected range, otherwise the whole sheet is printed.

So, thank you, the code you sent works, for me it is quite OK.

But, let me ask, just to know. Isn’t that a lot of code for printing a range? Isn’t there another way?

Thank you for your help, may your computer live forever.

Francesco
Back to top
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Mon Feb 23, 2004 10:11 am    Post subject: Reply with quote

Could you please post the macro you recorded that works?

Francesco wrote:
Isn’t that a lot of code for printing a range? Isn’t there another way?

The trick is to build up subroutines. Here is how I would write it using routines from my library...
Code:

   CalcSelectCells( oDoc, "A1:B5" )
   DocumentDispatch( oDoc, ".uno:Print", "", 0,_
      Array(_
         MakePropertyValue( "Copies", 1 ),_
         MakePropertyValue( "Selection", True ),_
         MakePropertyValue( "Collate", False ) ) )


I am using more and more routines that handle the dispatcher, the controller's selection, etc. More and more automatic moving between the documet model, it's controller and its frame.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
dfrench
Moderator
Moderator


Joined: 03 Mar 2003
Posts: 1605
Location: Wellington, New Zealand

PostPosted: Mon Feb 23, 2004 10:24 am    Post subject: Reply with quote

I recall that there have been a few problems with selection and recorded macros.
Using the API avoids this by using setprintareas(). If you setprintareas on a sheet, that is all that will be printed out when you do the print action. The following code sets one print area on the first two sheets. If the Print Only Selected Sheets option is turned off, running the macro will print only the selected areas for those 2 sheets.
Code:
Sub Macro1
dim selectedareas(0) as new com.sun.star.table.CellRangeAddress
oDoc=Thiscomponent   'The document running the macro
selectedareas(0).sheet=0  'first sheet
selectedareas(0).startcolumn=0  'Col A
selectedareas(0).startrow=0      ' Row 1  (zero based index)
selectedareas(0).endcolumn=2   ' Col C
selectedareas(0).endrow=9      ' Row 10
oSheet=oDoc.Sheets(0)
oSheet.setprintareas(selectedareas())  ' set the print area on the sheet
selectedareas(0).sheet=1  'second sheet
selectedareas(0).startcolumn=0  'Col A
selectedareas(0).startrow=0      ' Row 1  (zero based index)
selectedareas(0).endcolumn=2   ' Col C
selectedareas(0).endrow=9      ' Row 10
oSheet=oDoc.Sheets(1) 'second sheet
oSheet.setprintareas(selectedareas())  ' set the print area on the sheet
' assuming that print only selected sheets is off this will print all sheets with selected areas in them
oDoc.Print(Array())  ' print to default printer
End Sub
Note that this does not actually select the ranges so if they need to be selected in the macro for purposes other than printing you will have add code to do that.
You can set more than one print range on a sheet, selectedareas must be defined as an array and have the dimension of the number of areas to be set on the sheet.
Back to top
View user's profile Send private message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Mon Feb 23, 2004 11:38 am    Post subject: Reply with quote

If I may....

The style I use is a function to make the main code shorter, but without omitting any details....

Code:
Sub Macro1
   oDoc=Thiscomponent   'The document running the macro

   oSheet=oDoc.Sheets(0)
   ' 0=first sheet;  0=Col A;  0=Row 1;  2=Col C;  9=Row 10
   oSheet.setprintareas( MakeCellRangeAddress( 0, 0, 0, 2, 9 ) )  ' set the print area on the sheet

   oSheet=oDoc.Sheets(1) 'second sheet
   ' 1=second sheet;  0=Col A;  0=Row 1;  2=Col C;  9=Row 10
   oSheet.setprintareas( MakeCellRangeAddress( 1, 0, 0, 2, 9 ) )  ' set the print area on the sheet

   ' assuming that print only selected sheets is off this will print all sheets with selected areas in them
   oDoc.Print(Array())  ' print to default printer
End Sub



But you need this subroutine....
Code:
Function MakeCellRangeAddress( nSheetIndex, nStartColumn, nStartRow, nEndColumn, nEndRow ) As com.sun.star.table.CellRangeAddress
   oCellRangeAddress = createUnoStruct( "com.sun.star.table.CellRangeAddress" )
   With oCellRangeAddress
      .Sheet = nSheetIndex
      .StartColumn = nStartColumn
      .StartRow = nStartRow
      .EndColumn = nEndColumn
      .EndRow = nEndRow
   End With
   MakeCellRangeAddress() = oCellRangeAddress
End Function

_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
Francesco
Guest





PostPosted: Mon Feb 23, 2004 1:07 pm    Post subject: Reply with quote

Hi DanniB

I looked at my macro more carefully. Actually it is not for printing a "range", but for printing a "print area", defined in the macro itslelf. When I copied your macro in my program, it worked because the print area previously selected and printed, had not been removed. The illusion vanished when I tried more seriously.

Macros with range selection, yours too, actually don't work.

So now my problem is: how can I select a print area and print it from a macro, without switching the active sheet?

Should you still be interest in the code of the "working" macro, here's to you.

Regards

Francesco


=================================
Sub StampaFoglio
dim document as object
dim dispatcher as object
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dispatcher.executeDispatch(document, ".uno:DeletePrintArea", "", 0, Array())
dim args2(0) as new com.sun.star.beans.PropertyValue
args2(0).Name = "ToPoint"
args2(0).Value = "'Sheet1'.$A$1:$C$5"
dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args2())
dispatcher.executeDispatch(document, ".uno:DefinePrintArea", "", 0, Array())
dim args4(2) as new com.sun.star.beans.PropertyValue
args4(0).Name = "Copies"
args4(0).Value = 1
args4(1).Name = "RangeText"
args4(1).Value = "1"
args4(2).Name = "Collate"
args4(2).Value = false
dispatcher.executeDispatch(document, ".uno:Print", "", 0, args4())
Wait 150
dispatcher.executeDispatch(document, ".uno:DeletePrintArea", "", 0, Array())
End Sub
Back to top
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Mon Feb 23, 2004 1:27 pm    Post subject: Reply with quote

Francesco wrote:
I looked at my macro more carefully. Actually it is not for printing a "range", but for printing a "print area", defined in the macro itslelf. When I copied your macro in my program, it worked because the print area previously selected and printed, had not been removed. The illusion vanished when I tried more seriously.


Okay, great. And dfrench's answer makes sense. Explains why I could not get it to work.

I was puzzled by why you could get it to work. I don't like mysteries -- in programming. Computers are supposed to be deterministic.

Your explanation above is very satisfying as to what is going on.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
dfrench
Moderator
Moderator


Joined: 03 Mar 2003
Posts: 1605
Location: Wellington, New Zealand

PostPosted: Mon Feb 23, 2004 3:03 pm    Post subject: Reply with quote

Quote:
how can I select a print area and print it from a macro, without switching the active sheet


My macro does not concern itself with the active sheet at all (provided that the print option Print Only Selected Sheets is turned off).
From your experiences with setting printareas, it might be sensible to follow the print with setting the printareas to null on each page.
Code:
oSheet.setprintareas(array())
Back to top
View user's profile Send private message
Francesco
Guest





PostPosted: Thu Feb 26, 2004 8:41 am    Post subject: Reply with quote

Thanks, to both.

I am here again, just one more little help: how can I switch on and off (from a macro) the "Print only selected sheets" option?

TIA

Francesco
Back to top
Guest






PostPosted: Thu Feb 26, 2004 9:48 am    Post subject: Reply with quote

Sorry, one more thing

The code received from DannyB, actually prints all contents of all sheets of the open document (with "Print only selected sheet" off).

The code received from dfrench seems to work, but, I' prefer to select sheet by name and not by index. Is it possible?

Moreover, I must be sure "Print only selected sheet" is off when the macro starts, The only way to get this, is to set it off by another macro. How can I get that? The document will run on many machines, and I do not know how OOO will be configured on each of them.

Regards

Francesco
[/quote]
Back to top
Guest






PostPosted: Thu Feb 26, 2004 10:42 am    Post subject: Reply with quote

I have found out how to get sheets by name, here is the code.

Still I need how to set "Print only selected sheet" off/on


Waiting

Francesco

==========================
Sub PrintAreas
dim selectedareas(0) as new com.sun.star.table.CellRangeAddress
Dim oDoc as object
Dim oSheet as object

oDoc=Thiscomponent 'The document running the macro

oSheet=ThisComponent.Sheets.getByName("Sheet1")
'selectedareas(0).sheet=0 'first sheet
selectedareas(0).startcolumn=0 'Col A
selectedareas(0).startrow=0 ' Row 1 (zero based index)
selectedareas(0).endcolumn=2 ' Col C
selectedareas(0).endrow=9 ' Row 10
'oSheet=oDoc.Sheets(0)
oSheet=ThisComponent.Sheets.getByName("Sheet1")
oSheet.setprintareas(selectedareas()) ' set the print area on the sheet

oShhet=ThisComponent.Sheets.getByName("Sheet2")
'selectedareas(0).sheet=1 'second sheet
selectedareas(0).startcolumn=0 'Col A
selectedareas(0).startrow=0 ' Row 1 (zero based index)
selectedareas(0).endcolumn=2 ' Col C
selectedareas(0).endrow=9 ' Row 10
'oSheet=oDoc.Sheets(1)
oSheet=ThisComponent.Sheets.getByName("Sheet2")
oSheet.setprintareas(selectedareas()) ' set the print area on the sheet
oDoc.Print(Array()) ' print to default printer

'REMOVE PRINT AREAS

oSheet.setprintareas(array())
oSheet=ThisComponent.Sheets.getByName("Sheet1")
oSheet.setprintareas(array())
oSheet=ThisComponent.Sheets.getByName("Sheet2")
oSheet.setprintareas(selectedareas())
oSheet.setprintareas(array())
End Sub
Back to top
dfrench
Moderator
Moderator


Joined: 03 Mar 2003
Posts: 1605
Location: Wellington, New Zealand

PostPosted: Thu Feb 26, 2004 11:32 am    Post subject: Reply with quote

Quote:
Still I need how to set "Print only selected sheet" off/on

This does not appear to be exposed in the api.
Can't see anyway to do it with dispatching UNO either.
As an alternative, I looked for a way to select multiple sheets in a macro (no joy there either!)
Try asking on the openoffice developers mailing list.


In the meantime, I suggest that you deal with each sheet with printareas separately in your macro. You may need to wait briefly between print() requests.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API All times are GMT - 8 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group