Baanboard.com

Go Back   Baanboard.com > Forum > Baan SIGs > Code & Utilities

Retirement Notice

Baanboard is shutting down on 31-dec-2023. See: http://www.baanboard.com/baanboard/showthread.php?t=76043


User login

Frontpage Sponsor

Main

Poll
What do you expect from your SI Implementation partner for the success of ERP implementation.
Bring best practices - Not to offer more CR's Leveraging standard functions
20%
Need more honesty to work with the Users until their processes are fully mapped & Users are trained
40%
Focus on process automation/ integrations/ Real time data/ BI analytics
13%
Stick to basics
27%
Total votes: 15

Reference Content

Reply
 
Thread Tools Display Modes
  #1  
Old 15th February 2002, 22:58
~Vamsi's Avatar
~Vamsi ~Vamsi is offline
Guru
 
Join Date: Aug 2001
Location: San Diego CA, USA
Posts: 595
~Vamsi will become famous soon enough
Baan: ~*~ - DB: ~*~ - OS: ~*~
Page x of y: Kevin Brock's solution.

Lisa of RMCis faxed me Kevin's original post. I typed it up. Couple of observations. This must have been before Kevin discovered that HTML worked on baanfans. That is why he mentions about code not formatting properly. His later posts were always formatted. I have used VB tags for the code when typing this.

This solution works iff you have source code. And like he mentions in his post, you better have a very good reason to print x of y. This is a lot of coding for that functionality. He did mention in a recent post that he found a simpler method that did not require any changes to the session or the report. I believe he posted yet another solution after this one. But I am not sure. If someone has used it or has an electronic copy somewhere, please post it.

~Vamsi

<hr>

NOTE! Though this is long, I've posted it as I thought many folks may be interested in this solution.
Sorry about the formatting for the code samples, this message board trashes the indents.

I've not tried to do this myself ... that's what I was going to say a couple of days ago, but I was challenged by this question and I had fun solving it. I've run into this before but been able to get out fo doing page-of processing but decided to actually figure it out. Nove I have a general solution (perhaps someone else has something easier, but I don't understand how the second footer/lattr.enddata suggestion is supposed to do this either).

In most environments, page of processing can be quite difficult. The usual requirement is to count the number of pages and then print as, most times, the data output is too complex to compute the number of pages. If you can compute the number of pages up front it's probably a very simple and consistent report.

The other solution is to actually run the full report two times. The first time simply does not physically output anything but is used to get the actual final result. This can be done using the original data as long as the data is not changing during the report. I have implemented this solution more or less generically. You must also be careful with this solution for reports that update as you must not do so during the first pass (ofcourse the results could then be different as your report may process the resultant records differently after the update).

Here's what you can do. First, let's look at the report itself as this is the easiest to change. If you do not have a report script you will have to define one. Declare 2 new variables and add a before.program and after.program section (if there isn't already one):
Code:
		domain	tcmcs.long	total.pages
		domain	tcbool		page.of

before.program:
	import("page.of", page.of)
	if page.of then
		total.pages = 0
	else
		import("total.pages", total.pages)
	endif

after.program:
	|Send the current and final page count back to the parent session
	if page.of then
		export("total.pages", total.pages)
	endif

Then, change the header (or any other layout) of the report to include the variable "total.pages" where you need to show the total page count. That's it for the report. Comile it.

Now, for the tougher stuff; the main session (you must have source to make these changes). Add the following variable declarations:
Code:
			long		spl.date
			long		spl.fontnumber
			long		spl.left.mrg
			long		spl.pr.copies
			long		spl.pg.length
			long		spl.pg.width
			long		spl.time
			long		spl.view.rtl
			string		spl.device(14)
			string		spl.fileout(100)
			string		spl.paper.type(6)

		domain	tcbool		report.has.data
			long		sp1
			long		sp2
			long		rptid

	#define SEND(x) brp.ready(x)
^		report.has.data = true

|*** Report variable additions
	extern	domain	tcmcs.long	total.pages
	extern	domain	tcool		page.of

I've included a define to make life a little easier later on. Most of these variables (the spl.* ones) are used to save off the spooler variables for later use. What we will be doing is opening up 2 separate spool devices. The first one the user has control over and will be where the report will be printed. The second is for internal processing to get the total page count. This will work best on Unix systems as the output device can be directed to /dev/null, though there may be a good solution for NT as well (nul device may work, I've not tried it).

