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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Print PDF to a file from VFP8 2

Status
Not open for further replies.

dsandlin

Programmer
Jul 11, 2003
56
0
0
CR
I am trying to print a group of VFP reports, each to its own PDF file, but the resulting files are not recognized by the Acrobat reader.

My code looks like this...

SET PRINTER TO "Acrobat PDFWriter"
*SET PRINTER TO "CutePDF Writer" && I've tried several
*SET PRINTER TO "PDF995"

USE MySource

lcFileName = 'output.pdf'

REPORT FORM rptK1Form NOCONSOLE TO FILE (lcFileName)

Any suggestions? --Dick [laser]
 
dsandlin,

The problem is your use of TO FILE (lcFileName) in the REPORT FORM command. Remove that clause and all should be well.

When you output to a pseudo driver like a PDF driver, the driver is responsible for creating the output file. If you also have VFP do it, the two components will tread on each other's toes.

Mike


Mike Lewis
Edinburgh, Scotland

My Visual Foxpro web site: My Crystal Reports web site:
 
Mike,

I have tried removing the clause as you suggested and nothing happens. I do not get any output. Is there somewhere special that I should look for the output file? Do I have to create the file and then rename it to the name that I want (assuming that it can be found).

Prior versions from faq184-2143 seem to require creating a postscript file and running it through some ps2pdf() utility which stores the output in a subdirectory.

I was hoping to find a way to create the PDF file directly.

Please advise. -- Dick [flowerface]
 
If you're using the Acrobat PDFWriter, it should prompt for a filename (and location) when you run the report.

If it isn't, can you be a little more specific about what you're doing?
 
Dan,

Thanks for jumping in. The code shown in my example is a snippit that is simplified. Actually, I am scanning a table and copying each record into the source table for the report, then running the report. The report prints entries on top of a tax form image. I need to wind up with several thousand PDFs, each one a single, completed tax form that can be emailed to an individual. It is necessary that the controlling program assign a name to each pdf that matches one of the fields in the source table.

The documentation for the VFP8 Report Designer says that I should be able to print the report, in the format produced by the print driver, to the file that I specify in the TO FILE clause. Mike suggests that the PDF Writer is a pseudodriver that does not operate according to the spec.

I have seen a description (in FAQ184-2143) that might do the job, except that it is a two-step operation, starting with Postscript and using a PS2PDF converter. I was hoping to avoid the extra complexity, if I could.

Regards, Dick [lookaround]
 
This is what I'm currently using:
Code:
 LOCAL lsPrinter As String
lsPrinter = "CutePDF Printer" && Or whatever
SET PRINTER TO Default
SET PRINTER TO NAME '&lsPrinter'
REPORT FORM myReport TO PRINTER NOCONSOLE
SET PRINTER TO

"SET PRINTER TO NAME '&lsPrinter'" line is specially important on Win9x systems, otherwise it doesn't works.
ON Win2k/XP you can safely change it for "SET PRINTER TO NAME lsPrinter"

Regards,

Gerardo Czajkowski
ltc.jpg
 
Gerardo,

Thanks a million! I was leaving out the keyword NAME. That was my problem. I will give you a star for that one.

Interestingly, the PDF writer puts the output file in the default directory, and deposits a zero byte file in the destination named in the TO FILE clause. (assuming that the destination points to a different directory) I can deal with that, even though it seems a little quirky.

Thanks to all of you for your posts! -- Dick
 
Now that your problem is solved... {g}

One other issue you can look for in the future I have hit with output to the PDF Writer is the printer info in the TAG, TAG2, and EXPR columns in the first record of the FRX. If there is printer specific information, VFP sometimes will not output to the PDF.

_RAS
VFP MVP
 
rschummer,

I'm not sure what you mean by the columns of the FRX. When I renamed my report's FRX to DBF and tried to browse it, I got an error that it couldn't find the memo file. There is a "Tag" property of the report, but it is empty. How would I view the columns that you mentioned?


-- Dick
 
I'm not sure what you mean by the columns of the FRX. When I renamed my report's FRX to DBF and tried to browse it, I got an error that it couldn't find the memo file. There is a "Tag" property of the report, but it is empty. How would I view the columns that you mentioned?

I think rschummer meant use your report like a table and browse it.
Code:
use myreport.frx
browse

Locate the first record at the top.




Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Mike,

Thanks for the tip. I sent you a star, too. I knew that most things in VFP were in table format some way or other, but I didn't know how to browse it. That helped!

Fortunately, the printer that I used with Report Designer to create the report is a Postscript printer, so it went to the PDF Writer with no problem. I think if you used some other kind of printer, that might cause troubles.

