[Solved] Printing: tray selection worked, but not anymore

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
zenlord
Posts: 51
Joined: Tue Dec 22, 2009 5:50 pm

[Solved] Printing: tray selection worked, but not anymore

Post by zenlord »

Hi,

I have recently reworked my printing macro's and added some functionality - they are in the code snippet section of this forum. The whole reason to start using printing macro's in our office was that we needed to be able to print from several input trays (pre-printed stationary while being able to send out PDF-versions with the background in place).

This has worked some time, until I decided to upgrade OOo 3.2 (I think) to LO 3.4 - we were switching to a new corporate style and our new font was not working with OOo. At that time, printer tray selection became unstable: printing page 1 and page 2 to two separate trays was not possible: the tray that was selected for the first page, was also used for every next page.

I filed bug reports and saw that I was not alone: LO 3.3 and 3.4 was flawed when printing in linux. I upgraded to LO 3.5.2 and at that time I solved a little bug in my own macro's and VOILA: tray selection worked once again.

This week I have put much effort in expanding my macro's to be able to print to more than one hardcoded printer and adding errorHandling, only to find out that the tray selection has gone south once again. Beneath is the code to all macro's. I have tested with 'Fax_close' which calls 'print_stat_first' which calls 'printPage' for the first page and 'print_stat_rest' > 'printPage' for all other pages.

Can anyone please shed a light on this? I have added a MsgBox inside the macro's and they show me that the command to print to the tray is being executed correct (or at least that the variable 'iPageNr' and 'sTray' are holding the right content.

Code: Select all

REM ** VERSIONING **
'Version 2.0 (11 okt 2012)
'Added simple ErrorHandler and rewrote comments

REM  *****  BASIC  *****

Sub Main
	REM Set backgroundImage-option in DocumentSettings to True
	DIM oDoc, oSettings AS Object
	oSettings = oDoc.createInstance("com.sun.star.text.DocumentSettings")
	oSettings.PrintPageBackground = TRUE
End Sub


REM ** GENERAL HELPERS **

' ------------------------------
' This macro closes the current document
'
' Written by Andrew Pitonyak (2010)
' Adapted by Vincent Van Houtte (2011)
' ------------------------------
Sub closeDocument(oDoc AS Object)
	REM Check if the document exists
	If IsNull(oDoc) Then
		Exit Sub
	End If

	REM Store the document if it was modified
	If (oDoc.isModified) Then
	  If (oDoc.hasLocation AND (Not oDoc.isReadOnly)) Then
	    oDoc.store()
	  Else
	    oDoc.setModified(False)
	  End If
	End If

	REM Close the document
	oDoc.close(true)
End Sub

' ------------------------------
' Written by Andrew Pitonyak the Great
' Used in the Date-time-functions
' ------------------------------
Function FindCreateNumberFormatStyle ( sFormat As String, Optional doc, Optional locale)
	Dim oDoc As Object
	Dim aLocale As New com.sun.star.lang.Locale
	Dim oFormats As Object
	Dim formatNum As Integer
	oDoc = IIf(IsMissing(doc), ThisComponent, doc)
	oFormats = oDoc.getNumberFormats()
	'If you choose to query on types, you need to use the type
	'com.sun.star.util.NumberFormat.DATE
	'I could set the locale from values stored at
	'http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
	'http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
	'I use a NULL locale and let it use whatever it likes.
	'First, see if the number format exists
	If ( Not IsMissing(locale)) Then
	aLocale = locale
	End If
	formatNum = oFormats.queryKey (sFormat, aLocale, TRUE)
	'MsgBox "Current Format number is" & formatNum
	'If the number format does not exist then add it
	If (formatNum = -1) Then
	formatNum = oFormats.addNew(sFormat, aLocale)
	If (formatNum = -1) Then formatNum = 0
	'   MsgBox "new Format number is " & formatNum
	End If
	FindCreateNumberFormatStyle = formatNum
End Function


REM ** HELPER MACRO'S TO INSERT / REMOVE A DATESTAMP**

