We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Outlook 2003 "print it" rule

boettcher1
boettcher1 asked
on
Medium Priority
950 Views
Last Modified: 2012-05-07
Is there a way in Outlook 2003 to set the "print it" rule to print to a specific network printer and not to the default printer?
Comment
Watch Question

CERTIFIED EXPERT
Top Expert 2010

Commented:
Hi, boettcher1.

Not with a rule alone.  It's possible with a rule that runs a macro.  Is that an option?

Author

Commented:
I would love to try that if you can walk me through how to do it!!
CERTIFIED EXPERT
Top Expert 2010

Commented:
Here's the code for doing this.  It works by switching the default printer to the desired printer, printing the message, and then switching the default printer back to what it was.  Follow these instructions to set up and use this.

1.  Start Outlook
2.  Click Tools > Macro > Visual Basic Editor
3.  If not already expanded, expand Modules and click on Module1
4.  Copy the code below and paste it into the right-hand pane of the VB editor window
5.  Edit the code and make changes as needed.  I included comments where a line needs to be edited.
6.  Click the diskette icon on the toolbar to save changes
7.  Close the VB Editor
8.  Click Tools > Macro > Security
9.  Set the Security Level to Medium
10.  Create a rule that fires when this person receives a message.  
11.  Set the action portion of the rule to "run a script" and select this script as the one to run

That should do it.
Public Declare Function GetProfileString Lib "kernel32" Alias "GetProfileStringA" _
        (ByVal lpAppName As String, ByVal lpKeyName As String, _
        ByVal lpDefault As String, ByVal lpReturnedString As String, _
        ByVal nSize As Long) As Long
 
Function GetDefaultPrinter() As String
    Dim strPrinter As String, _
        intReturn As Integer
    strPrinter = Space(255)
    intReturn = GetProfileString("Windows", ByVal "device", "", strPrinter, Len(strPrinter))
    If intReturn Then
        strPrinter = UCase(Left(strPrinter, InStr(strPrinter, ",") - 1))
    End If
    GetDefaultPrinter = strPrinter
End Function
 
Sub PrintMessageToSpecificPrinter(Item As Outlook.MailItem)
    Dim wshNet As Object, _
        strCurrentDefault As String
    strCurrentDefault = GetDefaultPrinter()
    Set wshNet = CreateObject("Wscript.Network")
    'Change the printer name on the next line to that of the printer you want attachments printed to
    wshNet.SetDefaultPrinter "Microsoft Office Document Image Writer"
    Item.PrintOut
    wshNet.SetDefaultPrinter strCurrentDefault
    Set wshNet = Nothing
    Set objFSO = Nothing
End Sub

Open in new window

Author

Commented:
BlueDevilFan,
  When calling the printer in wshNet.SetDefaultPrinter "-----------" how does it want the printer named?  I have tried the following of which none worked:
"\\server name\printer name"
"printername on server name" (this is how it looks in Printers and Faxes)
"hostname"

Thank you for taking the time to "spoon feed" this to me!!

Author

Commented:
BlueDevilFan,
  I now have it switching between the default printer and the network printer I want to print to just fine.  However, when the email prints, it always waits for the default to get set back to the original default printer and then prints.  Thus printing to the wrong printer.  Is there something that I can change in the code?

Thanks!
CERTIFIED EXPERT
Top Expert 2010

Commented:
"when the email prints, it always waits for the default to get set back to the original default printer and then prints"
I can't imagine how that's possible.  Line 23 sets the default printer to the printer of your choice.  Line 24 prints the message.  Line 25 switches the default printer back to what it was originally.  The process cannot "wait" for the printer to switch before printing.  It has to print when the print command is issued.  I'm not disputing that the print is going to the wrong printers, merely explaining that the code cannot wait for a switch to occur before printing.  Insert the following line of code between lines 24 and 25.

    Sleep 2000

Add the following line of code to the top of the module

    Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

This introduces a two second delay between printing and restoring the default printer.  Let me know what happens.

Author

Commented:
I added those two lines.  It changes the default printer to the one I want to print to waits the 2 seconds and then changes the default printer back to the original default printer and prints to that printer.  
CERTIFIED EXPERT
Top Expert 2010

Commented:
I'm not disputing what you're seeing, but that seems impossible.  There's simply no way for the code to not print when it's told to do so or for it to wait until the printer has switched back.  I've tested this on two different machines I have and it works perfectly on both.  As a test remove line #25 altogether and run it again.  

Author

Commented:
When I do that it changes the default printer to the one I want my email to print to.  Prints to the correct printer.  But does not change the default back.
CERTIFIED EXPERT
Top Expert 2010