One last nagging problem is bothering me. The Report writer puts out this tiny little form (apparently modal) that says that it is printing. This is slowing down the process, blanking out my WAIT WINDOW that shows how many have completed, and, since it has a Cancel button, it is interfering with my use of ON CANCEL DO to jump out of the loop (that prints multiple PDFs). Some of these jobs create thousands of PDFs and I might want to shut down the process in the middle. Blowing it away with Task Manager is my last resort (and not a good one). Is there any kind of trick that might stop the report generator from showing that box? (I'm already using NOCONSOLE) -- Dick
 
dsandlin

Thanks for the tip. I sent you a star, too. I knew that most things in VFP were in table format some way or other, but I didn't know how to browse it. That helped!

Helpfull also to debug forms.

Code:
use myform.scx
browse

One last nagging problem is bothering me. The Report writer puts out this tiny little form (apparently modal) that says that it is printing. This is slowing down the process, blanking out my WAIT WINDOW that shows how many have completed, and, since it has a Cancel button, it is interfering with my use of ON CANCEL DO to jump out of the loop (that prints multiple PDFs). Some of these jobs create thousands of PDFs and I might want to shut down the process in the middle. Blowing it away with Task Manager is my last resort (and not a good one). Is there any kind of trick that might stop the report generator from showing that box? (I'm already using NOCONSOLE) -- Dick

Although not perfect (it apprears once) take a look at faq184-2918.





Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
You can move this window off the Windows screen. Here is some code I published in 1001 Things You Wanted To Know About Visual FoxPro (KiloFox), available from Hentzenwerke.com.

Put the following code in a program called ChangePrintingWindow.prg

Code:
#DEFINE ccWIN_PRINTING "Printing..."

* Only change the window if it exists
IF WEXIST(ccWIN_PRINTING)
   IF EMPTY(WPARENT(ccWIN_PRINTING))
      lcFont = WFONT( 1, ccWIN_PRINTING )
      lnSize = WFONT( 2, ccWIN_PRINTING )
      lcStyle = WFONT( 3, ccWIN_PRINTING )
      lnHeight = FONTMETRIC(6, lcFont, lnSize, lcStyle)
      lnWidth = FONTMETRIC(4, lcFont, lnSize, lcStyle) + ;
                FONTMETRIC(1, lcFont, lnSize, lcStyle)
      lnLeftBorder = SYSMETRIC(3) / lnHeight
      lnTitle = (SYSMETRIC(9)+2) / lnWidth
      lnTopBorder = SYSMETRIC(4) / lnWidth

      DEFINE WINDOW CustomPrint ;
         FROM WLROW(ccWIN_PRINTING), WLCOL(ccWIN_PRINTING) ;
         SIZE WROWS(ccWIN_PRINTING) - lnTopBorder, ;
         WCOLS(ccWIN_PRINTING) - lnLeftBorder ;
         SYSTEM ;
         TITLE tcTitle ;
         MINIMIZE ZOOM FLOAT CLOSE ;
         ICON FILE (tcIcon) ;
         FONT lcFont, lnSize;
         STYLE lcStyle ;
         COLOR RGB(0, 0, 0, 192, 192, 192)
 
      DEFINE WINDOW CustomPrintReport ;
         FROM 0, 0 ;
         TO (WROWS(ccWIN_PRINTING) - lnTopBorder) / 3, ;
         WCOLS(ccWIN_PRINTING) - lnLeftBorder ;
         NONE ;
         FONT lcFont, lnSize;
         STYLE lcStyle ;
         COLOR RGB(0, 0, 0, 192, 192, 192) ;
         IN WINDOW CustomPrint

      ACTIVATE WINDOW CustomPrint
      ACTIVATE WINDOW ccWIN_PRINTING IN CustomPrint
      MOVE WINDOW ccWIN_PRINTING TO - (lnTopBorder + lnTitle), - lnLeftBorder
      ACTIVATE WINDOW CustomPrintReport
      @ 1, 1 SAY PADC(tcText, WCOLS("CustomPrintReport"))
   ENDIF
ENDIF

RETURN SPACE(0)


You add a textbox expression in the earliest band of the report, typically a Title band. In the expression place a call to this routine.

Code:
ChangePrintingWindow("Win Title","Print.ico","Message...")

You do not get a cancel button or page numbers as the pages are printed. Couple of drawbacks you should be aware of.


_RAS
VFP MVP
 
Mike and Rick,

I tried moving the window off the page, which works as predicted, but the window still interferes even though you can't see it. The WAIT window is interrupted and the cancel button is still overruled. I also tried implementing an ON KEY LABEL to make F12 be the stop button, but that is not recognized either.

I wonder if I can just close the window or release it somehow to make it really go away, not just hide. I guess that I am making a mountain out of a mole hill....

--Dick
 
dsandlin said:
Thanks a million! I was leaving out the keyword NAME. That was my problem. I will give you a star for that one.

Thanks for the star, but I don't deserve it. Those ideas were posted some time ago -a year maybe- at this forum.

If you don't want to hard-code the PDF printer driver name you can do something like this:

Add this code somewhere on your main PRG

Code:
PUBLIC gsPDFPrinter AS String
LOCAL laPrinters as String, li As Integer
gsPDFPrinter = ""
DIMENSION laPrinters(1)
IF APRINTERS(laPrinters) > 0
	FOR li = 1 TO ALEN(laPrinters,1)
		IF "pdf"$LOWER(laprinters(li,1))
			gsPDFPrinter = ALLTRIM(laPrinters(li,1))
			EXIT
		ENDIF
	ENDFOR
ENDIF
This will search for the first installed printer that contains "pdf", so when you need to print to PDF simply issue
Code:
SET PRINTER TO NAME '&gsPDFPrinter'

With this you can even check if a PDF printer driver is not installed (gsPDFPrinter will be empty) and disable PDF printing.

Regards,

Gerardo Czajkowski
ltc.jpg
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top