' ------------------------------
' This macro inserts a 'DATE/TIME'-stamp with sActionText
' like 'Printed' or 'Sent'
'
' Written by Vincent Van Houtte (2011)
' ------------------------------
Sub InsertDTstampFirstPage(sActionText)
	DIM oCursor, oText, oDoc AS Object
	oDoc = ThisComponent
	oText = oDoc.getText()
	oCursor = oText.createTextCursor()
	oCursor.goToStart(FALSE)

	REM Create the date and time objects
	DIM oDate, oTime AS Object
	oDate = oDoc.createInstance("com.sun.star.text.TextField.DateTime")
	oDate.IsFixed = TRUE
	oDate.IsDate = TRUE
	oDate.NumberFormat = FindCreateNumberFormatStyle("D MMMM JJJJ", oDoc)
	
	oTime = oDoc.createInstance("com.sun.star.text.TextField.DateTime")
	oTime.IsFixed = True
	oTime.IsDate = False
	oTime.NumberFormat = FindCreateNumberFormatStyle("UU:MM", oDoc)

	REM Create the frame
	DIM oFrameDT AS Object
	oFrameDT = oDoc.createInstance("com.sun.star.text.TextFrame")
	With oFrameDT
	.setName("FrameDT")
	.AnchorType = com.sun.star.text.TextContentAnchorType.AT_PAGE
	.HoriOrient = com.sun.star.text.HoriOrientation.NONE
	.VertOrient = com.sun.star.text.VertOrientation.NONE
	.HoriOrientPosition = -4200
	.VertOrientPosition = -4000
	.width = 4000
	.height = 1500
	.BorderDistance = 100
	End With

	REM Insert the frame into the text document
	oText.insertTextContent( oCursor, oFrameDT, True )

	REM Write the text inside the frame
	DIM oCursor2 AS Object
	oCursor2 = oFrameDT.createTextCursor()
	With oCursor2
	.charHeight = 13
	.charWeight = com.sun.star.awt.FontWeight.BOLD
	.paraAdjust = com.sun.star.style.ParagraphAdjust.CENTER
	End With

	oFrameDT.insertString( oCursor2, sActionText, False )

	With oCursor2
	.charHeight = 9
	.charWeight = com.sun.star.awt.FontWeight.NORMAL
	.paraAdjust = com.sun.star.style.ParagraphAdjust.CENTER
	End With

	oFrameDT.insertControlCharacter( oCursor2, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False )
	oFrameDT.insertTextContent( oCursor2, oDate, False )

	oFrameDT.insertControlCharacter( oCursor2, com.sun.star.text.ControlCharacter.LINE_BREAK, False )
	oFrameDT.insertTextContent( oCursor2, oTime, False )
End Sub


' ------------------------------
' This macro inserts a 'DATE/TIME'-stamp with sActionText
' like 'Printed', 'Copy', 'Books' or 'Sent'
'
' Written by Vincent Van Houtte (2012)
' ------------------------------
Sub InsertDTstampLastPage(sActionText)
	DIM oCursor, oText, oDoc AS Object
	oDoc = ThisComponent
	oText = oDoc.getText()
	oCursor = oText.createTextCursor()
	oCursor.goToEnd(FALSE)

	REM Create the date and time objects
	DIM oDate, oTime AS Object
	oDate = oDoc.createInstance("com.sun.star.text.TextField.DateTime")
	oDate.IsFixed = TRUE
	oDate.IsDate = TRUE
	oDate.NumberFormat = FindCreateNumberFormatStyle("D MMMM JJJJ", oDoc)
	
	oTime = oDoc.createInstance("com.sun.star.text.TextField.DateTime")
	oTime.IsFixed = True
	oTime.IsDate = False
	oTime.NumberFormat = FindCreateNumberFormatStyle("UU:MM", oDoc)

	REM Create the frame
	DIM oFrameDT AS Object
	oFrameDT = oDoc.createInstance("com.sun.star.text.TextFrame")
	With oFrameDT
	.setName("FrameDT")
	.AnchorType = com.sun.star.text.TextContentAnchorType.AT_PAGE
	.HoriOrient = com.sun.star.text.HoriOrientation.NONE
	.VertOrient = com.sun.star.text.VertOrientation.NONE
	.HoriOrientPosition = -4200
	.VertOrientPosition = -2500
	.width = 4000
	.height = 1500
	.BorderDistance = 100
	End With

	REM Insert the frame into the text document
	oText.insertTextContent( oCursor, oFrameDT, True )

	REM Write the text inside the frame
	DIM oCursor2 AS Object
	oCursor2 = oFrameDT.createTextCursor()
	With oCursor2
	.charHeight = 13
	.charWeight = com.sun.star.awt.FontWeight.BOLD
	.paraAdjust = com.sun.star.style.ParagraphAdjust.CENTER
	End With

	oFrameDT.insertString( oCursor2, sActionText, False )

	With oCursor2
	.charHeight = 9
	.charWeight = com.sun.star.awt.FontWeight.NORMAL
	.paraAdjust = com.sun.star.style.ParagraphAdjust.CENTER
	End With

	oFrameDT.insertControlCharacter( oCursor2, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False )
	oFrameDT.insertTextContent( oCursor2, oDate, False )

	oFrameDT.insertControlCharacter( oCursor2, com.sun.star.text.ControlCharacter.LINE_BREAK, False )
	oFrameDT.insertTextContent( oCursor2, oTime, False )
End Sub



