Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Two sided / Two different page reports

Status
Not open for further replies.

CouponPages

Programmer
Feb 17, 2003
37
US
I have a request from a client for printing two sided invoices, which I have never tried before, and I can't seem to find anything written on the subject.

The basic idea is that side one has just the name and address and some other client information, and the second side has details of the invoice and some additional information.

What I tried to do was create two detail areas, then use a variable called side, then a UDF that changed the value to either 1 or two... then I assumed I could break the page when the variable changed in detail area 1, then put detail area 2 on the second page... the result was a mess.

What I think I truly need are two headings, and two detail areas... one set for each page, with a page break on each heading, but I can't seem to find any way to make that happen.

Does anyone have an experience with reports like this?
 
Why not create two separate reports, one for each page. Run the first one, with NOPAGEEJECT, then run the second one.

You will have to set up your printer driver for duplex printing, but apart from that, it should be straightforward.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
What I've done in the past is create the detail for both pages on the same report form, and set the 'Print when...' to MOD(_PAGENO) = 1 for the first page, and MOD(_PAGENO) = 0 for the second.
Obviously, this only works for 2 page documents, and the layout looks a bit ugly in design mode.
But your method of using a UDF is fine too. It can easily be modified to accommodate more pages than 2.



-Dave Summers-
[cheers]
Even more Fox stuff at:
 
I have considered that, but the issue that's unclear to me is bringing them together. The client needs to submit the report to a printing company that will print, sort and mail the invoice, so the final product needs to be a single PS or PDF file.

If I run the two reports independently, is there a way to combine the results into one result so that basically you get:

- page 1 from report 1
- followed by page 1 from the second
- followed by page 2 from the first
- followed by page 2 from the second
- etc

I just Googled FoxPro Duplex two files... and came up with this from Microsoft, which assumes two single one page reports. I'll need to see if there is a way to use it with two reports of any size. In my case, the report is about 50,000 pages x two sides. The key is that they must absolutely be in synch so that the front page (from report 1) must match the same client on page two (from the second report). If it misses even once, the result is tens of thousands of worthless pages.


 
Thanks Dave... I didn't think of making the second detail conditional. It sounds reasonable... I'll tinker with that.
 
The trick I use for this is to create a index on the table.
I create a detail band for the field in the index &
do new page on the detail band.

Needless to say, the printer must be able to duplex.

This works for tax bills where the Address is on one side and the tax info is on the other.
Form is them folded and mailed.


David W. Grewe Dave
 
The client needs to submit the report to a printing company that will print, sort and mail the invoice, so the final product needs to be a single PS or PDF file.

Then you don't need to duplex them. Each page is quite distinct. It is up to the printing company to ensure the final product is double-sided.

I would go with two separate reports, and make sure you output them in the order that the printing company requires.

How you get them into a single PDF file depends on your PDF creation software. My PDF printer driver has a setting that says to concanate each file onto end of the previous one; maybe whatever PDF software you are using has something similar.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
I think you can achieve this functionality by using Groups. About 7 years ago I faced a similar requirement (though more complex) and initially achieved it by using two passes. I then were able to use Cathy's Pountney idea of using replicate(CHR(13), Number to make it start on a new page) and a lot of help by Sergey Berezniker.
 
If you don't mind coughing up a little over $100 for a sitewide developer license, XFRX will allow you to do this all programmatically within VFP (outputting both reports to a single PDF).

I have to do this with a lot of the reports I create.

