A member of our Outlook-Users mailing list prepares birthday greetings ahead of time and sets them for deferred delivery.
My personal preference would be to use the macro at Send an email when an Appointment reminder fires because I am truly lazy (as any good Lazy Programmer should be :)) and could compose the message in the appointment and the time stamp would be on the birthday, not when I sent it to the Outbox. Plus, I would not be annoyed by the "you have unsent messages, do you really want to close Outlook" messages.
But that is just me... and this macro could be the basis for other useful purposes. You can use similar techniques to send contact data to Word documents or Merge to email using only Outlook, which uses bookmarks in a template to place the merge fields.
To change the "default" deferral time, see Set a default 'Do not Deliver before' time. While you can't change the default within Outlook, you can use VBA to set the deferral time automatically.
The code calculates the deferral date based on this year (Now) but checks to see if the birthday is in the past and if so, adds a year to the date. This will allow you to create the messages in December for January birthdays. If you always prepare the messages no more than 30 days prior to the birthday, you could use the following instead of the If bday < Now() Then block.
bday = DateSerial(Year(Now +30), Month(oContact.Birthday), Day(oContact.Birthday))
To customize the message or subject with the person's first name, use oContact.FirstName
objMsg.Subject = "Happy Birthday, " & oContact.FirstName
Defer delivery until a Contact's birthday
To use, open the VBA Editor using Alt+F11 and add this code to the ThisOutlookSession then create a toolbar button or ribbon command for it.
Select the contact and run the macro. A message form opens, addressed to the contact, set for deferred delivery as of 6 AM on the day of their birthday. You can either use objMsg.Display to display the message and add a note to it or use objMsg.Send to send it to the Outbox automatically.
Public Sub SendDeferredBirthdayGreetings() Dim bday If TypeName(ActiveExplorer.Selection.Item(1)) = "ContactItem" Then Set oContact = ActiveExplorer.Selection.Item(1) 'uses "this" year bday = DateSerial(Year(Now), Month(oContact.Birthday), Day(oContact.Birthday)) If bday < Now() Then 'add 1 year bday = DateSerial(Year(Now) + 1, Month(oContact.Birthday), Day(oContact.Birthday)) Else bday = bday + 0.25 ' sets it for 6 am the day of the birthday End If Dim objMsg As MailItem Set objMsg = Application.CreateItem(olMailItem) objMsg.To = oContact.Email1Address objMsg.Subject = "Happy Birthday" objMsg.Body = "Hope your day is a happy one!" objMsg.DeferredDeliveryTime = bday 'displays the message form so you can enter more text objMsg.Display 'use this to send to outbox 'objMsg.Send Set objMsg = Nothing Else MsgBox "Sorry, you need to select a contact" End If End Sub
Calculate the Contact's Age
You can calculate the contact's age and add it to the message or subject. (Do so at your own risk. :))
This requires you have the correct birth year in contacts.
age = DateDiff("yyyy", oContact.Birthday, bday) objMsg.To = oContact.Email1Address objMsg.Subject = "Happy " & age & " Birthday" objMsg.Body = "Hope your day is a happy one! May you enjoy the next " & age & " years as much as the last " & age & "!"
Use a Template
If you want to use a template, you need to replace the Set objMsg = Application.CreateItem(olMailItem) line with
Set objMsg = Application.CreateItemFromTemplate("C:\path\to\birthday-wishes.oft")
and remove the objMsg.Body line that adds text to the body. If you want to add a personalized first line and the template text, add & objMsg.Body to the end of the line so it copies the template text, like this:
objMsg.Body = "Hope your day is a happy one " oContact.FirstName & "!" & objMsg.body