Solved

Outlook 2003 "print it" rule

Posted on 2009-07-01
16
924 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?
0
Comment
Question by:boettcher1
  • 7
  • 7
  • 2
16 Comments
 
LVL 76

Expert Comment

by:David Lee
ID: 24756429
Hi, boettcher1.

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

Author Comment

by:boettcher1
ID: 24756579
I would love to try that if you can walk me through how to do it!!
0
 
LVL 76

Expert Comment

by:David Lee
ID: 24756906
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

0
 

Author Comment

by:boettcher1
ID: 24757256
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!!
0
 

Author Comment

by:boettcher1
ID: 24757822
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!
0
 
LVL 76

Expert Comment

by:David Lee
ID: 24758357
"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.
0
 

Author Comment

by:boettcher1
ID: 24762354
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.  
0
 
LVL 76

Expert Comment

by:David Lee
ID: 24762390
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.  
0
What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

 

Author Comment

by:boettcher1
ID: 24762411
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.
0
 
LVL 76

Expert Comment

by:David Lee
ID: 24762448
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.
0
 

Author Comment

by:boettcher1
ID: 24762494
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.
0
 

Expert Comment

by:statzd
ID: 24765330
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

0
 
LVL 76

Expert Comment

by:David Lee
ID: 24781102
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

0
 
LVL 76

Accepted Solution

by:
David Lee earned 250 total points
ID: 24781116
Follow these instructions to use this code.

1.  Start Outlook
2.  Click Tools > Macro > Visual Basic Editor
3.  If not already expanded, expand Microsoft Office Outlook Objects and click on ThisOutlookSession
4.  Copy the code from the Code Snippet box and paste it into the right-hand pane of
5.  Outlook's VB Editor window
6.  Edit the code as needed.  I included comment lines wherever something needs to or can change
7.  Click the diskette icon on the toolbar to save the changes
8.  Close the VB Editor
9.  Click Tools > Macro > Security
10. Set the Security Level to Medium
11. Close Outlook
12. Start Outlook
13. Outlook will display a dialog-box warning that ThisOutlookSession contains macros and asking if you want to allow them to run.  Say yes.

This code monitors the inbox for new items.  When an item arrives the code checks to see if it is a message.  If it is, then it checks to see if it meets whatever condition(s) you've set.  In other words, it emulates a rule without using rules.  If the item meets your condition(s), then it is printed.

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 = "Some Subject" Or Item.SenderName = "John Doe" Then

            PrintMe Item

        End If

    End If

End Sub

Open in new window

0
 

Author Comment

by:boettcher1
ID: 24806794
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
 
0
 

Assisted Solution

by:statzd
statzd earned 250 total points
ID: 24807734
boettcher1,

the PrintMe subroutine needed to be included with the second code snippet, which was why the script didn't print, but I plugged that in and then had weird issues with writing to the %TEMP% folder, so I changed the saveas directory to C:\ and then it worked fine for me. That was probably a problem local to my system or account, so you may or may not need to do that.  I also added a few lines to set the default printer back. Here's BlueDevilFan's code including the PrintMe routine:


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 = "Message1" Then

            PrintMe Item

        End If

    End If

End Sub
 

Sub PrintMe(Item As outlook.mailItem)

    Dim strFilename As String, strDefaultPrinter As String, wrdApp As Object, wrdDoc As Object

    strFilename = "c:\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'

    strDefaultPrinter = wrdApp.ActivePrinter

    wrdApp.ActivePrinter = "\\printserver1\printer2"

    wrdDoc.PrintOut

    wrdDoc.Close False

    Set wrdDoc = Nothing

    wrdApp.ActivePrinter = strDefaultPrinter

    

    wrdApp.Quit False

    Set wrdApp = Nothing

End Sub

Open in new window

0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Outlook 2016 display images 14 43
Outlook search works halfway only, why? 7 42
Best method to eliminate & combine duplicate Office 365 contacts 3 34
Moved to Outlook 2013 4 35
Learn more about how the humble email signature can be used as more than just an electronic business card. When used correctly, a signature can easily be tailored for different purposes by different departments within an organization.
If you don't know how to downgrade, my instructions below should be helpful.
This Experts Exchange video Micro Tutorial shows how to tell Microsoft Office that a word is NOT spelled correctly. Microsoft Office has a built-in, main dictionary that is shared by Office apps, including Excel, Outlook, PowerPoint, and Word. When …
To add imagery to an HTML email signature, you have two options available to you. You can either add a logo/image by embedding it directly into the signature or hosting it externally and linking to it. The vast majority of email clients display l…

914 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now