Commented:
Right.  The test was to show that the process cannot wait for the original printer to be the default again before printing.  If that was happening, then the item would not have printed at all.  It would have sat there waiting for the original default printer to be restored so it could print to it.  The problem appears to be a timing issue.  Apparently the print process is taking so long that the default has switched back to the original printer.  Put line 25 back in place and increase the amount of sleep time from 2000 to 5000.

Author

Commented:
Okay.  I did that.  It changes the defaul printer to the one I want to print to, waits 5 seconds, changes back to the original default printer and prints there.  

I agree with you. I don't get why it won't print to the correct printer.  The command to print  comes before the command to change back to the original default printer.  It isn't making sense why your code isn't working.  In theory, it looks perfect.

Commented:
BlueDevilFan,

I plugged in your code and experienced the same thing that boettcher1 did: when run, it will change the default printer to the new one, then change the default printer back to the original, then print, in that order, even though the order of the code says "change printer, print email, change printer back".

 The mailitem.printout method doesn't appear to actually execute to the printer until the script completes, and so when it executes the printer is already back to the original default.

It doesn't make much sense to me either.

I also tried creating separate scripts run by separate Outlook rules (all rules triggered by same criteria):

Rule 1:
  Run script 1: change default printer to \\printserver2\printer2

Rule 2:
  Run script 2: print email

Rule 3:
  Run script 3: change default printer back to \\printserver1\printer1

This also seems to run as 1 complete process, and doesn't send the print command until the third rule and script completes (so prints to the wrong printer).

I also tried running your original code and my abbreviated code with 30 seconds of Sleep just to convince myself that it wasn't a process timing thing - instead of flipping back to the original default printer and printing right away, it just waits 30 seconds, then changes back to the original and prints. The print process just won't execute until the script completes.

A quick work around is to just have a separate Outlook rule and print script for each of the emails that should go to a different printer. Each script changes the default printer to the correct one for that particular email, but does not change it back so that it prints to the right one.
This work-around doesn't satisfy me, though, as with more than a few rules it would become a paint o maintain.

 I simplified your code down for testing purposes by hardcoding printer names.

Sub PrintMessageToSpecificPrinter(Item As outlook.mailItem)
    Dim wshNet As Object
    Set wshNet = CreateObject("Wscript.Network")
    'Change the printer name on the next line to that of the printer you want attachments printed to
    wshNet.SetDefaultPrinter "\\printserver1\printer1"
 
 Item.PrintOut
 
    wshNet.SetDefaultPrinter "\\printserver2\printer2"
 
    Set wshNet = Nothing
    
    Set objFSO = Nothing
    
End Sub

Open in new window

CERTIFIED EXPERT
Top Expert 2010

Commented:
Hi, statzd.

Thanks for testing and providing additional feedback.  Apparently the difference is running the code from a rule.  I wasn't running the code from a rule, I was running it manually.  Apparently that makes a huge difference.  I cannot get the code to work reliably from a rule.  Sometimes it works and other times it doesn't.  I can't figure out why.  So, I've abandoned this approach altogether.  Let's try a different solution.

This approach saves the message to your Temp folder then uses Word to print to a specific printer.  Unfortunately this solution doesn't work from a rule either.  We have to use another means of triggering the code.  The solution to that is in the next post.
Sub PrintMe(Item As Outlook.MailItem)
    Dim strFilename As String, wrdApp as Object, wrdDoc As Object
    strFilename = Environ("TEMP") & "\OutlookMessage.rtf"
    Item.SaveAs strFilename, olRTF
    Set wrdApp = CreateObject("Word.Application")
    Set wrdDoc = wrdApp.Documents.Open(strFilename)
    'Change the printer name on the following line'
    wrdApp.ActivePrinter = "HP Deskjet 3320"
    wrdDoc.PrintOut
    wrdDoc.Close False
    Set wrdDoc = Nothing
    wrdApp.Quit False
    Set wrdApp = Nothing
End Sub

Open in new window

CERTIFIED EXPERT
Top Expert 2010
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
I tried the new code.  My email will come into my inbox but does not print.  I used:

 Dim WithEvents olkFolder As Outlook.Items
 
Private Sub Application_Quit()
    Set olkFolder = Nothing
End Sub
 
Private Sub Application_Startup()
    Set olkFolder = Session.GetDefaultFolder(olFolderInbox).Items
End Sub
 
Private Sub olkFolder_ItemAdd(ByVal Item As Object)
    If Item.Class = olMail Then
        'Edit the condition on the followign line.  You can have other conditions, these are just an example.'
        If Item.Subject = "hey" Or Item.SenderName = "John Doe" Then
            PrintMe Item
        End If
    End If
End Sub
 
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.