Any idea how to make sure, that pages printed in batch printing are output from printer in correct order?
Problem is, that printer prints some documents in wrong order, even when they are submitted to spooler in correct order.
Adobe Acroread32.exe is doing printing.
bJOB_STATUS_SPOOLING is updated using subroutine in Form timer.
Pseudocode used now...
Code:
For i=1 to DocCount
RetVal = ShellExecute(0&, "Print", Chr$(34) & sDocumentName & Chr$(34), vbNullString, vbNullString, SW_MINIMIZE)
Do While bJOB_STATUS_SPOOLING
Doevents
Loop
RetVal = ShellExecute(0&, "Print", Chr$(34) & sWaybillName & Chr$(34), vbNullString, vbNullString, SW_MINIMIZE)
Do While bJOB_STATUS_SPOOLING
Doevents
Loop
Next i
Re: Batch printing - printed pages in wrong order.
Since you are shelling the print command and ADOBE is doing the printing, not sure there is much in VB you can do about this. Here's a link on Raymond Chen's blog that may apply.
Out of curiosity what is the purpose of the timer? You said it modified that boolean, but what else is it doing? Maybe looking for the shell window to close? From your post, I can't really visualize your "printing process".
Edited and thought. If you were to build a test batch file (.bat) that contains the commands to print those documents in the order your want with 2+ copies, do they get printed as expected? If so, maybe the solution is to dynamically build a batch file and execute the batch file instead of printing one document at a time.
If batch file still prints out of order (expected), that may show that this is out of your control without modifying some spooler setting or sending 1 document at a time and waiting... ShellExecuteAndWait
Last edited by LaVolpe; Jul 8th, 2018 at 10:24 AM.
Insomnia is just a byproduct of, "It can't be done"
Re: Batch printing - printed pages in wrong order.
Timer routine calls CheckPrinter subroutine, which requests print spooler and sets bJOB_STATUS_SPOOLING variable.
I also tried to print using 'Use printer in offline-state', so that jobs are spooled, but not sent to printer. Likewise some jobs are in wrong order in spooler (sorted by job start time).
No checking for shell window close. It seems that Acroread32.exe stays in memory after printing to spooler is completed. Maybe that method could be used to check and proceed with next print job, but how - since user may have other Acroread instances loaded?
Re: Batch printing - printed pages in wrong order.
I see. You are testing the default printer's job state (spooled jobs) on a timer's interval. Understanding the code comments is difficult, but I think I was able to follow it.
Is it possible that the timer is triggering too soon? In other words, the spooler hasn't registered a job yet when your timer kicks off? So, you get a false positive that no jobs are currently spooled? If possible, maybe set a larger interval for testing and see if that helps.
Edited: Here's what I'm thinking:
Code:
reset spooler boolean
For i=1 to DocCount
Send 1st document to printer
start timer
Do While ...
DoEvents
' timer is disabled when boolean is set to no jobs
Loop
Send 2nd document to printer
start timer
Do While ...
DoEvents
' timer is disabled when boolean is set to no jobs
Loop
Next
And as a side note. By waiting on an empty spool (no jobs), what happens if a job is waiting and printer is out of paper? Wouldn't that make your app just loop infinitely? Don't know whether that scenario generates an error in your module and whether you are testing for errors.
Edited: I see that errors, like out of paper, are logged, but logged to a string. If not using the error information, you may want to consider that. Personally, I don't like errors returned in string parameters because that requires parsing. I'd rather have it return a Long value of the most important error (if multiple errors exist) or a bit-wise value (up to 32 on/off values) that relate to a list of errors. For example, (prntError And 1) = errOutOfPaper, (prntError And 2) = errDoorOpen, (prntError And 4) = errPaperJam, etc. If needed, then a string can be composed, for a msgbox maybe, based on the error(s) returned. Otherwise, the composed string returned from your function should be displayed to the user IMO. In any case, an error should cancel/pause the print request until problem is resolved.
Last edited by LaVolpe; Jul 8th, 2018 at 11:28 AM.
Insomnia is just a byproduct of, "It can't be done"
Re: Batch printing - printed pages in wrong order.
CheckPrinter routine calls
Code:
PrinterStr = CheckPrinterStatus(PI2.Status) 'Check if printer is in ready state.
ChekcPrinterStatus function which stores error and other printer status information to 'bJob_xxx' boolean variables. I left those out from pseudocode, to simplify things. Boolean bJOB_STATUS_SPOOLING variable is the key issue here, as MS says that this is the state to monitor. When bJOB_STATUS_SPOOLING=False other document could be spooled so that it prints correct order (ie. after the previous spooled document). But somehow that is not always the case. I have tried Timer intervals from 55 upto 500 ms. When logging it seems that bJOB_STATUS_SPOOLING=True state is very short, like 200-300 ms per single page document.
I already have been tried to start timer immediately after shelling document printout, but that did not help. Orginally coded routine so that the timer is started beginning of the printing routine so that timer routine is enabled whole time during printing routine.
No jobs state could be one answer, so that print next document when previous document is spooled and printed. Infinite loop situation when printer has error, paper out, door open etc. - yes these are handled, but left out from pseudocode for simplicity.
Re: Batch printing - printed pages in wrong order.
Sounding more like trying to sync your timer with the printer spool is proving unreliable. Starting the timer before or after sending the print job may not work well for various reasons: Print command opens Adobe, then Adobe starts the print process. The time needed to start Adobe and execute the print from Adobe can be wildly different depending on current O/S usage, i.e., system busy with other stuff. Since ShellExecute is async, it returns quickly
Due to the short time that the job may stay in the pool, this method may not work for you. The timing you mentioned may even be printer driver specific? Is it even possible that small print jobs aren't even entered in the pool to be queried?
Another workaround, if you can create PDF files, is to combine to 2 documents into a single PDF then print it.
Insomnia is just a byproduct of, "It can't be done"
Re: Batch printing - printed pages in wrong order.
It seems odd that if the spooling of a single page takes 200-300ms that you would be using a timer interval of 50 or even 500 to check it. With 50 especially it may well return false before the spooling even begins. Try a higher interval 1,2 or even up to 5 seconds just to test and see if your problem goes away.
Another test that may help would be to create a second timer and set it to like 50ms then in that timer log the call, time and result so you can see when the spooling starts and stops for each document.
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
For health reasons i try to avoid reading unformatted Code
Re: Batch printing - printed pages in wrong order.
Originally Posted by LaVolpe
Sounding more like trying to sync your timer with the printer spool is proving unreliable. Starting the timer before or after sending the print job may not work well for various reasons: Print command opens Adobe, then Adobe starts the print process. The time needed to start Adobe and execute the print from Adobe can be wildly different depending on current O/S usage, i.e., system busy with other stuff. Since ShellExecute is async, it returns quickly
Due to the short time that the job may stay in the pool, this method may not work for you. The timing you mentioned may even be printer driver specific? Is it even possible that small print jobs aren't even entered in the pool to be queried?
Another workaround, if you can create PDF files, is to combine to 2 documents into a single PDF then print it.
Yes, i thought and came same conclusion after some more testing.
Calling CheckPrinter routine asyncronously using timer do not work. Single page documents spool too fast to catch spooling event.
Have to do some rewriting and testing, altought i would not hold my breath on this as faster machines could still cause spooler state detection problem.
I will split CheckPrinter routine to separate OpenPrinter and ClosePrinter routines.
- call OpenPrinter before printing routine and during printing just call CheckPrinter directly from DO - LOOP without constantly opening and closing printer
- call ClosePrinter after printing routine done.
Investigated merging of pdf files too, but some documents contain tens of pages and whole DocCount loop could be hundreds, so merging would slow operation too much.
PRINTER_CHANGE_JOB
Notify of any changes to a job. You can set this general flag or one or more of the following specific flags:
PRINTER_CHANGE_ADD_JOB
PRINTER_CHANGE_SET_JOB
PRINTER_CHANGE_DELETE_JOB
PRINTER_CHANGE_WRITE_JOB https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
Last edited by Tech99; Jul 10th, 2018 at 10:25 AM.
Re: Batch printing - printed pages in wrong order.
Originally Posted by DataMiser
It seems odd that if the spooling of a single page takes 200-300ms that you would be using a timer interval of 50 or even 500 to check it. With 50 especially it may well return false before the spooling even begins. Try a higher interval 1,2 or even up to 5 seconds just to test and see if your problem goes away.
Another test that may help would be to create a second timer and set it to like 50ms then in that timer log the call, time and result so you can see when the spooling starts and stops for each document.
Have to correct time value, 200-300 ms was timing from shellexecute call to the point when document disappered from spooler (bNoPrintJobsInSpooler=True state). This was measured using 55 ms timer interval - so it might be faster than that - but somewhat in longer run averaged to 200-300 ms.
→ The Comprehensive Guide to Cloud Computing
A complete overview of Cloud Computing focused on what you need to know, from selecting a platform to choosing a cloud vendor.