button to send and print emails

Status
Not open for further replies.

mdarnold

Member
Outlook version
Outlook 2010 64 bit
Email Account
Exchange Server
Hi,

I'm a novice to VBA, however I'm working on a button to provide an option to send and print emails with a click of the button. I want all of the header information included in the printouts (such as the date it was sent), so I can only print the emails after they have actually been sent (i.e. moved from the outbox to the sent items folder).

I set up a macro and added a button to the ribbon to assign a "print" category to all outgoing emails when I click the button. The code is as follows:

Code:
Sub SendPrint() 
 
Dim obj 
 
Dim oCategory As Outlook.Category 
 
Set obj = ActiveInspector.CurrentItem 
 
Set objOL = CreateObject("Outlook.Application") 
 
If Not objOL.ActiveInspector Is Nothing Then 
 
Set objItem = objOL.ActiveInspector.CurrentItem 
 
objItem.Categories = "print" 
 
End If 
 
obj.Send 
 
End Sub
I need code to process any items added to the Sent Items folder to look for the "Print" category, print the email if the category is present.

I tried using the following code, which I found on the web, and modified for my needs, but it didn't work:

Code:
Private WithEvents Items As Outlook.Items 
 
Private Sub Application_Startup()
 Dim Ns As Outlook.NameSpace
 Set Ns = Application.GetNamespace("MAPI")
 Set Items = Ns.GetDefaultFolder(olFolderSentItems).Items 
 
End Sub 
 
Private Sub Items_ItemAdd(ByVal Item As Object)
 If TypeOf Item Is Outlook.MailItem Then
   PrintNewItem Item
 End If 
 
End Sub 
 
Private Sub PrintNewItem(Mail As Outlook.MailItem)
 On Error Resume Next
 If MailItem.Categories Is "Print" Then
   Mail.PrintOut
 End If 
 
End Sub
I tried entering it as a module, but after some digging I found that it needed to be entered as a class module. So I entered it as a class module, however it's still not working. Can someone help? I'm using Office 2010 64-bit.

After I get that part working, I'd like to add another line of code to remove the "Print" category from the printed email, just to clean up the process a little bit.

Thanks,

Mark
 

mdarnold

Member
Outlook version
Outlook 2010 64 bit
Email Account
Exchange Server
Also tried adding the following code to ThisOutlookSession, which seemed straightforward enough:

Code:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
   If TypeOf Item Is Outlook.MailItem And Item.Categories = "Print" Then
       Mail.PrintOut
   End If 
 
End Sub
It also didn't work. :/
 

mdarnold

Member
Outlook version
Outlook 2010 64 bit
Email Account
Exchange Server
Yes, the message will be assigned with the "Trash" category when it is sent to the outbox (and then the Sent Items folder).
I meant "print " category. I didn't see an option to edit my post.
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
I knew what you meant. I'm going to test and see what needs fixed.
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
Also tried adding the following code to ThisOutlookSession, which seemed straightforward enough:

Code:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
   If TypeOf Item Is Outlook.MailItem And Item.Categories = "Print" Then
       Mail.PrintOut
   End If 
 