(I hope this doesn't count as promoting/commercial posting - it is simply a solution for this problem)
 
BillKuhn,

(I hope this doesn't count as promoting/commercial posting - it is simply a solution for this problem)

Don't worry. No-one is likely to object to your mentioning a commercial product if it could genuinely solve a problem. After all, VFP itself is a commercial product.

By the way, I agree with you about XFRX. I've found it very worthwhile.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
For the record, because of the complexity of the report, the solution I used was an old-school technique that many modern programmers would never relate to.

What I did was pretty simple, I wrote the entire thing directly in PostScript using ? and an alternate file.

I simply SET ALTERNATE to my output file, queried the SQL Server database, then used SCAN... ENDSCAN with simple ? commands for the data.

I know it sounds so anti-establishment to bypass the report generators and all the GUI tools, but the result was a short and ultra efficient little program that spit out over 12,000 pages of PostScript in less than 3 seconds... from a 16GB SQL Server database. I then converted the PS to PDF in a matter of seconds so that they could review the print job before sending it to the printing company.

PostScript is actually pretty easy to create by hand, and the resulting file was much smaller than any automated report generator could ever hope to create. By using this technique, my program was free to position every element anywhere on the page with pinpoint accuracy without the limitations of detail bands, headers, etc... Information could flow in any way I wanted, seeking and jumping back and forth through cursors without feeling like I was trying to hack some way to make it work.

For what it's worth, some of the best reports I've every written could NEVER have been done within the restrictions of a report generator. Long live the "?" command!!!
 
CouponPages,

I know it sounds so anti-establishment to bypass the report generators and all the GUI tools ...

Not at all. In certain cases, it is a very sensible solution, especially as you are obviously comfortable with the Postscript language. After all, all you are doing is sending text to a file.

The important point is that you have solved the problem.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
White605,

If you can please post some of your code

I don't have CouponPages expertise in Postscript (in fact, I don't have much PS expertise at all). But the following is some code I wrote some years ago to accompany a magazine article on the Postscript language.

The code draws the logo of an outdoor-equipment supplier. The logo shows a mountain peak (a series of diagonal lines), with the moon (a plain circle) behind it. As you can see, it's basically some subroutines, followed by a main program.

Code:
% Prints the "mountains 
% and moon" graphic

/sky
{ -140 -70 moveto
  0 140 rlineto
  280 0 rlineto
  0 -140 rlineto
  .5 setgray
  closepath fill } def

/moon
{ newpath 1 setgray
  72 20 28 0 360 arc fill } def
  
/mountains
{ newpath
  -140 -70 moveto
  0 16 rlineto
  80 64 rlineto
  60 -48 rlineto
  80 64 rlineto
  60 -48 rlineto
  0 -48 rlineto
  0 setgray
  closepath fill } def

% main program
250 400 translate
sky
moon
mountains
showpage

The following code prints a text string with a 3D effect. The line beginning with 0.9 is the equivalent of a FOR / ENDFOR loop.

Code:
% Prints a string with 3-D effect

% procedure to print string once
/printstr
{0 0 moveto (This is my text) show }
def      

% establish the font
/Times-Bold findfont 
50 scalefont setfont 

100 400 translate

% print string in a loop
0.9 -0.075 0 
{setgray printstr .5 -1 translate } 
for

showpage

To run these programs from VFP, just send them to a text file, then send the file to a Postscript printer. Be sure to use a plain text-only printer driver (or the DOS COPY command), otherwise you will just print the program, not execute it.

Hope this helps.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Here's a short example of the basic, most essential syntax.

One thing to note, line breaks are ignored, so technically this script could be split up or joined into one long line.

Code:
/Helvetica-Oblique findfont 10 scalefont setfont

 72 720 moveto (This sentence is 1 inch from the left, 10 from the bottom.) show

 36 288 moveto (This is 1/2 inch at 4 inch from the bottom.) show

 36 668 moveto (This sentence is higher on the page than the last.) show

 36 648 moveto (This sentence is 20 points lower than the last.) show

/NewCenturySchlbk-Italic findfont 14 scalefont setfont

 36 620 moveto (This sentence is in another font.) show

showpage
 


Here's a snippet of FoxPro code that I used in the actual detail section in the billing program.

Code:
SELECT detail
up = 432
SCAN WHILE na_id = id2run
    ? psshow( col2, up, detail.Ptype)
    ? psshow( col3, up, Camp)
    ? psshow( Col4, up, STR(detail.pl_amount,10), "RIGHT" )
    ? psshow( Col5, up, STR(detail.pl_amount - detail.pl_balance, 10), "RIGHT" )
    ? psshow( Col6, up, STR(detail.pl_balance,10), "RIGHT" )
    TotBal = TotBal + detail.pl_balance
    up = up - fntsize
ENDSCAN

What you are seeing here in a nutshell is that I scan a cursor for the current client ID. On each line you see a call to a short function that I wrote that prints the moveto command with the left column position and UP position, followed by the text I want to print. The optional third parameter specifies an optional justification, RIGHT, CENTER or LEFT (left is the default, so I leave it out when I print most text).

A static variable is used to store the left column positions of each of the detail columns, and the variable fntsize is used for subtracting the last UP position to set the next UP position.

NOTE: I start by setting the variable UP at where I want to start, and since PostScript positions start in the lower left, I subtract the FNTSIZE variable from UP every time I want to go to the next line.

Code:
** Detail Columns
col1 = 0.5 * 72
col2 = 1.2 * 72
col3 = 2.5 * 72
col4 = 5.5 * 72
col5 = 6.5 * 72
col6 = 7.5 * 72
store 14 to fntsize

Notice that to simplify my layout and make it more readable, I create static variables at the top of my program based upon inches, then multiply them by 72.

 
When I was learning Postscript, I would create a simple document in Notepad, then print it with a Postscript printer driver, but sending the output to a non-PS printer.

That way, you see the source code of the program that the driver generates. I'm not saying you could learn PS entirely in that way, but it's a good technique for generating examples of code.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
About 15 years ago, I picked up the two "Official" books on the subject published by Adobe. I think they are now called the "Red" and "Green" books.

A lot of the focus was on the more advanced functionality such as vector graphics, bitmaps and scaling.

After exploring the basics I came to the following summary which is 99% of what you need to use it for reports and basic text.

If you can understand the following snippet... you can do almost everything.

Code:
/Helvetica-Oblique findfont 10 scalefont setfont
 72 720 moveto (Hello World) show
showpage

In a nutshell:

1. Set a font. If the entire page is one font, you only set it once.

2. Position the next output by using two numbers, followed by the command moveto.

3. Place the text you want to print in parenthesis and write the word "show".

4. When you're done placing text, use the command "showpage".

Other than that, some additional information to know:

PostScript is a stack based language. As such commands are executed in reverse notation. In plain English, that means you send it data, it keeps placing it on a stack until the command comes that tells it do do something with it.

Case in point, graphic commands are sent by sending the coordinates first, then a command to tell it what to do with them... such as a line, box, circle or other path.

Text is the same way, you send the text in parenthesis, then you send a command telling it what to do with the text. Normally the command you use is "show".

Unlike traditional printer, positioning is non-linear. You can add text to the page in any seqence you want. You can position text at the top, then the bottom like a regular printer, or you can randomly place the text at any time.

There are 72 points per inch, so if you want to work in inches, multiply the position desired by 72.

In a typical report, all you need to do is keep track of the current vertical position at any time, then subtract whatever number of points you need to jump down to the next line.

For horizontal positions, you should use static variables for the individual columns you are going to use.

Once you get past the basics, it's pretty easy to add some fancy stuff like lines, boxes, shadowed text, text on angles...etc. But for what it's worth, most reports don't need much of that.

Since Windows came along, I haven't written anything new to use PostScript in years, until I realized that the PostScript files it produce can be converted to PDF with programs like GhostScript... with a single line.

In my case, my programs spit out PS files from within web pages, then they launch GhostScript in the background and I get great PDF reports from the web site. Prior to that I struggled trying to get good printable reports or invoices from web applications.

Although it's easy to write PostScript, I'm only hand writing it in this case because the type of two sided multi-band reports I need are impossible with the built-in report generator.

For regular reports, my web-application uses a simple

"Set printer name PostScript"
"Report Form XYZ to file XYZ.PS"
"Run PS2PDF.BAT XYZ.PS"

In this case, my web server has a generic color postcript printer called "PostScript" (an HP Color LaserJet 8500PS), and it has GhostScript installed. I then created a one-line batch file called PS2PDF that generates the PDFs.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top