Print an Envelope for an Outlook Contact


 

Recently I was talking with my friend Chuck about features he wishes Microsoft would add to Outlook. One of the items on his list is the ability to print an envelope from a contact. Chuck noted that the only two ways he knows of to do this now is to either do a mail merge, which isn’t practical for printing a single envelope, or to copy and paste the contact’s address into Word. Copying the address may be simpler than setting up a mail merge, but it’s still too time consuming. Although I rarely use postal mail myself, I can see how this could be useful for those who do. Time to do some scripting.

At 27 lines, the resulting script is surprisingly short. That’s largely due to how easy Microsoft has made it to print an envelope from Word. Here’s how it works. The script starts by looking to see if you have an item open or just have one selected. Next, it checks to see if that item is a contact. If it isn’t, then the script displays an error and exits. Otherwise, it gets the default address of the selected contact, launches Word, creates an envelope, adds the contact’s address, adds your return address (which you define in the script), and prints the envelope. Simple stuff.

Hopefully this script will make Chuck’s work a little simpler, faster, and more efficient.

Requirements.

This solution should work in Outlook/Word 2007 and later. It may work in earlier versions too, but I haven’t tested with anything older than 2007.

Instructions.

Follow these instructions to add the code to Outlook.

  1. Start Outlook
  2. Press ALT + F11 to open the Visual Basic Editor
  3. If not already expanded, expand Microsoft Office Outlook Objects
  4. If not already expanded, expand Modules
  5. Select an existing module (e.g. Module1) by double-clicking on it or create a new module by right-clicking Modules and selecting InsertModule.
  6. Copy the code from the code snippet box and paste it into the right-hand pane of Outlook’s VB Editor window
  7. Edit the return address at the top of the code just below the comment
  8. Click the diskette icon on the toolbar to save the changes
  9. Close the VB Editor
Sub PrintEnvelope()
    'On the next line edit your return address.  Use /n to indicate the end of a line.
    Const RETURN_ADDRESS = "David Lee/n101 Main Street/nHometown, USA 10101"
    Const SCRIPT_NAME = "Print Envelope"
    Dim olkCon As Object, wrdApp As Object, wrdDoc As Object, strAddress As String
    Select Case TypeName(Application.ActiveWindow)
        Case "Explorer"
            Set olkCon = Application.ActiveExplorer.Selection(1)
        Case "Inspector"
            Set olkCon = Application.ActiveInspector.CurrentItem
    End Select
    If olkCon.Class <> olContact Then
        MsgBox "You must select a contact in order to use this macro.", vbCritical + vbOKOnly, SCRIPT_NAME
    Else
        strAddress = olkCon.FullName & vbCrLf & olkCon.MailingAddress
        Set wrdApp = CreateObject("Word.Application")
        Set wrdDoc = wrdApp.Documents.Add
        With wrdDoc.Envelope
            .Insert Address:=strAddress, ReturnAddress:=Replace(RETURN_ADDRESS, "/n", vbCrLf)
            .PrintOut
        End With
        wrdDoc.Close False
    End If
    Set olkCon = Nothing
    Set wrdDoc = Nothing
    Set wrdApp = Nothing
End Sub

Using the Solution.

1. Select or open a contact. The contact can be in any contact folder.
2. Run the macro. The envelope will print on your default printer.

Adding Buttons to Run the Macro with a Single Click.

If you want to be able to run the macro with a single click, then you’ll need to add a toolbar button for Outlook 2007 or a button on the Quick Access Toolbar (QAT) for Outlook 2010.

Outlook 2007. Follow these instructions to add toolbar buttons that runs the macro.

Outlook 2010. Follow these instructions to add the macro to the QAT.

About these ads

