No announcement yet.

DDOC page limit

  • Filter
  • Time
  • Show
Clear All
new posts

  • #21
    As far as the Ddoc is concerned. Here are the steps we used.

    We tried to use SpecifyPrinter and then dpenddoc %ddoc_specifyprinter which works at 24,000 and prints real info through PDFCreator to a specified PDF file.
    We tried with %ddoc_viewbuild which allows you to view the pages as they are being created. I put a msgbox just before the dpEndDoc and all data was there in the preview. Went to page 1 and various pages and the last page of 44,328 or so pages. As soon as I dismissed the messagebox and executed dpEndDoc the data disappeared while the print preview was still on screen but now with no data.

    I tried with no msgbox and no specify printer, just a %ddoc_end_close. All with the same result. A 65 megabyte file with 44,328 empty pages.

    These were annual statements representing about 10 billion under trust. The customer produced 24,000 pages just fine and sent to their third party mailer who normally takes care of turning the single pdf into a mailout. The customer had to printout and hand stuff 6300 themselves by printing to the their local printer.

    We only have one option at this point and that is to have the customer break it into two print jobs. In GUI mode PDFCreator will allow two .ddc files to be loaded into the queqe while the auto-printing is turned off. Once there, you can combine the two documents, turn printing on and get one pdf. I've tested this with some small files. We don't know if this will actually work though with the large ones. I've already spent 12 hrs testing ddoc with different configurations.

    I tried XPRINT simulating the same thing. It attaches to the printer and feeds PDFCreator from statement one. It didn't have a problem working this way and was really fast. We are currently waiting to see if Don can figure it out. If not, we'll re-write this program in PB ver 8 using XPRINT. XPRINT has all the functions we need. There is too much stake here.

    I'll let you know how it comes out. Personally we never thought to check this size of a job.

    We actually have two other customers whose PDF output will be larger than this coming up.

    Bob Mechler
    Last edited by BOB MECHLER; 9 Jan 2008, 08:29 PM. Reason: Corrections


    • #22
      I think you have one thig left to try with ddoc P&P so you don't have to rewrite...

      Do not try to use dpEndDoc with immediate print. Instead, dpEndDoc SAVING the "DDC" file wihtout printing.

      Then SHELL or CreateProcess ddoc.exe with the /Sprintername,ddcfilename command-line option. This will farm out the printing to a separate process.

      It's worth a try, since it's only about three lines of code. Here's how I do it..
      ' end the document and set the delete option
             dpEndDoc  grpp.hdoc, %DDOC_END_CLOSE   ' cannot set delete flag here.. it does immediate delete
             ' set the delete flag so the view or print will do that and delete the ddc file when done:
             dpSetDocDeleteFlag grpp.szDDCFileName, %TRUE
      then later after I check if the user wants his reports to go to a printer directly or to preview (toolbar option)...

                ' Launch ddoc.exe with correct options based on print destination and wait for it to finish
                ' writing to spooler (if send to printer) or enter idle state (if sent to previewer).
                ' ddoc.exe /S wants printername, filename COMMA-SEPARATED
                ' 5/26/05 I cannot use simply "ddoc.exe" here because this is not SHELLed.. it results in failure
                ' unless ddoc.exe is on the path
                'CALL          PPP_ProgramPath(lpfile)  ' returns with trailing slash
                'lpfile     = lpFile & "ddoc.exe"
                lpfile     = ""
                LOCAL szDdoc AS ASCIIZ * 16, szFilePart AS ASCIIZ * 16
                szDdoc= "ddoc.exe"
                i          =  searchPath(BYVAL %NULL,        szDdoc,    BYVAL %NULL,      SIZEOF(lpFile), lpFile,   szFilePart)
                '                        path, null=default  filename   extension if not  destination for fully-   filename only
                '                        Windows path        to file    part of filename  qualified filename found
                IF ISTRUE i THEN
                      '  MSGBOX "SearchPath found ddoc.exe as ==>" & lpFile ' OK '5/26/05
                   lpVerb                = "open"
                   IF @pPCJ.Destination.iType = %UO_PRINT_OPTION_PREVIEW THEN
                           lpParameters  =  grpp.szDdcFileName
                   ELSEIF @pPCJ.Destination.iType = %UO_PRINT_OPTION_PRINTER THEN
                           lpParameters  =  "/S" & @pPCJ.Destination.szName & "," & Grpp.szDDCFileName
                           MSGBOX "invalid @ppCJ.Destination.itype"
                   END IF
                   iTimeout      = %INFINITE
                   SEI.cbSize       = SIZEOF(SEI)
                   SEI.fmask        = %SEE_MASK_NOCLOSEPROCESS  ' we need the returned process handle
                   SEI.hWnd         = @pPCJ.hWndCaller
                   SEI.lpVerb       = VARPTR(lpVerb)
                   SEI.LpFile       = VARPTR(lpFile)
                   SEI.lpParameters = IIF& (lstrLen(lpParameters), VARPTR(lpParameters), %NULL)
                   SEI.lpDirectory  = %NULL
                   SEI.nShow        = %SW_SHOW      ' should be zero for a document file PER MSDN DOC.
                                                    ' MSDN DOC IS WRONG, use SW_SHOW!
                   SEI.hInstApp     = 0             ' updated by function
                   SEI.lpIdList     = %NULL         ' here down to hprocess ignored unless appropriate mask included in fmask
                   SEI.lpClass      = %NULL
                   SEI.hkeyClass    = %NULL
                   SEI.dwHotKey     = %NULL
                   SEI.item         = %NULL
                   SEI.hProcess     = 0             ' will be updated by ShellExecuteEx
                   IF ISTRUE ShellExecuteEx(SEI) THEN       ' function succeeded and returned
                     IF @pPCJ.Destination.iType = %UO_PRINT_OPTION_PRINTER THEN
                           iWaitStat      = WaitForSingleObjectEx (SEI.hProcess, iTimeout, 0)
                     ELSEIF @pPCJ.Destination.iType = %UO_PRINT_OPTION_PREVIEW THEN
                           iWaitStat      = WaitForInputIdle ( SEI.hProcess, iTimeOut)
                     END IF
                     SELECT CASE AS LONG iWaitStat
                       CASE -1&
                            E = GetLastError
                            'MSGBOX "Wait Failed:" & SystemErrorMessageText (E)
                            fv =  E
                       CASE %WAIT_OBJECT_0
                           ' this is good, we can post a success code
                             fv = 0   ' success
                     END SELECT
                     CloseHandle SEI.hProcess
                      fv = -1&  ' non-zero, error could not launch ddoc.exe
                      MSGBOX "Could not launch previewer"
                  END IF    ' fi shellexecuteEx succeeded
               ELSE    ' searchpath failed to find ddoc.exe
                 PPPS_ERRORMSGBOX ("Can't find Print Library 'ddoc.exe installed" & $CRLF & "Cannot Print.")
               END IF  ' if we found ddoc.exe using searchpath
      To set the delete flag you have to modify the file header of the DDC file...
      'TYPE I can use without divulging any proprietary info
          Fill0      AS STRING * 114
      END TYPE
      FUNCTION dpSetDocDeleteFlag (szDdcFile AS ASCIIZ, FlagValue AS LONG) AS LONG
          LOCAL hFile AS LONG, ddh AS DDHTYPE, iFlag AS INTEGER
          iFlag   = ISTRUE (FlagValue)          ' convert to integer
          hFile   = FREEFILE
             SEEK      hFile, SIZEOF(ddh.Fill0)
             PUT       hFile, , iFlag
             CLOSE     hFile
          END IF
      Well, it's maybe ten lines of code instead of three once you extract what you need, but it's still not a lot to try to avoid the preview and I think it's worth a try.

      (Much of code above you don't need but I left it in to make sure everything is there).
      Last edited by Michael Mattias; 10 Jan 2008, 08:59 AM. Reason: corrected ddoc command line text to add comma, ddcfilename
      Michael Mattias
      Tal Systems Inc. (retired)
      Racine WI USA
      [email protected]


      • #23
        Today was eye doctor day, just recovering from dilated eyes.

        It's unclear if the /S is an undocumented feature or you are giving me the code for it.

        This is the only job where we don't grab the filename, do a dpEndDoc and then shell to ddoc.exe /PA to print in a separate process. I thought if the SpecifyPrinter option was used that it had to be just before dpEndDoc to allow the system to switch to the desired PDF printer and then switch back to the normally default printer right away. I'll study the example however I did try the method where we didn't specify a printer at all and just closed the file(%DDOC_END_CLOSE), which we found under Document and Setting/Local Setting/Temp with no problem(dpGetFileName). Normally after the shelled Ddoc started, we then just deleted the .ddc later

        ddoc.exe /Sprintername,ddcname would be a welcome enhancement and allow a lot of other programs that work just fine with ddoc to get a PDF option since they will be less that 1000 pages at all times.

        I will study this carefully.

        Just as a sidenote, I thought the dpEndDoc was probably releasing the handle but PDFCreator was simply not picking it up in time to return a pointer to the data.


        Bob Mechler
        Last edited by BOB MECHLER; 10 Jan 2008, 10:13 PM. Reason: Correction


        • #24
          It's unclear if the /S is an undocumented feature or you are giving me the code for it.
          It never made it into the help file, but it is a supported feature and in any event you can find it in the source code where ddoc.exe parses the command line.

          It just might be a timing thing, since the normal "dpEndDoc" with "print" or "view" options does a SHELL to ddoc.exe anyway... ie the print or preview runs in another process anyway.

          I had to use it this way because the way the PPPS was designed, the user could change the printer name or change from "print" to "preview" after the report has been generated. That is, he can have an 'inventory' of "*.ddc" files and select which one to print, where and how.

          (At least that was the plan, I still have not added the feature to the software. Thanks for reminding me... I was running low on New Feature Suggestions).

          Michael Mattias
          Tal Systems Inc. (retired)
          Racine WI USA
          [email protected]


          • #25
            Yeah, I'd noticed the other switches in the code but assumed they weren't implemented. I'm glad you mentioned it because it proved to be the key in fixing another ddoc related problem that just came up this week with another customer.

            They have a user website we built that has a custom feature of allowing the logged in user to download statement PDF's for the past year. They were just now getting up to speed when they started getting out of memory errors from PDFCreator when they created hundreds of pdfs for the first time.

            We changed the code to use the /S flag and instead of the out of memory error we got blank pdfs.

            When I was having the error the code looked like this:

                      dpGetFileName hfile%, zFilename, %MAX_PATH
                      dpEndDoc hFile%, %DDOC_END_CLOSE
                      IF zFilename$ > "" THEN            
                        SHELL "ddoc.exe /SPDFCreator," + zFilename$
                      END IF
            All the pdf's were created but were empty.

            I got a hint from your code that some waiting for a process to complete was probably needed and I had found and used code that did just that only for an entirely different purpose.

            When the additional code below was added, it took a little longer but all the pdf's had content. We sent it on to the customer this afternoon.

            Forgive me if I don't give credit where credit is due for the code. I just don't remember where the technique came from but it was from the forum.

            The SLEEP 1000 may not be necessary but I had to add it at some point in other programs where intermittent problems were occurring.

                      dpGetFileName hfile%, zFilename, %MAX_PATH
                      dpEndDoc hFile%, %DDOC_END_CLOSE
                      IF zFilename$ > "" THEN            
                        sFilename$ = TRIM$(zFilename$)
                        SLEEP 1000
                        Yinstance& = SHELL("ddoc.exe /SPDFCreator," + sFilename$)
                        Zprocessid& = OpenProcess(%PROCESS_QUERY_INFORMATION + %PROCESS_TERMINATE,%False,Yinstance&)
                          DIALOG DOEVENTS
                          I& = GetExitCodeProcess(BYVAL Zprocessid&,lpExitCode&)
                        LOOP WHILE lpExitCode& = %STILL_ACTIVE
                      END IF


            • #26
              >When I was having the error the code looked like this:
                        dpGetFileName hfile%, zFilename, %MAX_PATH
                       dpEndDoc hFile%, %DDOC_END_CLOSE
                        IF zFilename$ > "" THEN
              From context it appears your problem here was far simpler.

              If zFileName (no trailing dollar sign) is LOCAL/DIM as ASCIIZ, then your SHELL is executing with the wrong value following the comma.

              If zFileName (no trailing dollar sign) is LOCAL/DIM AS STRING, then it has no value because dpGetFileName wants an ASCIIZ string for parameter two.

              Michael Mattias
              Tal Systems Inc. (retired)
              Racine WI USA
              [email protected]


              • #27
                zFileName (no trailing dollar sign) is LOCAL/DIM AS STRING, then it has no value because dpGetFileName wants an ASCIIZ string for parameter two.
                BTW... this is a good way to corrupt the stack and get one of those 'mystery GPFs' that seems 'impossible' at the point in your code where the protection fault is detected and reported ("appname must close...")
                Michael Mattias
                Tal Systems Inc. (retired)
                Racine WI USA
                [email protected]


                • #28
                  The following code has been working just fine with no GPF's for at least 4 years. It's part of a general routine that takes a plain text file report and creates a ddoc report. Every report we produce that isn't started and ended within the BAS is run through this routine.

                      dpGetFileName hfile%, zFileName,%MAX_PATH
                       dpEndDoc hfile%, %DDOC_END_CLOSE
                      IF NOPREVIEW THEN
                        SHELL "ddoc.exe /PA " + zFileName$
                        SHELL "ddoc.exe " + zFileName$
                      END IF
                  Does the addition of a '$' to zFileName (an ASCIIZ * %MAX_PATH variable) cast it into a normal string?

                  Bob Mechler


                  • #29
                    I'm pretty sure ....
                    LOCAL szFile AS ASCIIZ * %MAX_PATH

                    ...results in two different variables... but that may be PB-version dependent.

                    In any event I never ever do that. I always use "LOCAL|STATIC|GLOBAL varname AS whatever" and never use type specifiers.

                    Or maybe it depends on your "#DIM ALL|NONE|ARRAY" compiler directive. Maybe you could toggle whatever you are using and see if the behavior differs.
                    Michael Mattias
                    Tal Systems Inc. (retired)
                    Racine WI USA
                    [email protected]