chocobochick
08-18-2005, 09:34 AM
Greetings. I'm new to this forum, so I thought I'd start out with a doozy.
The Project: I've been attempting to create a VBA Outlook macro that, when executed, prints every message in a dedicated folder. This macro is part of a process I'm developing to convert emails and attachments to multipage TIF images, working largely in conjunction with Zan Image Printer (http://www.zan1011.com/index.htm) software to append each print job to a temp.tif file, which the script copies and deletes when all attachments from a MailItem have been completed. The script also creates a text file containing account numbers extracted from the Subject line, and it changes printer settings (by swapping INI files) from B&W to grayscale if it detects any JPG/GIF/etc attachments, the message is flagged, or it contains the word "picture" in the subject line.
The Problem: I have a While loop that pauses batch processing until a file named "sentinel.txt" is generated in the filesystem, signifying that the printer has completed a job. This loop hogs the processor while the printer is working and attachments are being opened by their default programs, slowing the process significantly and prompting unwanted popups from programs like MS Word asking if the user would like to cancel the process because it's taking too long. I tried to solve this by placing the DoEvents function within the loop, but now the printer randomly finishes a job and starts the next one within a single DoEvents window, creating and deleting the sentinel file before my loop even knows it was ever there. This throws off the running count of printed attachments in the code, causing TIF files to be spliced across MailItems and B&W/grayscale printer settings to change unexpectedly.
The Code: This is the loop in question, nested within a ForEach loop that processes each MailItem in the folder.
' Send message and all attachments to the printer
itm.PrintOut
' Wait for sentinel file to be regenerated for each print job
For i = 1 To itm.Attachments.count + 1
While Not fs.FileExists(strProgramPath & "\sentinel.txt")
DoEvents ' Without this line, program is slow. With it, program is unreliable.
Wend
' Delete file now that we know it's there. Otherwise, next loop might exit
' before printer has been able to start its next job and delete it again.
fs.DeleteFile (strProgramPath & "\sentinel.txt")
Next
The Questions:
Is there a way to print each attachment individually (I won't always know what it is) rather than using Outlook VBA's PrintOut method with default print settings to print each attachment?
Is there a way in VBA, with or without DoEvents, to handle the multitasking better so the script isn't hogging the processor but it still won't miss the sentinel file generation?
Are there any other ways I might approach this project?
Thanks in advance for comments and suggestions. Any insight to this project would be great!
P.S. As I typed this, another idea came to me. The printer software has the option of running a command or application after completing a job, which I've used to append text to a time-stamped log so I could compare against my script's log and doublecheck the missed sentinel files. But I could feasibly set the printer to append a new line to a specified data file. Then my script could read this file at timed intervals in another DoEvents loop, count the number of lines in the file, and proceed with the program when "# of lines = # of attachments + 1". This way, the file is always there, and I can let the script delete it when it's satisfied all attachments have been printed. I may give this a try.
The Project: I've been attempting to create a VBA Outlook macro that, when executed, prints every message in a dedicated folder. This macro is part of a process I'm developing to convert emails and attachments to multipage TIF images, working largely in conjunction with Zan Image Printer (http://www.zan1011.com/index.htm) software to append each print job to a temp.tif file, which the script copies and deletes when all attachments from a MailItem have been completed. The script also creates a text file containing account numbers extracted from the Subject line, and it changes printer settings (by swapping INI files) from B&W to grayscale if it detects any JPG/GIF/etc attachments, the message is flagged, or it contains the word "picture" in the subject line.
The Problem: I have a While loop that pauses batch processing until a file named "sentinel.txt" is generated in the filesystem, signifying that the printer has completed a job. This loop hogs the processor while the printer is working and attachments are being opened by their default programs, slowing the process significantly and prompting unwanted popups from programs like MS Word asking if the user would like to cancel the process because it's taking too long. I tried to solve this by placing the DoEvents function within the loop, but now the printer randomly finishes a job and starts the next one within a single DoEvents window, creating and deleting the sentinel file before my loop even knows it was ever there. This throws off the running count of printed attachments in the code, causing TIF files to be spliced across MailItems and B&W/grayscale printer settings to change unexpectedly.
The Code: This is the loop in question, nested within a ForEach loop that processes each MailItem in the folder.
' Send message and all attachments to the printer
itm.PrintOut
' Wait for sentinel file to be regenerated for each print job
For i = 1 To itm.Attachments.count + 1
While Not fs.FileExists(strProgramPath & "\sentinel.txt")
DoEvents ' Without this line, program is slow. With it, program is unreliable.
Wend
' Delete file now that we know it's there. Otherwise, next loop might exit
' before printer has been able to start its next job and delete it again.
fs.DeleteFile (strProgramPath & "\sentinel.txt")
Next
The Questions:
Is there a way to print each attachment individually (I won't always know what it is) rather than using Outlook VBA's PrintOut method with default print settings to print each attachment?
Is there a way in VBA, with or without DoEvents, to handle the multitasking better so the script isn't hogging the processor but it still won't miss the sentinel file generation?
Are there any other ways I might approach this project?
Thanks in advance for comments and suggestions. Any insight to this project would be great!
P.S. As I typed this, another idea came to me. The printer software has the option of running a command or application after completing a job, which I've used to append text to a time-stamped log so I could compare against my script's log and doublecheck the missed sentinel files. But I could feasibly set the printer to append a new line to a specified data file. Then my script could read this file at timed intervals in another DoEvents loop, count the number of lines in the file, and proceed with the program when "# of lines = # of attachments + 1". This way, the file is always there, and I can let the script delete it when it's satisfied all attachments have been printed. I may give this a try.