' ------------------------------
' This macro removes the 'DATE/TIME'-stamp created with
' the previous macro
'
' Written by Vincent Van Houtte (2011)
' ------------------------------
Sub RemoveDTstamp()
	DIM oDoc, oTextFrames, oFrameDT AS Object
	oDoc = ThisComponent

	REM Look for the datetimestamp-frame and remove it
	oTextFrames = oDoc.getTextFrames
	If oTextFrames.hasByName("FrameDT") Then
		oFrameDT = oTextFrames.getByName("FrameDT")
		oFrameDT.dispose()
	EndIf
End Sub


REM ** HELPER PRINTING FUNCTIONS **

' ------------------------------
' This macro shows a dialog with a list of all installed printers on your system.
' Ideally, the dialog closes after a selection has been made
'
' Written by Vincent Van Houtte (2012)
' ------------------------------
Function ShowListPrinters
	DIM aPrinterNames

	REM Initiate Errorhandler
	On error GoTo ErrorHandler

	aPrinterNames = GetAllPrinterNames()

	DialogLibraries.loadLibrary("Standard")
	d = CreateUnoDialog(DialogLibraries.Standard.dlgListPrinters)
		d.setTitle("Selecteer printer")
		l = d.getControl("ListPrinters")
		l.getModel().StringItemList = aPrinterNames
		l.selectItemPos( 0, true )
	d.execute()
		list = d.getModel().getByName("ListPrinters")
		result = list.StringItemList(list.SelectedItems(0))
	d.dispose()
	ShowListPrinters = result

'ErrorHandler
Exit Function
	ErrorHandler:
	Reset
	MsgBox "Error " & Err & ": " & Error$ + chr(13) + "At line : " + Erl + chr(13) + Now , 16 ,"an error occurred" 
End Function


' ------------------------------
' This macro returns an array with a list of all installed printers. It is possible
' that it doesn't work on older (pre OOo3.5) versions of OOo / LO
'
' Written by Niklas Nebel (cited by Andrew Pitonyak)
' Adapted very slightly by Vincent Van Houtte (2012)
' ------------------------------
Function GetAllPrinterNames()
	DIM oPrintServer ' The print server service.
	DIM oCore        ' Get classes and other objects by name.
	DIM oClass       ' XPrinterServer class object.
	DIM oMethod      ' getPrinterNames method from the XPrinterServer class.

	REM Initiate Errorhandler
	On error GoTo ErrorHandler

	' Create the object that will not be directly usable until OOo 3.5.
	oPrintServer = CreateUnoService("com.sun.star.awt.PrinterServer")
	oCore = CreateUnoService("com.sun.star.reflection.CoreReflection")

	' Get the class object for the XPrinterServer interface.
	oClass = oCore.forName("com.sun.star.awt.XPrinterServer")

	' Get the getPrinterNames method for the XPrinterServer class.
	oMethod = oClass.getMethod("getPrinterNames")

	' Call the getPrinterNames method on the PrinterServer object.
	GetAllPrinterNames = oMethod.invoke(oPrintServer, Array())

'ErrorHandler
Exit Function
	ErrorHandler:
	Reset
	MsgBox "Error " & Err & ": " & Error$ + chr(13) + "At line : " + Erl + chr(13) + Now , 16 ,"an error occurred" 
End Function 


REM ** HELPER PRINTING MACRO'S **

' ------------------------------
' This macro prints a given page without the background(-image) to the
' papertray holding the pre-printed (first-page-)stationary:
' you can set an image as a background, that you don't want to print,
' but that you want to show up when converted to PDF.
'
' Written by Vincent Van Houtte (2011)
' ------------------------------
Sub Print_stat_first(iPageNr, sPrinter)
	DIM sTray AS String
	DIM bBg AS Boolean
	sTray = "Tray2"
	bBg = False
	printPage(sTray, bBg, iPageNr, sPrinter)
End Sub


' ------------------------------
' This macro prints a given page without the background(-image) to the
' papertray holding the pre-printed (other-page-)stationary:
' you can set an image as a background, that you don't want to print,
' but that you want to show up when converted to PDF.
'
' Written by Vincent Van Houtte (2011)
' ------------------------------
Sub Print_stat_rest(iPageNr, sPrinter)
	DIM sTray AS String
	DIM bBg AS Boolean
	sTray = "Tray1"
	bBg = False
	printPage(sTray, bBg, iPageNr, sPrinter)
End Sub


' ------------------------------
' This macro prints a given page without the background(-image) to the
' papertray holding plain paper, for example to keep in your own file
'
' Written by Vincent Van Houtte (2011)
' ------------------------------
Sub Print_plain(iPageNr, sPrinter)
	DIM sTray AS String
	DIM bBg AS Boolean
	sTray = "Tray1"
	bBg = False
	printPage(sTray, bBg, iPageNr, sPrinter)