I'll just include my code from my test along with the comments. Hopefully this will explain the rest.
Some of the exit code (at the choice.again() call) is not the greatest as a lot of statements get repeated, but does work. I've also taken the quick route of using message(), instead of mess() and message codes, when showing error/warning texts.

Code:
choice.print.data:
on.choice:
	|Initial open to get the user's selections, report defaults to choice
	|from session
	sp1 = spool.open("", "", 1)
	if (sp1 <= 0) then
		choice.again()
	endif

	save.spooler.choices()

	|Now open the temporary device to NULL to run the report
	|for page of processing.
	|Note: pg.length must be reset in case the two device definitions
	|are different; we want page of calculated against the real device
	spool.fileout = "/dev/null"	|Platform specific! (i.e. Unix)
	sp2 = spool.open("", "ASCIF", 0)
	spool.pg.length = spl.pg.length
	if (sp2 <= 0) then
		message("Unable to open spooler for page of processing")
		spool.id = sp1
		spool.close()
		reset.spooler.choices()
		choice.again()
	endif

	|Run the report to the temporary device and expect a total page
	|count back. Note! Report program MUST export to the local
	|total.pages variable
	report.has.data = false
	page.of = true
	spool.id = sp2
	rptid = brp.open(spool.report, "", 0)
	if (rptid > 0) then
		read.main.table()	|Process the report
		brp.close(rptid)
		spool.id = sp2
		spool.close()
		
		|Determine if hte report will have any data the FIRST time
		|to save some processing time.
		if not report.has.data then
			message("Nothing found to print")
			spool.id = sp1
			spool.close()
			reset.spooler.choices()
			choice.again()
		endif
	else
		message("Unable to open report!")
		spool.id = sp2
		spool.close()
		spool.id = sp1
		spool.close()
		choice.again()
	endif
	
	reset.spooler.choices()
	
	|Run the real report (spooler#2 - to null device should already
	|be closed by this time)
	page.of = false
	spool.id = sp1
	rptid = brp.open(spool.report, "", 0)
	if (rptid > 0) then
		read.main.table()	|Process the report
		brp.close(rptid)
		spool.id = sp1
		spool.close()
	else
		message("Unable to open report!")
		spool.id = sp1
		spool.close()
	endif

|*** functions
**************************************************************

functions:

function save.spooler.choices()
{
	|Save contents of spool.* variales changed by the temporary
	|output report so the user's last selections are not lost.
	spl.date = spool.date
	spl.fontnumber = spool.fontnumber
	spl.left.mrg = spool.left.mrg
	spl.pr.copies = spool.pr.copies
	spl.pg.length = spool.pg.length
	spl.pg.width = spool.pg.width
	spl.time = spool.time
	spl.view.rtl = spool.view.rtl
	spl.fileout = spool.fileout
	spl.device = spool.device
	spl.paper.type = spool.paper.type
}

function reset.spooler.choices()
{
	|Reset all the spooler variables for later use by the report or
	|this session.
	spool.date = spl.date
	spool.fontnumber = spl.fontnumber
	spool.left.mrg = spl.left.mrg
	spool.pr.copies = spl.pr.copies
	spool.pg.length = spl.pg.length
	spool.pg.width = spl.pg.width
	spool.time = spl.time
	spool.view.rtl = spl.view.rtl
	spool.fileout = spl.fileout
	spool.device = spl.device
	spool.paper.type = spl.paper.type
}

function read.main.table()
{
	|These routines are not included. However, whenever a record is
	|ready to send to the report, I used my macro, e.g. SEND(rptid). This
	|way the report.has.data variable is set whenever something has
	|actually been sent.
	... rest of program ...
}

Caution! Baan will actually build two temporary files. It appears that if the output is directed to /dev/null or perhaps ASCIF this is immediately removed from $BSE/tmp. Be careful you don't fill up the spool directory with the output from these.

