Report Printing oldvalue instead of newvalue

Hi, I Currently have a situation i need help with a report printing. I have a report viewer. with a parameter called identity. this is a report that when printed should print the pallet number.

so the operators presses a PrintPallet button. then i execute my code (the end of my SP is below) get a parameter out. i put that parameter into the variable PalletID, I use this to put the variable into the parameter of the report. as soon as the report gets the parameter it will load. and then I run a Function that excecutes a print without a dialog. with an invoikelater to have time to load the report.

This was working fine until last week, we have much more traffice so the SP takes longer to execute, and the report also takes longer to load. so it is not loading on time. example is that if i print now pallet.
2004568 this load in the DB all perfect. but the report prints the number 2004567. next time this happens it should print 2004569 but it doesn’t it prints 2004568. so it s one late all the time.

I know I can partially fix this by increment the delay on the function, which I did to 1500ms instead of the 500 I have on the code below. this gives enough time and it prints correctly with the newvalue. but i don’t like this solution. I want to prevent this to happen completely, so i want to find a way to only print the report after the report executes and it’s ready with the newvalue. I need a trap or condition to prevent this and only print the report when the newvalue is already executed.

 #only partial code foe store procedure, 

call.registerOutParam(3, system.db.INTEGER)
call.registerInParam("action", system.db.INTEGER, action)
call.registerInParam("maxid", system.db.INTEGER, maxp)
call.registerInParam("minid", system.db.INTEGER, minp)
	
system.db.execSProcCall(call)
	

	
PalletID =(call.getOutParamValue(3))

	
event.source.parent.parent.getComponent('Report Viewer').identity = PalletID
	
if PalletID!=(call.getOutParamValue(3)):
		system.gui.messageBox("<html><center>El Papel no fue impreso con el numero correcto<br> Por favor presionar Reprint Labels y Comunicar a Juan Pablo.")	
	def printlabel(printreport = event.source.parent.parent.getComponent('Report Viewer')):
		import system
		
		printreport.print(None, False)
		printreport.print(None, False)
		system.db.refresh(event.source.parent.parent.getComponent('Power Table'),"data")	
		
	system.util.invokeLater(printlabel, 500)

instead of using a print function on the component, use system.report.executeAndDistribute(). One thing to keep in mind, to use this method the printer must be installed on the gateway. If your printers are shared on a network this shouldn’t be a problem.
Example

params = {'palletID':palletID}
system.report.executeAndDistribute(path='yourReport', 
project='YourProject',
parameters = params,
action='print', 
actionSettings = {'primaryPrinterName':PrinterName,
'copies':1})

Thanks, but this are not network printers, this goes to two printers one it is a network printer and it would work for that so thank you. the other one is small label printer that just prints a sticker with a barcode.

I do have a way to it . that i has been working on my packing slip window. which instead of having the report on the window. I open a new window pass the parameter palletid into the root container. and then the report it bound to the property and i have a propertychange script that runs the print function, and I believe this should probably never, but I’m not a 100% so I’m looking for advice. but I was hoping to get something like a handshake. like report executed? yes then print.

If you need this to work/print on client side, you could make use of the javax.print library in conjunction with the system.report.executeReport function. executeReport executes much faster than just passing the parameter value to a report viewer component. Also, you won’t need a delay. As soon as you get the new palletID you can trigger the process and it will have the latest value.

The byte array from executeReport can be interpreted by thejavax.print library. Leave executeReport at the default array setting (.pdf I believe) and use BYTE_ARRAY.AUTOSENSE as the doc flavor when interpreting using the javax.print library.

I can give sample code to print to the system default printer(of the computer executing the script) if needed

Thanks for the reply, yes if you can provide me with a sample code of how to make it work would be perfect because I’m not sure how to run it, so a sample code would be extremely appreciated.

I made some quick code which is almost the same as what I use to print my reports. I normally have to print 8 pages with different data for each page in quick succession. My code executes in about 5 seconds total.

Since you are doing a smaller report and less pages, yours will probably run quicker.

Place the below code in your PrintPallet buttonClicked event handler. Change the project name and project path to the correct values. Also make sure to put in the code to grab the PalletID you want to print.

The below code will print 1 copy of the report out of the default printer for the client machine this is executed on.

If you want more copies, you can either duplicate the printjob.print line or do it correctly and look at the documentation for javax.print to set up printjob attributes(number of copies is a setable attribute, I don’t use it so I don’t know how to set it up)

#make this a process we can call asynchronously to prevent UI lockup
	def longProcess():
		#import needed libraries
		import system
		import javax.print
		
		from javax.print import SimpleDoc
		from javax.print import DocFlavor
		from javax.print import PrintServiceLookup
	
		
		#fetch pallet ID 
		PalletID = "some code to grab needed PalletID"
		
		#Setup and execute report locally
		file = system.report.executeReport(path = "Report_Path_here",
		project = "Your Project Name Here",
		parameters = {'identity':PalletID})
		
		#setup printing parameters and print the new report
		service = PrintServiceLookup.lookupDefaultPrintService()	#fetch system default printer
		flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE			#Define  what type of info we are using(Autosense will autodetect)
		doc = SimpleDoc(file, flavor, None)					#create the document we want to print
		printjob = service.createPrintJob()				#create the print job
		printjob.print(doc, None)							#print the document we created
		
		def end():
			print"Printed Report"
			return
		
		system.util.invokeLater(end)
	system.util.invokeAsynchronous(longProcess)

1 Like

Thank you for the help, while I was doing the script I realized there is an easier and safe to do it.

what I did was to create a custom property in the PrintPallet Button called prints (BOOL)

I also added to the script. in the PrintPallet to set the property to 1 when operator pressed PrintPallet.

then on the reportviewer in the extension function OnReportGenerated which executes once after the report has finished

if self.parent.getComponent('Group').getComponent('PrintPallet').prints ==1:
	self.print(None, False)
	self.print(None, False)
	self.parent.getComponent('Group').getComponent('PrintPallet').prints =0

Thanks, anyway I also try your code and appreciated.