End Sub


' ------------------------------
' This macro prints a given page with the background(-image) to the
' papertray holding plain paper, for example to keep in your official books
'
' Written by Vincent Van Houtte (2012)
' ------------------------------
Sub Print_plain_with_background(iPageNr, sPrinter)
	DIM sTray AS String
	DIM bBg AS Boolean
	sTray = "Tray1"
	bBg = True
	printPage(sTray, bBg, iPageNr, sPrinter)
End Sub


' ------------------------------
' This macro prints a specified page given the chosen parameters
'
' Written by Vincent Van Houtte (2010)
' ------------------------------
Sub printPage(sTray, bBg, sPageNr AS String, sPrinter)
	DIM oDoc AS Object
	oDoc = ThisComponent

	REM Initiate Errorhandler
	On error GoTo ErrorHandler

	REM Set backgroundImage-option in DocumentSettings to False
	DIM oSettings AS Object
	oSettings = oDoc.createInstance("com.sun.star.text.DocumentSettings")
	oSettings.PrintPageBackground = bBg

	REM Set the chosen printer
	DIM mPrinterOpts(2) AS NEW com.sun.star.beans.PropertyValue
	mPrinterOpts(0).Name = "Name"
	'mPrinterOpts(0).Value = "MFC8880DN"
	mPrinterOpts(0).Value = sPrinter
	mPrinterOpts(1).Name = "PaperFormat"
	mPrinterOpts(1).Value = com.sun.star.view.PaperFormat.A4
	mPrinterOpts(2).Name = "PaperOrientation"
	mPrinterOpts(2).Value = com.sun.star.view.PaperOrientation.PORTRAIT
	oDoc.Printer = mPrinterOpts()

	REM set Papertray in Styles
	DIM oStyle, oViewCursor, oPageStyleName, oPageStyles AS Object
	DIM iPageNr AS Integer
	iPageNr = sPageNr
	oViewCursor = oDoc.CurrentController.getViewCursor()
	oViewCursor.JumpToPage(iPageNr, false) 
	oPageStyleName = oViewCursor.PageStyleName
	oPageStyles = oDoc.StyleFamilies.getByName("PageStyles")
	oStyle = oPageStyles.getByName(oPageStyleName)
	'If the printer has but one tray, comment the next line out:
	oStyle.PrinterPaperTray = sTray

	REM Set printOptions
	DIM mPrintOpts(3) AS NEW com.sun.star.beans.PropertyValue
	mPrintOpts(0).Name = "CopyCount"
	mPrintOpts(0).Value = 1
	mPrintOpts(1).Name = "Collate"
	mPrintOpts(1).Value = True
	mPrintOpts(2).Name = "Pages"
	mPrintOpts(2).Value = sPageNr
	mPrintOpts(3).Name = "Wait"
	mPrintOpts(3).Value = True

	REM Print
	oDoc.Print(mPrintOpts())

	REM RESET OPTIONS
	REM Set backgroundImage-option in DocumentSettings to True
	oSettings = oDoc.createInstance("com.sun.star.text.DocumentSettings")
	oSettings.PrintPageBackground = True

'ErrorHandler
Exit Sub
	ErrorHandler:
	Reset
	MsgBox "Error " & Err & ": " & Error$ + chr(13) + "At line : " + Erl + chr(13) + Now , 16 ,"an error occurred" 
End Sub


' ------------------------------
' This macro prints the complete document given the chosen parameters
'
' Written by Vincent Van Houtte (2010)
' ------------------------------
Sub printDoc(sTray, bBg, sPrinter)
	DIM oDoc AS Object
	oDoc = ThisComponent

	REM Initiate Errorhandler
	On error GoTo ErrorHandler

	REM Set backgroundImage-option in DocumentSettings to False
	DIM oSettings AS Object
	oSettings = oDoc.createInstance("com.sun.star.text.DocumentSettings")
	oSettings.PrintPageBackground = bBg

	REM Set the chosen printer
	DIM mPrinterOpts(2) AS NEW com.sun.star.beans.PropertyValue
	mPrinterOpts(0).Name = "Name"
	'mPrinterOpts(0).Value = "MFC8880DN"
	mPrinterOpts(0).Value = sPrinter
	mPrinterOpts(1).Name = "PaperFormat"
	mPrinterOpts(1).Value = com.sun.star.view.PaperFormat.A4
	mPrinterOpts(2).Name = "PaperOrientation"
	mPrinterOpts(2).Value = com.sun.star.view.PaperOrientation.PORTRAIT
	oDoc.Printer = mPrinterOpts()

	REM set Papertray in Styles
	DIM oStyle, oViewCursor, oPageStyleName, oPageStyles AS Object
	DIM iPageNr AS Integer
	iPageNr = sPageNr
	oViewCursor = oDoc.CurrentController.getViewCursor()
	oViewCursor.JumpToPage(iPageNr, false) 
	oPageStyleName = oViewCursor.PageStyleName
	oPageStyles = oDoc.StyleFamilies.getByName("PageStyles")
	oStyle = oPageStyles.getByName(oPageStyleName)
	'If the printer has but one tray, comment the next line out:
	oStyle.PrinterPaperTray = sTray

	REM Set printOptions
	DIM mPrintOpts(2) AS NEW com.sun.star.beans.PropertyValue
	mPrintOpts(0).Name = "CopyCount"
	mPrintOpts(0).Value = 1
	mPrintOpts(1).Name = "Collate"
	mPrintOpts(1).Value = True
	mPrintOpts(2).Name = "Wait"
	mPrintOpts(2).Value = True

	REM Print
	oDoc.Print(mPrintOpts())

	REM RESET OPTIONS
	REM Set backgroundImage-option in DocumentSettings to True
	oSettings = oDoc.createInstance("com.sun.star.text.DocumentSettings")
	oSettings.PrintPageBackground = True