End Sub
It also didn't work. :/
this one worked for me, once i set macro security to low and restarted outlook (it's a new test system)... I thought i had it printing to onenote or pdf, not a paper printer though.... good thing the message was short.
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
one thing to keep in mind - you can only use 1 category. If you use 2 or more, you need use look for print in the category string.

I only tested the last macro.
 

mdarnold

Member
Outlook version
Outlook 2010 64 bit
Email Account
Exchange Server
this one worked for me, once i set macro security to low and restarted outlook (it's a new test system)... I thought i had it printing to onenote or pdf, not a paper printer though.... good thing the message was short.
one thing to keep in mind - you can only use 1 category. If you use 2 or more, you need use look for print in the category string.

I only tested the last macro.
It's not working for me.

Here's exactly what I did. I have these two codes in 'ThisOutlookSession':

Code:
Sub SendPrint() 
 
Dim obj 
 
Dim oCategory As Outlook.Category 
 
Set obj = ActiveInspector.CurrentItem 
 
Set objOL = CreateObject("Outlook.Application") 
 
If Not objOL.ActiveInspector Is Nothing Then 
 
Set objItem = objOL.ActiveInspector.CurrentItem 
 
objItem.Categories = "print" 
 
End If 
 
obj.Send 
 
End Sub
Code:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
   If TypeOf Item Is Outlook.MailItem And Item.Categories = "Print" Then
       Mail.PrintOut
   End If 
 
End Sub
I made a button on the new email ribbon, pointing to the .ThisOutlookSession.SendPrint macro

I restarted Windows 7.

Booting windows 7 and outlook 2010 back up, I ensured my macro settings were set to 'enable all macros'.

I composed an email to myself, sending it by clicking the new button I made.

I looked in my sent box and saw my email with the 'print' category. No print action had occurred.

I received the email I sent myself.

Is there anything different in how you tested it? Thanks for your help.
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
I went into Options, set the category then sent the message. So the second macro does work - it just doesn't work with the code that adds the category and sends in one step.

Try adding obj.Save to the SendPrint code so its saved as a draft before sending - I'll also test it using that macro to send.
 

mdarnold

Member
Outlook version
Outlook 2010 64 bit
Email Account
Exchange Server
I went into Options, set the category then sent the message. So the second macro does work - it just doesn't work with the code that adds the category and sends in one step.

Try adding obj.Save to the SendPrint code so its saved as a draft before sending - I'll also test it using that macro to send.
I found the mistake in my code. I sheepishly discovered that I was assigning a lowercase 'print' category, and looking for an uppercase 'Print' category. Oops.

The second code is now picking up the Print category, but I now get the error "Run-time error '424': Object Required", and the debugger points to the "Mail.PrintOut" line.

What's gone wrong? How can I guide the code to the object? Thanks!
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
Oh, and one more thing - the printout line needs to be item.printout. I'm surprised you didn't get an error on it.

Item.PrintOut

Oh, two things - the category name is case sensitive. You could make it case insensitive using lcase("print") but it's not necessary since the code is doing it.
it turns out save isn't necessary.

A base minimum code sample is

Code:
Sub SendPrint() 
 
Dim obj 
 
Dim oCategory As Outlook.Category 
 
Set obj = ActiveInspector.CurrentItem 
 
obj.Categories = "Print" 
 
obj.Send 
 
End Sub 
 
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
   If TypeOf Item Is Outlook.MailItem And Item.Categories = "Print" Then
       Item.PrintOut
   End If 
 
End Sub
 

mdarnold

Member
Outlook version
Outlook 2010 64 bit
Email Account
Exchange Server
Oh, and one more thing - the printout line needs to be item.printout. I'm surprised you didn't get an error on it.

Item.PrintOut

Oh, two things - the category name is case sensitive. You could make it case insensitive using lcase("print") but it's not necessary since the code is doing it.
it turns out save isn't necessary.
Thank-you, I did run into the Item.PrintOut error, after I got that macro working. It wouldn't reach that point in the code previously because my category was in lowercase.

So it works, but it doesn't do what I need it to do. The message is printing before the message is actually sent, so the header information concerning the date the message was sent is not present. I need the code to monitor the sent items folder for incoming messages with a 'Print' category.

I tried using the other code I was working with earlier, but it just causes my outlook to freeze.

I inserted it as a class module:
Code:
Private WithEvents Items As Outlook.Items 
 
Private Sub Application_Startup()
 Dim Ns As Outlook.NameSpace
 Set Ns = Application.GetNamespace("MAPI")
 Set Items = Ns.GetDefaultFolder(olFolderSentItems).Items 
 
End Sub 
 
Private Sub Items_ItemAdd(ByVal Item As Object)
 If TypeOf Item Is Outlook.MailItem Then
   PrintNewItem Item
 End If 
 
End Sub 
 
Private Sub PrintNewItem(Mail As Outlook.MailItem)
 On Error Resume Next
 If MailItem.Categories Is "Print" Then
   Mail.PrintOut
 End If 
 
End Sub
Any ideas?
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
Your code prints the draft. If you want to print the sent message, use this (assuming you have only one account/one sent folder as it looks at the default sent folder) - you'll use your button to add the category and send then the itemadd macro watches for items with the category to be added to the sent item folder and prints.

Code:
Option Explicit 
 
Private WithEvents Items As Outlook.Items 
 
Private Sub Application_Startup() 
 
Set Items = Session.GetDefaultFolder(olFolderSentMail).Items 
 
End Sub 
 
Private Sub Items_ItemAdd(ByVal Item As Object)
  If Item.Categories = "Print" Then
     Item.PrintOut
  End If 
 
End Sub 
 
Sub SendPrint() 
 
Dim obj 
 
Dim oCategory As Outlook.Category 
 
Set obj = ActiveInspector.CurrentItem 
 
obj.Categories = "Print" 
 
obj.Send 
 
End Sub
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
LOL we both think alike.

You can put the entire block of code into ThisOutlookSession - Application_startup and the private withevents line needs to be in it for sure though. Click in the app startup code and click Run so you can test without restarting outlook.

If you want to test for mailitem, you can use this - but unless you send a lot of non-mail items, that is not necessary - you are only printing if the category matches and I assume you won't use print category on non-mail items.

Private Sub Items_ItemAdd(ByVal Item As Object)
If TypeOf Item Is Outlook.MailItem Then
If Item.Categories Is "Print" Then
Item.PrintOut
End If
End If

End Sub
 

mdarnold

Member
Outlook version
Outlook 2010 64 bit
Email Account
Exchange Server
Your code prints the draft. If you want to print the sent message, use this (assuming you have only one account/one sent folder as it looks at the default sent folder) - you'll use your button to add the category and send then the itemadd macro watches for items with the category to be added to the sent item folder and prints.
Thank-you so much Diane. I added a line to remove the category before it prints. It works beautifully.

Code:
Option Explicit 
 
Private WithEvents Items As Outlook.Items 
 
Private Sub Application_Startup() 
 
Set Items = Session.GetDefaultFolder(olFolderSentMail).Items 
 
End Sub 
 
Private Sub Items_ItemAdd(ByVal Item As Object)
  If Item.Categories = "Printed" Then
     Item.Categories = ""
     Item.PrintOut
  End If 
 
End Sub 
 
Sub SendPrint() 
 
Dim obj 
 
Dim oCategory As Outlook.Category 
 
Set obj = ActiveInspector.CurrentItem 
 
obj.Categories = "Printed" 
 
obj.Send 
 
End Sub
 

mdarnold

Member
Outlook version
Outlook 2010 64 bit
Email Account
Exchange Server
The macro has worked great, but I've ran into a glitch. In my default print style I have the footer set up to print the page numbers as 'Page [Page #] of [Total Pages]'.

Whenever I print out an email using my send + print button, the pagination is in the format "Page x of 0" (It detects the Total Pages as zero for some reason). When I print normally I don't have this issue. Is there a way to modify the code have it detect to proper amount of total pages?
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
I'm pretty sure that is just outlook being stupid, but I'm checking on it.
 

mdarnold

Member
Outlook version
Outlook 2010 64 bit
Email Account
Exchange Server
I'm pretty sure that is just outlook being stupid, but I'm checking on it.
Have you had time to look into this Diane? I was wondering if a workaround would be to use VBA to paginate instead of using the page style print options, however I have no idea how to do this, or if it's even possible. Do you think that would work?
 

Forum Admin

Senior Member
Yes, I did, but got side tracked with end-of-summer stuff. :( It is a limitation when using code to print. Email doesn't have pages so the length is determined by the printer driver but vba hooks in to the process after that point. It can count the pages as it prints but not calculate the total.
 
Status
Not open for further replies.
Top