50 comments on “Print an Envelope for an Outlook Contact

    • Hi, John.

      I’m glad you like the script. To print on a custom size envelope, add these two lines

      .DefaultHeight = InchesToPoints(5.75)
      .DefaultWidth = InchesToPoints(8.75)
      

      immediately after this line

      With wrdDoc.Envelope
      
    • David,
      Thank you for your guidance.
      I copied and pasted your script lines into my macro.
      However, Outlook responded with Compile error: Sub or Function not defined “InchesToPoints”
      How can I fix this?
      Thanks.

    • That did it. Wonderful. except…for my promotional post card, the address block still needs to move another 1.75″ to the right. Also, would it be too much to ask if I could center align the text?
      Hope I’m not a Pain in the tuckus, but it is way fun to finally have some control over this process.

      Next, I’m going to ask if you know of a way to reset a default setting in Excel: Whenever I launch the program, the “Find” function defaults to Within: “Sheet”. I would like to change that to “Workbook.” Would I do that with a macro that runs automatically with the launch of the program or a ResEdit change in the registry? Or am I completely off base here?

    • Do both addresses need to move to the right or only one of them? If it’s the latter, which one? I don’t see a way to center an address.

    • My card has the return address pre-printed, so I am only concerned with the placement of the addressee text block. If I can move the addressee text block 1.75″ to the right, that will work. If I can’t center-align the text block, so be it. No problem. Flush left works, too as long as I can move the whole block 1.75″ right.

    • Add this line of code

      .AddressFromLeft = wrdApp.InchesToPoints(1.75)
      

      immediately after this line

      .Insert Address:=strAddress, ReturnAddress:=Replace(RETURN_ADDRESS, "/n", vbCrLf)
      

      I compared the original address placement to the address placement with this command added and it looks to me like it’s pulled to the left. Adjust the distance (i.e. 1.75) as needed.

    • We’re getting closer. I added:
      .AddressFromLeft = wrdApp.InchesToPoints(1.75)

      The result was that the addressee text block printed 1.75″ from the left edge of the 8.5″ wide paper.
      That being the case, I changed the value from 1.75 to 5.5. But the program responded with “One of the values passed to this method or property is out of range.
      I learned that the maximum value the program will accept is 4.75.
      Unfortunately, that isn’t enough.
      I made the addressee text size smaller thinking that might change the block dimensions, but no luck. 4.75 is the max offset.
      I thought I could outsmart it by changing the document width, but the net allowable value of intent remained the same.
      Then I tried “.AddressFromRight” but that is an invalid command.
      It seems the addressee text block is defined as 4″ (or 3″ with a 1″ right margin).
      Perhaps there is a way to make the addressee text block less wide thereby allowing it to be positioned further right.
      Alternatively, if I could center or right align the addressee text, that might just work.
      But I think one of your previous notes to me indicated that text alignment was not programmable.

    • John,

      The 4.75 inch limit is based on the 8.75 inch width of the envelope. If you increase the width you can also increase the value of AddressFromLeft. That appears to be the only solution. I don’t think the process checks to see if the envelope is actually the size specified, so you should be able to tell the process that the envelope is wider and force the address more to the right.

      I don’t see any way to center the address in the address block.

    • Yes, I tried that. Like I said, the net indent amount is always the same.
      If I increase the width by 1 inch, I can increase the left indent 1″. Net result is the same placement.
      For a width of 8.5 the max for AddressFromLeft is 4.5.
      For a width of 11, the max for AddressFromLeft is 7
      For a width of 6, the max for AddressFromLeft is 2. etc.
      I don’t have the command list. The program assumes the “envelope” is being fed by the end.
      Perhaps if I can add a line of code to rotate the “envelope” and feed it from the top I can gain more flexibility in text placement.
      It this has gotten too boring for you, I don’t expect you to do any more head scratching about it.
      Maybe you can just share where I can find the command list and/or tutorial.
      Meanwhile, thanks for all your time and interest.

    • John,

      You can find out all about Word’s envelope object here. This is the documentation for Office 2013. It’s not that this is boring or that I’m tired of participating, I’m just not sure that I can be of any additional help. The limitation seems to be baked into the product.

    • I’m delighted to have learned of this program-ability within Outlook. I’ve only made very fundamental use of scripting until now. I can see I am missing many shortcut opportunities. Thanks for the education. I will look into the link you provided.

      Before I sign off, do you have any insight into this request:
      Do you know of a way to reset a default setting in Excel? Whenever I launch the program, the “Find” function defaults to Within: “Sheet”. I would like to change that to “Workbook.” Would I do that with a macro that runs automatically with the launch of the program or a ResEdit change in the registry? Or am I completely off base here?

      Thanks!

    • John,

      You’re welcome.

      Keeping in mind that my area of expertise is Outlook, not Excel, to the best of my knowledge Excel doesn’t store that option setting in the registry. It appears to be hard-coded into Excel itself. I had to do some research to find a solution and the only solution I found is to use a macro like the following:

      Private Sub Workbook_Open()
          Application.CommandBars.FindControl(ID:=1849).Execute
          SendKeys "%(t)%(h)W~{ESC}"
      End Sub
      

      Note that this solution is from this page.

      I tested the solution on my system and it works. Give it a try and see if it works for you.

  1. Word doesn’t seem to have a preset “envelope” size for “invitation” envelopes which are 8.75w x 5.75h. Do you have a way to construct this custom size?

    Thank you. I’m delighted to have found your incredibly functional script.

  2. Wow! This is a wonderful solution.
    Just a couple of things, I can’t get the Company Name to work (I’m using Outlook 2013 so it may be slightly different).
    And I would like it to print to a different printer than my default one. It would permanently print to the other printer (that is, I don’t require an option to ‘select’ a printer).
    But even without these two tweaks, this is just brilliant! :)

    • Hi, Charlotte.

      Thanks! I appreciate that.

      The name of the field is CompanyName in Outlook 2013. I’ve modified the code to allow you to set the printer that the envelopes will print to. I also cleaned up the code that handles the company name. Please give this version a try and let me know if that’s what you wanted.

      Sub PrintEnvelope()
          'On the next line, edit your return address.  Use /n to indicate the end of a line.
          Const RETURN_ADDRESS = "David Lee/n101 Main Street/nHometown, USA 10101"
          'On the next line, edit the name of the printer you want envelopes to print to
          Const TARGET_PRINTER = "Bullzip PDF Printer"
          Const SCRIPT_NAME = "Print Envelope"
          Dim olkCon As Object, wrdApp As Object, wrdDoc As Object, strAddress As String, strPrinter As String
          Select Case TypeName(Application.ActiveWindow)
              Case "Explorer"
                  Set olkCon = Application.ActiveExplorer.Selection(1)
              Case "Inspector"
                  Set olkCon = Application.ActiveInspector.CurrentItem
          End Select
          If olkCon.Class <> olContact Then
              MsgBox "You must select a contact in order to use this macro.", vbCritical + vbOKOnly, SCRIPT_NAME
          Else
              If IsBlank(olkCon.CompanyName) Then
                  strAddress = olkCon.FullName & vbCrLf & olkCon.MailingAddress
              Else
                  strAddress = olkCon.FullName & vbCrLf & olkCon.CompanyName & vbCrLf & olkCon.MailingAddress
              End If
              Set wrdApp = CreateObject("Word.Application")
              strPrinter = wrdApp.ActivePrinter
              wrdApp.ActivePrinter = TARGET_PRINTER
              Set wrdDoc = wrdApp.Documents.Add
              With wrdDoc.Envelope
                  .Insert Address:=strAddress, ReturnAddress:=Replace(RETURN_ADDRESS, "/n", vbCrLf)
                  .PrintOut
              End With
              wrdDoc.Close False
              wrdApp.ActivePrinter = strPrinter
          End If
          Set olkCon = Nothing
          Set wrdDoc = Nothing
          Set wrdApp = Nothing
      End Sub
      
      Function IsBlank(strVal As String) As Boolean
          If Trim(strVal) = "" Then
              IsBlank = True
          End If
      End Function
      
    • David, that is just brilliant! I’ve added in my ancient ‘envelope’ printer and it’s working away like billyo!
      And you were so swift to respond. Thanks a million – it’s people like you that restores faith in humanity. A great script that will benefit many! :)
      Charlotte

    • I get a compile error: syntax error when I run the code.

      VBA highlights this line in blue:

      If olkCon.Class olContact Then

      Steve

    • Hi, David

      I copied the code from the April 15 reply.

      I’m getting errors on these lines:

      1. If olkCon.Class olContact Then

      Should I substitute an ‘=’ for ‘ ‘?

      2. Set wrdDoc = wrdApp.Documents.Add

      3. wrdDoc.Close False

      Thanks for the help, Steve

    • Hi, Steve.

      It sounds like something is going wrong when you copy and paste the code. Is it alright if I send you the code by email?

    • David,
      Is there a way to change the font size?

      Great addition to Outlook. Simple and Speedy

    • Hey, Steve.

      Thanks! I’m glad you like it.

      Sure. Yes, we can control the font for both the address and the return address. Use this version of the code to do that.

      Sub PrintEnvelope()
          'On the next line edit your return address.  Use /n to indicate the end of a line.
          Const RETURN_ADDRESS = "David Lee/n101 Main Street/nHometown, USA 10101"
          Const SCRIPT_NAME = "Print Envelope"
          Dim olkCon As Object, wrdApp As Object, wrdDoc As Object, strAddress As String
          Select Case TypeName(Application.ActiveWindow)
              Case "Explorer"
                  Set olkCon = Application.ActiveExplorer.Selection(1)
              Case "Inspector"
                  Set olkCon = Application.ActiveInspector.CurrentItem
          End Select
          If olkCon.Class <> olContact Then
              MsgBox "You must select a contact in order to use this macro.", vbCritical + vbOKOnly, SCRIPT_NAME
          Else
              strAddress = olkCon.FullName & vbCrLf & olkCon.MailingAddress
              Set wrdApp = CreateObject("Word.Application")
              Set wrdDoc = wrdApp.Documents.Add
              With wrdDoc.Envelope
                  .Insert Address:=strAddress, ReturnAddress:=Replace(RETURN_ADDRESS, "/n", vbCrLf)
                  'Control the font used for the address.  Comment out or remove the next 5 lines if you want to use the default font style.
                  With .AddressStyle.Font
                      .Bold = True
                      .Name = "Arial"
                      .Size = 14
                  End With
                  'Control the font used for the return address.  Comment out or remove the next 5 lines if you want to use the default font style.
                  With .ReturnAddressStyle.Font
                      .Bold = True
                      .Name = "Arial"
                      .Size = 14
                  End With
                  .PrintOut
              End With
              wrdDoc.Close False
          End If
          Set olkCon = Nothing
          Set wrdDoc = Nothing
          Set wrdApp = Nothing
      End Sub
      
    • Love the script. Love the modifications to specify printer and font specs. Next refinement, please: change envelope size. I take it “wrdDoc.Envelope” grabs a template by that name from Word. How can I specify a mail piece of a different size (e.g.: my promo post card)?

  3. Thank you very much indeed for this, it worked first time.
    Like a previous poster stated, I’ve been waiting for ages to do this!
    I wonder if I could ask :-
    If the contact has data in the ‘Company:’ field
    How could I include the ‘Company:’ in the address?
    Thanks once again.
    Mike

    • Hi, Mike.

      You’re welcome. Glad you found the solution useful.

      Yes, you can include the contents of the “company” field. To do that, edit line 15 of the code. For example, if you want the company name to come after the addressee’s name, then you’d change line 15 to this

      strAddress = olkCon.FullName & vbCrLf & olkCon.CompanyName & vbCrLf & olkCon.MailingAddress
      
    • Hello again,
      If the ‘Company:’ field is empty then a blank line is printed.
      Could I test the ‘Company:’ field to see if it is empty?
      Q1 Does the following work?
      If olkCon.CompanyName = “” Then ‘Test if the Company field is empty
      strAddress = olkCon.FullName & vbCrLf & olkCon.MailingAddress
      Else
      strAddress = olkCon.FullName & vbCrLf & olkCon.CompanyName & vbCrLf & olkCon.MailingAddress
      End If
      Q2 Or is this the correct way to test for an empty field?
      If olkCon.CompanyName = Empty

      Mike

    • Hi, Mike.

      There’s a problem with the syntax of the second approach. It should be

      If IsEmpty(olkCon.CompanyName) Then
      

      Other than that, you can use either approach. They both do essentially the same thing.

    • Thanks once again for your quick reply!

      I couldn’t get this line to work:-
      If IsEmpty(olkCon.CompanyName) Then
      It might me my implementaton though.

      BUT this line works a treat:-
      If olkCon.CompanyName = “” Then

      I am absolutely double pleased with this, it really is very useful, thanks again.

      Does this mean I am now a fully qualified VB programmer?

      Best Wishes

      Mike

    • IsEmpty should return True if the field’s value is uninitialized or has the value “empty”. I had forgotten that “Empty” as in

      If olkCon.CompanyName = Empty Then
      

      was a reserved word that compares a variable to its default value based on the variable’s type. For example, a string variable is “Empty” if it’s set to “”, while an integer variable is “Empty” if it’s set to 0. This makes

      If olkCon.CompanyName = Empty Then
      

      functionally equivalent to

      If olkCon.CompanyName = "" Then
      

      A better solution might be to create a function that test to see if the field is truly empty or if it is space filled (you wouldn’t want to include the company name if it contained one or more spaces). Perhaps something like

      Function IsBlank(strVal As String) As Boolean
          If Trim(strVal) = "" Then
              IsBlank = True
          End If
      End Function
      

      The test would then change to

      If IsBlank(olkCon.CompanyName) Then
      

      How about “VB programmer in training”? That’s how I think of myself. I’m still learning and picking things up here and there myself. There’s always someone out there who knows more, has found some clever way of doing things, etc.

      Cheers!

    • Hi, Art.

      I’m glad you like the solution. I can definitely handle selecting a printer. I’m not sure about picking a paper tray, but I’ll check into it.

    • Art,

      I should have asked how you want this to work. Do you want the macro to print to the same printer/tray all the time, or do you want the print dialog-box to appear so you can manually choose those options each time you run the macro?

    • I have a printer with an envelope feeder, is there a way to instruct the program to use that specific tray all the time?

    • Hi, Brian.

      That might be possible. I don’t happen to have a printer with an envelope feeder to test on, so the best I can do is suggest how to do it and let you try it out. Assuming that you’re using the code in the original post, try inserting this command

      wrdDoc.PageSetup.FirstPageTray = 5

      immediately after line 17. Once you’ve done that, try printing an envelope and let me know what happens.

  4. Thank you very much for this! I’ve been meaning to find out how to do this for like 10 years. Only thing to make it better, would be to have the choice of business size envelope or check envelope? (The doc doesn’t display before printing out, so there’s no chance to tweak the envelope size manually.)

    • Hi, Eileen.

      You’re welcome!

      You can set the envelope size by adding this command immediately after line 18 of the code in the post. To see which sizes are available open a document in Word, then select the Mailings tab. Click Envelopes, then click the Options button. Use the “Envelope size” pulldown to see the names of the different sizes. They’ll be things like “Size 10″, “C4″, and “US Legal”.

      'On the next line change "Size 10" to the size you want to use.
      .DefaultSize = "Size 10"
      

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s