'ErrorHandler
Exit Sub
	ErrorHandler:
	Reset
	MsgBox "Error " & Err & ": " & Error$ + chr(13) + "At line : " + Erl + chr(13) + Now , 16 ,"an error occurred" 
End Sub



REM ** PRINTING MACRO'S ASSIGNED TO BUTTONS**

' ------------------------------
' This macro prints the document once to stationary and exits
'
' Written by Vincent Van Houtte (2011)
' ------------------------------
Sub Fax_close()
	DIM oDoc, oCursor, oText AS Object
	DIM iPageCount, n AS Integer
	DIM sPage AS String
	DIM sPrinter AS String

	REM Initiate Errorhandler
	On error GoTo ErrorHandler

	sPrinter= ShowListPrinters()
	oDoc	= ThisComponent

	REM I don't know why the next 3 lines are here - probably leftovers from a precious version
	'oText	= oDoc.getText()
	'oCursor	= oText.createTextCursor()
	'oCursor.goToStart(FALSE)

	REM Count the amount of pages
	iPageCount = oDoc.getCurrentController().getPropertyValue("PageCount")

'Print stat
	REM Print the first page
	Print_stat_first(1, sPrinter)

	REM Loop over every next page and print it
	n = 2
	While n <= iPageCount
		Print_stat_rest(n, sPrinter)
		n = n + 1
	Wend

'Exit
	REM Save and close the document
	closeDocument(oDoc)

'ErrorHandler
Exit Sub
	ErrorHandler:
	Reset
	MsgBox "Error " & Err & ": " & Error$ + chr(13) + "At line : " + Erl + chr(13) + Now , 16 ,"an error occurred" 
End Sub


' ------------------------------
' This macro prints a copy of the document, sends the 
' document to the default email app as a PDF and exits
'
' Written by Vincent Van Houtte (2011)
' ------------------------------
Sub Mail_close()
	DIM oDoc, oCursor, oText AS Object
	DIM iPageCount, n AS Integer
	DIM sPage AS String
	DIM sPrinter AS String

	REM Initiate Errorhandler
	On error GoTo ErrorHandler

	sPrinter= ShowListPrinters()
	oDoc	= ThisComponent

	REM Count the amount of pages
	iPageCount = oDoc.getCurrentController().getPropertyValue("PageCount")

'Print copy
	REM Insert timestamp of sending
	Dim sActionText AS String
	sActionText = "VERZONDEN"
	InsertDTstampFirstPage(sActionText)

	REM Print the page
	REM Loop over every page
	n = 1
	Do Until n > iPageCount
		Print_plain(n, sPrinter)
		n = n + 1
	Loop

	REM Remove the copystamp-frame
	RemoveDTstamp()

'Create PDF
	REM Replace .odt with .pdf
	DIM sDocURL, sPDFURL AS String
	sDocURL = oDoc.getURL()
	sPDFURL = Left$(sDocURL,Len(sDocURL)-4) + ".pdf"

	REM Save as PDF
	DIM args(0) AS NEW com.sun.star.beans.PropertyValue
	args(0).Name = "FilterName"
	args(0).Value = "writer_pdf_Export"
	oDoc.storeToURL(sPDFURL,args())