It would be best if a full spooler output device would not need to be opened and the physical writes could be skipped. However, setting lattr.print = false in the report during page of processing won't work as the line counter will not be incremented. I've used similar logic in some COBOL report routines but was able to keep the final output from occurring as I had full control of the code. This could be done in Baan as long as you wrote your report from scratch and skipped using the report writer (not a good solution). Any one have any ideas on this?

I hope this wasn't too long and the cost of running the report 2 times doesn't outweigh the result.

Have fun with this! Let me know if you've been able to make use of this solution or if there is a better way/improvement you can think of.

Kevin Brock
Senior Technical Consultant
Quality Consultants, Inc.
...a member of the Process Technology Group of companies
Atlanta, Georgia

Ask me about QKEY: a new solution for developing additions to Baan standard code when no source is available.
Reply With Quote
  #2  
Old 3rd January 2006, 09:09
Rita Kotecha Rita Kotecha is offline
Senior Member
 
Join Date: Oct 2003
Location: Mumbai
Posts: 214
Rita Kotecha is on a distinguished road
Baan: Baan Vc - DB: SQL 2k - OS: Win 2k
Thanks Mr Kevin Brock,

I could use this code. But is there any way we do not need to process the report twice and can get the total No. of Pages.
__________________
Regards
Rita
Reply With Quote
  #3  
Old 4th January 2006, 15:28
mark_h's Avatar
mark_h mark_h is offline
Guru
 
Join Date: Sep 2001
Location: Kentucky, USA
Posts: 7,819
mark_h will become famous soon enoughmark_h will become famous soon enough
Baan: Baan 4C4 A&D1 - DB: Oracle - OS: Sun Solaris
I do not think Kevin has been around this board in a long time. In this method you do need to process it twice. I only have one program that does "page x of y" and I do my best to avoid using this anywhere else.
__________________
Mark

GO Cards!
My latest mantra - make sure you have latest stpapi patches and the latest session object. If on LN then please explore the option of using DAL2 functionality.

Shared Solutions for Baan systems provided free by Baan Board.
Play the Google game and help Baanboard get better rankings. Do your part. Click here to find how.
Reply With Quote
  #4  
Old 5th January 2006, 10:48
Rita Kotecha Rita Kotecha is offline
Senior Member
 
Join Date: Oct 2003
Location: Mumbai
Posts: 214
Rita Kotecha is on a distinguished road
Baan: Baan Vc - DB: SQL 2k - OS: Win 2k
Hi,

Can we generalise this code, so that it can be used for various reports. (like writing it into a dll or a function etc..). If yes, can you please guide me how to go about it ?
__________________
Regards
Rita
Reply With Quote
  #5  
Old 5th January 2006, 12:08
george7a's Avatar
george7a george7a is offline
Guru
 
Join Date: May 2004
Location: Nazareth
Posts: 1,492
george7a is on a distinguished road
Baan: IVc, 5.0 b, 5.0 c, LN 6.1 - DB: MS SQL, Oracle - OS: Windows 2000, 2003 & UNIX
Quote:
Originally Posted by Rita Kotecha
Thanks Mr Kevin Brock,

I could use this code. But is there any way we do not need to process the report twice and can get the total No. of Pages.
I have done once a similar thing but it was more simple. I thought I will share it with you.

I had a sales order report and I had to know how many lines does every customer have ( I needed to put the custoemr total beside the last customer). what I did is I wrote a query and checked how many sequences are there for that customer in the wanted period and I counted them. In this case I guess if we sum all the customers lines & added the header lines & other layouts , we can have the total number of lines which will help us to know the total number of pages.

- George
__________________
_
George Abdo
Thabet.Net
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Page x of y: Jo Büche's solution. ~Vamsi Code & Utilities 11 21st February 2018 08:26
How to specify report page sizing for a non printer device Jabran Tools Development 1 3rd August 2004 13:39
Herstellkostenberechnung in BaaN 4c Kai's Forum Users Deutsches Forum 4 5th July 1999 01:00


All times are GMT +2. The time now is 01:27.


©2001-2023 - Baanboard.com - Baanforums.com