'Send to mailapp
	REM Get the values of the textfields inside the document to form the subject line
	DIM enuTF, aTextField AS Object
	DIM sDosName, sDosNum, sDosUref, sTo, sSubject AS String
	enuTF = oDoc.TextFields.createEnumeration
		Do While enuTF.hasMoreElements
		aTextField = enuTF.nextElement
			if aTextField.supportsService("com.sun.star.text.TextField.Input") then
				Select Case aTextField.getPropertyValue("Hint")
					Case "briefBetreft":
						sDosName = aTextField.getPropertyValue("Content")
					Case "briefOnzeReferte":
						sDosNum = aTextField.getPropertyValue("Content")
					Case "briefUwReferte":
						sDosUref = aTextField.getPropertyValue("Content")
					Case "verzendingsadres":
						sTo = aTextField.getPropertyValue("Content")
				End Select
			end if
		Loop
	sSubject = sDosName + " - " + sDosUref + " - " + sDosNum

	REM Send the PDF as an attachment
	DIM MailClient, MailAgent, MailMessage AS Object
	'On linux systems, use SimpleCommandMail
	MailAgent = CreateUnoService("com.sun.star.system.SimpleCommandMail")
	'On windows systems, use SimpleSystemMail
	'MailAgent = CreateUnoService("com.sun.star.system.SimpleSystemMail")
	MailClient = MailAgent.querySimpleMailClient()
		MailMessage=MailClient.createSimpleMailMessage()
		MailMessage.setRecipient(sTo)
		MailMessage.setSubject(sSubject)
		MailMessage.setAttachement(array(sPDFURL))
	MailClient.sendSimpleMailMessage(MailMessage, 0)

'Exit
	REM Save and close the document
	closeDocument(oDoc)

'ErrorHandler
Exit Sub
	ErrorHandler:
	Reset
	MsgBox "Error " & Err & ": " & Error$ + chr(13) + "At line : " + Erl + chr(13) + Now , 16 ,"an error occurred" 
End Sub

Sub Letter_close()
' ------------------------------
' This macro prints the document once to stationary, once as a copy and exits
'
' Written by Vincent Van Houtte (2011)
' ------------------------------
	DIM oDoc, oCursor, oText AS Object
	DIM iPageCount, n AS Integer
	DIM sPage AS String
	DIM sPrinter AS String

	REM Initiate Errorhandler
	On error GoTo ErrorHandler

	sPrinter= ShowListPrinters()
	oDoc	= ThisComponent

	REM Count the amount of pages
	iPageCount = oDoc.getCurrentController().getPropertyValue("PageCount")

'Print stat
	REM Print the first page
	Print_stat_first(1, sPrinter)

	REM Loop over every next page and print it
	n = 2
	While n <= iPageCount
		Print_stat_rest(n, sPrinter)
		n = n + 1
	Wend

'Print copy
	REM Insert timestamp of sending
	Dim sActionText AS String
	sActionText = "KOPIE"
	InsertDTstampFirstPage(sActionText)

	REM Print the page
	REM Loop over every page
	n = 1
	Do Until n > iPageCount
		Print_plain(n, sPrinter)
		n = n + 1
	Loop
	
	REM Remove the copystamp-frame
	RemoveDTstamp()

'Exit
	REM Save and close the document
	closeDocument(oDoc)

'ErrorHandler
Exit Sub
	ErrorHandler:
	Reset
	MsgBox "Error " & Err & ": " & Error$ + chr(13) + "At line : " + Erl + chr(13) + Now , 16 ,"an error occurred" 
End Sub

Sub Letter_recommended_close()
' ------------------------------
' This macro prints the document twice to stationary, once as a copy and exits
'
' Written by Vincent Van Houtte (2011)
' ------------------------------
	DIM oDoc, oCursor, oText AS Object
	DIM iPageCount, n AS Integer
	DIM sPage AS String
	DIM sPrinter AS String

	REM Initiate Errorhandler
	On error GoTo ErrorHandler

	sPrinter= ShowListPrinters()
	oDoc	= ThisComponent

	REM Count the amount of pages
	iPageCount = oDoc.getCurrentController().getPropertyValue("PageCount")

'Print stat
	REM Print the first page
	Print_stat_first(1, sPrinter)

	REM Loop over every next page and print it
	n = 2
	While n <= iPageCount
		Print_stat_rest(n, sPrinter)
		n = n + 1
	Wend

'Print stat second
	REM Print the first page
	Print_stat_first(1, sPrinter)

	REM Loop over every next page and print it
	n = 2
	While n <= iPageCount
		Print_stat_rest(n, sPrinter)
		n = n + 1
	Wend

'Print copy
	REM Insert timestamp of sending
	Dim sActionText AS String
	sActionText = "AANGETEKEND"
	InsertDTstampFirstPage(sActionText)

	REM Print the page
	REM Loop over every page
	n = 1
	Do Until n > iPageCount
		Print_plain(n, sPrinter)
		n = n + 1
	Loop
	
	REM Remove the copystamp-frame
	RemoveDTstamp()

'Exit
	REM Save and close the document
	closeDocument(oDoc)

'ErrorHandler
Exit Sub
	ErrorHandler:
	Reset
	MsgBox "Error " & Err & ": " & Error$ + chr(13) + "At line : " + Erl + chr(13) + Now , 16 ,"an error occurred" 
End Sub


' ------------------------------
' This macro prints a copy of the document, and makes a 
' PDF-doc with copy-stamp
'
' Written by Vincent Van Houtte (2011)
' ------------------------------
Sub Print_copy()
	DIM oDoc, oCursor, oText AS Object
	DIM iPageCount, n AS Integer
	DIM sPage AS String
	DIM sPrinter AS String

	REM Initiate Errorhandler
	On error GoTo ErrorHandler

	sPrinter= ShowListPrinters()
	oDoc	= ThisComponent

	REM Count the amount of pages
	iPageCount = oDoc.getCurrentController().getPropertyValue("PageCount")

'Print copy
	REM Insert timestamp of sending
	Dim sActionText AS String
	sActionText = "KOPIE"
	InsertDTstampFirstPage(sActionText)

	REM Print the page
	REM Loop over every page
	n = 1
	Do Until n > iPageCount
		Print_plain(n, sPrinter)
		n = n + 1
	Loop

'Create PDF
	REM Replace .odt with _cp.pdf
	DIM sDocURL, sPDFURL AS String
	sDocURL = oDoc.getURL()
	sPDFURL = Left$(sDocURL,Len(sDocURL)-4) + "_cp.pdf"

	REM Save as PDF
	DIM args(0) AS NEW com.sun.star.beans.PropertyValue
	args(0).Name = "FilterName"
	args(0).Value = "writer_pdf_Export"
	oDoc.storeToURL(sPDFURL,args())

	REM Remove the copystamp-frame
	RemoveDTstamp()

'ErrorHandler
Exit Sub
	ErrorHandler:
	Reset
	MsgBox "Error " & Err & ": " & Error$ + chr(13) + "At line : " + Erl + chr(13) + Now , 16 ,"an error occurred" 
End Sub
P.S. Simply reverting to the older set of macro's seems not to work - so I'm thinking this might not be related to OOo/LO at all. If anyone can help me test this, I would be very grateful...
Last edited by zenlord on Mon Oct 15, 2012 12:11 pm, edited 1 time in total.
LibreOffice 4.1 on Linux (Debian Wheezy backports)
B Marcelly
Volunteer
Posts: 1160
Joined: Mon Oct 08, 2007 1:26 am
Location: France, Paris area

Re: [BASIC] printing: tray selection worked, but not anymore

Post by B Marcelly »

Hi,
Of course I just had a glimpse at the code...

You should have added at top of the module :

Code: Select all

Option Explicit
This will find undeclared variables. Like in Sub printDoc : sPageNr is not declared, so Basic declares it as Variant, defaulted to empty, and iPageNr then is set to zero. Maybe it's what you want...

You did the common mistake :

Code: Select all

Sub printPage(sTray, bBg, sPageNr AS String, sPrinter)
This is interpreted by Basic as :

Code: Select all

Sub printPage(sTray As Variant, bBg As Variant, sPageNr AS String, sPrinter As Variant)
But what you mean is :

Code: Select all

Sub printPage(sTray As String, bBg As Boolean, sPageNr AS String, sPrinter As Variant)
This error may cause very strange problems if the argument is modified in the routine. Anyway, it is more clear to specify the data type of each variable.
Same error in your Dim declarations :

Code: Select all

DIM sDosName, sDosNum, sDosUref, sTo, sSubject AS String
' should be :
DIM sDosName As String, sDosNum As String, sDosUref As String, sTo As String, sSubject As String
For variables containing an API object, I prefer to declare them As Object, not Variant, because Basic has a little more controls than with Variant.

These codes work, but are more complex than needed :

Code: Select all

       REM Loop over every page
       n = 1
       Do Until n > iPageCount
          Print_plain(n, sPrinter)
          n = n + 1
       Loop
' ________ 

       REM Loop over every next page and print it
       n = 2
       While n <= iPageCount
          Print_stat_rest(n, sPrinter)
          n = n + 1
       Wend
Simpler is better :

Code: Select all

For n = 1 to iPageCount
  Print_plain(n, sPrinter)
next
' _______________

For n = 2 to iPageCount
  Print_plain(n, sPrinter)
next
Bernard

OpenOffice.org 1.1.5 / Apache OpenOffice 4.1.1 / LibreOffice 5.0.5
MS-Windows 7 Home SP1
zenlord
Posts: 51
Joined: Tue Dec 22, 2009 5:50 pm

Re: [BASIC] printing: tray selection worked, but not anymore

Post by zenlord »

Thank you very much! I will test your suggestions immediately - I have a problem with the code that the printerpapertray is not always set correctly - it might be caused by the missing declarations...

Vincent
LibreOffice 4.1 on Linux (Debian Wheezy backports)
zenlord
Posts: 51
Joined: Tue Dec 22, 2009 5:50 pm

Re: [BASIC] printing: tray selection worked, but not anymore

Post by zenlord »

The option 'explicit" has revealed some undeclared variables and one variable that was declared as an Object, but had to be a String.

Thank you for your looking at my code - unfortunately, the problem is not solved.

I suspect the problem to be in this snippet (inside sub printPage):

Code: Select all

	REM set Papertray in Styles
	DIM oStyle AS Object, oViewCursor AS Object, sPageStyleName AS String, oPageStyles AS Object
	DIM iPageNr AS Integer
	iPageNr = sPageNr
	oViewCursor = oDoc.CurrentController.getViewCursor()
	oViewCursor.JumpToPage(iPageNr, false) 
	sPageStyleName = oViewCursor.PageStyleName
	oPageStyles = oDoc.StyleFamilies.getByName("PageStyles")
	oStyle = oPageStyles.getByName(sPageStyleName)
	'If the printer has but one tray, comment the next line out:
	oStyle.PrinterPaperTray = sTray
If the viewcursor does not jump to the correct page, the printerpapertray is not set for the page that eventually gets printed. I checked for the values of the variables, but I don't know if the correct pagestyle is found and used.
LibreOffice 4.1 on Linux (Debian Wheezy backports)
zenlord
Posts: 51
Joined: Tue Dec 22, 2009 5:50 pm

Re: [BASIC] printing: tray selection worked, but not anymore

Post by zenlord »

I installed xray, and it revealed to me tha my suspicion is correct: the tray is set correctly, but it is always set for the first page, and not for the page that needs to be printed.

This snippet of code does not work as intended:

Code: Select all

	oViewCursor = oDoc.CurrentController.getViewCursor()
	oViewCursor.JumpToPage(iPageNr, false) 
	sPageStyleName = oViewCursor.PageStyleName
I checked the var iPageNr, and that is set correctly - can anyone enlighten me on how to get the pagestyleName of a specific page, pretty please?
LibreOffice 4.1 on Linux (Debian Wheezy backports)
B Marcelly
Volunteer
Posts: 1160
Joined: Mon Oct 08, 2007 1:26 am
Location: France, Paris area

Re: [BASIC] printing: tray selection worked, but not anymore

Post by B Marcelly »

Your last code snippet works for me (Windows, AOO 3.4.1 and LibO 3.5.3), and should work in other configurations.

The jumpToPage() method has only one argument, but this is not the problem.

Code: Select all

oViewCursor.JumpToPage(iPageNr)
The argument of jumpToPage() is the rank of the page in the document, it may be different from the page number printed at a header or footer. For example the cover page may print without number, and the footer of the next pages printed with page numbers starting from 1. There may also be phantom pages (blank pages), e.g. page 2 if the document has styles for right pages and left pages.

Display your variable, the current page number, and the page style name :

Code: Select all

oViewCursor.JumpToPage(iPageNr)
MsgBox("iPageNr " & iPageNr & chr(10) & "Page " & oViewCursor.Page & chr(10) & "Style : " & oViewCursor.PageStyleName)
Check iPageNr = Page, and look at this page rank in the document.
Bernard

OpenOffice.org 1.1.5 / Apache OpenOffice 4.1.1 / LibreOffice 5.0.5
MS-Windows 7 Home SP1
zenlord
Posts: 51
Joined: Tue Dec 22, 2009 5:50 pm

Re: [BASIC] printing: tray selection worked, but not anymore

Post by zenlord »

Thank you for thinking with me. The MsgBox prints 'iPageNr = Page' and on both pages, the pageStyle = 'Standaard'. This contradicts my version of Libreoffice 3.5.2 itself: in the page styles menu (GUI), I can see clearly that the second page has a style applied called 'Nextpage'. Libreoffice Basic recognises also that the pagestyle exists, because when I hardcode the pagestyle 'Nextpage', there is no error raised and the sub completes with the opposite result.

This is starting to look like a bug in the version I'm using currently: 3.5.2 on Debian Squeeze.
LibreOffice 4.1 on Linux (Debian Wheezy backports)
zenlord
Posts: 51
Joined: Tue Dec 22, 2009 5:50 pm

Re: [Basic] printing: tray selection worked, but not anymore

Post by zenlord »

OK,

So I made a new template from scratch, copied the macro and dialog over and now it works as expected. There must have been something in the existing documenttemplate that was holding the macro back from fetching the correct PageStyleName. Very frustrating, but hey - marking this one as SOLVED... and adding the final macro to the code-snippets forum.

THX!
LibreOffice 4.1 on Linux (Debian Wheezy backports)
Post Reply