When you have a good overview of all your contact details in an Excel file, it can be useful to export these towards Outlook (eg to allow automatic synchronization towards your mobile). When including contact pictures, the look and feel of Outlook and your mobile increases a lot by immediately showing the related pictures when receiving a mail or call.
Since the contact details can change over time, I created the Excel macro below to update existing contacts and create the non existing contact within Outlook, including all available details of the contact.
Using a ‘Reference’ sheet, in which the columns are references using a named cell, it’s easy to retrieve the contact details from the right column, while still being able to easily change the data or order. The data is retrieved using the Cells.Range option, eg: Sheets(sheetName).Cells(i, Sheets("References").Range("columnname").Value)
In order to make sure the same contact is not added multiple times, the contact is first retrieved from the available Outlook contacts using the olFolder.Item.Restrict(…filter…) option based on the email address of the contact.
Since I load the contact details from a DB using a linked Query within Excel, I also refresh the query data before performing the migration from Excel to Outlook.
All details can be found in the macro source below and the example Excel file (including the macro).
'Developed by myT, http://myTselection.blogspot.com
Option Explicit
Public Sub RefreshQueries()
Dim wks As Worksheet
Dim qt As QueryTable
Dim lo As ListObject
For Each wks In Worksheets
For Each qt In wks.QueryTables
qt.Refresh BackgroundQuery:=False
Next qt
For Each lo In wks.ListObjects
lo.QueryTable.Refresh BackgroundQuery:=False
Next lo
Next wks
Set qt = Nothing
Set wks = Nothing
End Sub
'http://www.globaliconnect.com/excel/index.php?option=com_content&view=article&id=167:import-contacts-from-excel-to-outlook-automate-in-vba&catid=79&Itemid=475
Sub ExcelWorksheetDataAddToOutlookContacts()
'Automating Outlook from Excel: This example uses the Items.Add Method to export data from an Excel Worksheet to the default Contacts folder.
'Automate Outlook from Excel, using Late Binding. You need not add a reference to the Outlook library in Excel (your host application), in this case you will not be able to use the Outlook's predefined constants and will need to replace them by their numerical values in your code.
Dim oApplOutlook As Object
Dim oNsOutlook As Object
Dim oCFolder As Object
Dim oDelFolder As Object
Dim oCItem As Object
'Dim olItems As Outlook.Items
Dim olItems As Object
'Dim olContactItem As contactItem
Dim olContactItem As Object
Dim oDelItems As Object
Dim lLastRow As Long, i As Long, n As Long, c As Long
Dim firstRowToProcess As Integer, emailColumn As Integer, pictureColumn As Integer, processedColumn As Integer, itemsFound As Integer
Dim sheetName As String, fullFilePath As String
Dim updateExistingContacts As Boolean
RefreshQueries
'Config:
sheetName = "Contacts"
firstRowToProcess = 2
updateExistingContacts = False
updateExistingContacts = MsgBox("Update and overwrite fields of existing contacts? Pictures will always be updated. (Existing notes will be appended, not overwritten)", vbYesNo, "Overwrite")
Application.ScreenUpdating = False
' turns off screen updating
Application.DisplayStatusBar = True
' makes sure that the statusbar is visible
Application.StatusBar = "Preparing export contacts to Outlook"
'determine last data row in the worksheet:
lLastRow = Sheets(sheetName).Cells(Rows.Count, "A").End(xlUp).Row
'Create a new instance of the Outlook application, if an existing Outlook object is not available.
'Set the Application object as follows:
On Error Resume Next
Set oApplOutlook = GetObject(, "Outlook.Application")
'if an instance of an existing Outlook object is not available, an error will occur (Err.Number = 0 means no error):
If Err.Number <> 0 Then
Set oApplOutlook = CreateObject("Outlook.Application")
End If
'disable error handling:
On Error GoTo 0
'use the GetNameSpace method to instantiate (ie. create an instance) a NameSpace object variable, to access existing Outlook items. Set the NameSpace object as follows:
Set oNsOutlook = oApplOutlook.GetNamespace("MAPI")
'----------------------------
'Empty the Deleted Items folder in Outlook so that when you quit the Outlook application you bypass the prompt: Are you sure you want to permanently delete all the items and subfolders in the "Deleted Items" folder?
'set the default Deleted Items folder:
' 'The numerical value of olFolderDeletedItems is 3. The following code has replaced the Outlook's built-in constant olFolderDeletedItems by its numerical value 3.
' Set oDelFolder = oNsOutlook.GetDefaultFolder(3)
' 'set the items collection:
' Set oDelItems = oDelFolder.Items
'
' 'determine number of items in the collection:
' c = oDelItems.Count
' 'start deleting from the last item:
' For n = c To 1 Step -1
' oDelItems(n).Delete
' Next n
'
'----------------------------
'set reference to the default Contact Items folder:
'The numerical value of olFolderContacts is 10. The following code has replaced the Outlook's built-in constant olFolderContacts by its numerical value 10.
Set oCFolder = oNsOutlook.GetDefaultFolder(10)
' Set olItems = oCFolder.Items.Restrict("[MessageClass]='IPM.Contact'")
'Find contact to update, if not found add a new contact item
'post each row's data on a separate contact item form:
For i = firstRowToProcess To lLastRow
'restrict info: https://msdn.microsoft.com/en-us/vba/outlook-vba/articles/items-restrict-method-outlook
'folder items info: https://msdn.microsoft.com/en-us/vba/outlook-vba/articles/folder-items-property-outlook
Set olItems = oCFolder.Items.Restrict("[MessageClass]='IPM.Contact' And [Email1Address] = '" & Sheets(sheetName).Cells(i, Sheets("References").Range("email").Value) & "'")
itemsFound = 0
For Each olContactItem In olItems
Application.StatusBar = "Updating Outlook contact " + olContactItem.FullName & ", " & Sheets(sheetName).Cells(i, Sheets("References").Range("pnr").Value)
'matching contact found in Outlook and Excel
'web pictures should be stored in a local folder
fullFilePath = Replace(Sheets(sheetName).Cells(i, Sheets("References").Range("pictureurl").Value), "http://someimageurl", "C:\Users\username\Documents\Pictures\profilephotos\")
If FileExists(fullFilePath) Then
olContactItem.AddPicture (fullFilePath)
Else
'MsgBox ("Missing picture: " + fullFilePath + ", for member: " + olContactItem.firstName + " " + olContactItem.lastname)
Debug.Print ("Missing picture: " & fullFilePath & ", for member: " & olContactItem.firstName & " " & olContactItem.lastName)
End If
If updateExistingContacts = True Then
With olContactItem
'update existing contact fields https://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook._contactitem_properties.aspx
.firstName = Sheets(sheetName).Cells(i, Sheets("References").Range("first_name").Value)
.lastName = Sheets(sheetName).Cells(i, Sheets("References").Range("last_name").Value)
If (Sheets(sheetName).Cells(i, Sheets("References").Range("birthdate").Value) <> "") Then
.Birthday = DateValue(Sheets(sheetName).Cells(i, Sheets("References").Range("birthdate").Value))
End If
.BusinessAddressStreet = "BusinessStreet 100"
.BusinessAddressCity = "BusinessCity"
.BusinessAddressCountry = "BusinessCountry"
.BusinessAddressPostalCode = "BusinessPostal"
.BusinessHomePage = "http://www.company.com"
'do not remove or duplicate existing categories, set some desired category when not yet set
If (InStr(.Categories, "Business") = 0) Then
.Categories = .Categories & ",Business"
End If
.CompanyName = "Company"
.Email1DisplayName = Sheets(sheetName).Cells(i, Sheets("References").Range("email").Value)
.FullName = Sheets(sheetName).Cells(i, Sheets("References").Range("first_name").Value) & " " & Sheets(sheetName).Cells(i, Sheets("References").Range("last_name").Value)
.FileAs = Sheets(sheetName).Cells(i, Sheets("References").Range("first_name").Value) & " " & Sheets(sheetName).Cells(i, Sheets("References").Range("last_name").Value)
'.gender = Sheets(sheetName).Cells(i, Sheets("References").Range("gender").Value)
' If (Sheets(sheetName).Cells(i, Sheets("References").Range("gender").Value) = "M") Then
' .gender = Microsoft.Office.Interop.Outlook.OlGender.olMale
' ElseIf (Sheets(sheetName).Cells(i, Sheets("References").Range("gender").Value) = "F") Then
' .gender = Microsoft.Office.Interop.Outlook.OlGender.olFemale
' Else
' .gender = Microsoft.Office.Interop.Outlook.OlGender.olUnspecified
' End If
.HomeAddressCity = Sheets(sheetName).Cells(i, Sheets("References").Range("city").Value)
.HomeAddressCountry = "DefaultCountry"
.HomeAddressPostalCode = Sheets(sheetName).Cells(i, Sheets("References").Range("postcode").Value)
.HomeAddressStreet = Sheets(sheetName).Cells(i, Sheets("References").Range("street").Value) & " " & Sheets(sheetName).Cells(i, Sheets("References").Range("street_number").Value)
.JobTitle = Sheets(sheetName).Cells(i, Sheets("References").Range("current_function").Value)
'.Language = Sheets(sheetName).Cells(i, Sheets("References").Range("speaking_language_info_list").Value)
.MobileTelephoneNumber = Sheets(sheetName).Cells(i, Sheets("References").Range("mobile").Value)
.BusinessTelephoneNumber = Sheets(sheetName).Cells(i, Sheets("References").Range("phone").Value)
.BusinessFaxNumber = Sheets(sheetName).Cells(i, Sheets("References").Range("fax").Value)
.Department = Sheets(sheetName).Cells(i, Sheets("References").Range("division").Value)
.ManagerName = Sheets(sheetName).Cells(i, Sheets("References").Range("manager").Value)
.WebPage = "http://www.company.com"
If (InStr(.body, "Staff number: ") = 0) Then
.body = "Staff number: " & Sheets(sheetName).Cells(i, Sheets("References").Range("pnr").Value) & vbCrLf
.body = .body & "Recruitment date: " & Sheets(sheetName).Cells(i, Sheets("References").Range("recruitment_date").Value) & vbCrLf
.body = .body & "Education: " & Sheets(sheetName).Cells(i, Sheets("References").Range("educations").Value) & vbCrLf
.body = .body & "Languages: " & Sheets(sheetName).Cells(i, Sheets("References").Range("speaking_language_info_list").Value) & vbCrLf
.body = .body & "Specialty skills: " & Sheets(sheetName).Cells(i, Sheets("References").Range("specialty_skills").Value) & vbCrLf
' Else
' keeps original body note, but duplicates all data if run mulitple times
' originalBody = .body
' .body = "Staff number: " & Sheets(sheetName).Cells(i, Sheets("References").Range("pnr").Value) & vbCrLf
' .body = .body & "Recruitment date: " & Sheets(sheetName).Cells(i, Sheets("References").Range("recruitment_date").Value) & vbCrLf
' .body = .body & "Education: " & Sheets(sheetName).Cells(i, Sheets("References").Range("educations").Value) & vbCrLf
' .body = .body & "Languages: " & Sheets(sheetName).Cells(i, Sheets("References").Range("speaking_language_info_list").Value) & vbCrLf
' .body = .body & "Specialty skills: " & Sheets(sheetName).Cells(i, Sheets("References").Range("specialty_skills").Value) & vbCrLf
' .body = .body & vbCrLf & originalBody
End If
End With
End If
Sheets(sheetName).Cells(i, Sheets("References").Range("processed").Value).Value = "OK"
olContactItem.Save
itemsFound = itemsFound + 1
Next
If itemsFound = 0 Then
Application.StatusBar = "Adding Outlook contact " & Sheets(sheetName).Cells(i, Sheets("References").Range("first_name").Value) & " " & Sheets(sheetName).Cells(i, Sheets("References").Range("last_name").Value) & ", " & Sheets(sheetName).Cells(i, Sheets("References").Range("pnr").Value)
'Using the Items.Add Method to create a new Outlook contact item in the default Contacts folder.
Set oCItem = oCFolder.Items.Add
'display the new contact item form:
'oCItem.Display
'set properties of the new contact item:
With oCItem
'update existing contact fields https://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook._contactitem_properties.aspx
.firstName = Sheets(sheetName).Cells(i, Sheets("References").Range("first_name").Value)
.lastName = Sheets(sheetName).Cells(i, Sheets("References").Range("last_name").Value)
If (Sheets(sheetName).Cells(i, Sheets("References").Range("birthdate").Value) <> "") Then
.Birthday = DateValue(Sheets(sheetName).Cells(i, Sheets("References").Range("birthdate").Value))
End If
.BusinessAddressStreet = "BusinessStreet 100"
.BusinessAddressCity = "BusinessCity"
.BusinessAddressCountry = "BusinessCountry"
.BusinessAddressPostalCode = "BusinessPostal"
.BusinessHomePage = "http://www.company.com"
'do not remove or duplicate existing categories, set some desired category when not yet set
If (InStr(.Categories, "Business") = 0) Then
.Categories = .Categories & ",Business"
End If
.CompanyName = "Company"
.Email1DisplayName = Sheets(sheetName).Cells(i, Sheets("References").Range("email").Value)
.FullName = Sheets(sheetName).Cells(i, Sheets("References").Range("first_name").Value) & " " & Sheets(sheetName).Cells(i, Sheets("References").Range("last_name").Value)
.FileAs = Sheets(sheetName).Cells(i, Sheets("References").Range("first_name").Value) & " " & Sheets(sheetName).Cells(i, Sheets("References").Range("last_name").Value)
'.gender = Sheets(sheetName).Cells(i, Sheets("References").Range("gender").Value)
' If (Sheets(sheetName).Cells(i, Sheets("References").Range("gender").Value) = "M") Then
' .gender = Microsoft.Office.Interop.Outlook.OlGender.olMale
' ElseIf (Sheets(sheetName).Cells(i, Sheets("References").Range("gender").Value) = "F") Then
' .gender = Microsoft.Office.Interop.Outlook.OlGender.olFemale
' Else
' .gender = Microsoft.Office.Interop.Outlook.OlGender.olUnspecified
' End If
.HomeAddressCity = Sheets(sheetName).Cells(i, Sheets("References").Range("city").Value)
.HomeAddressCountry = "DefaultCountry"
.HomeAddressPostalCode = Sheets(sheetName).Cells(i, Sheets("References").Range("postcode").Value)
.HomeAddressStreet = Sheets(sheetName).Cells(i, Sheets("References").Range("street").Value) & " " & Sheets(sheetName).Cells(i, Sheets("References").Range("street_number").Value)
.JobTitle = Sheets(sheetName).Cells(i, Sheets("References").Range("current_function").Value)
'.Language = Sheets(sheetName).Cells(i, Sheets("References").Range("speaking_language_info_list").Value)
.MobileTelephoneNumber = Sheets(sheetName).Cells(i, Sheets("References").Range("mobile").Value)
.BusinessTelephoneNumber = Sheets(sheetName).Cells(i, Sheets("References").Range("phone").Value)
.BusinessFaxNumber = Sheets(sheetName).Cells(i, Sheets("References").Range("fax").Value)
.Department = Sheets(sheetName).Cells(i, Sheets("References").Range("division").Value)
.ManagerName = Sheets(sheetName).Cells(i, Sheets("References").Range("manager").Value)
.WebPage = "http://www.company.com"
If (InStr(.body, "Staff number: ") = 0) Then
.body = "Staff number: " & Sheets(sheetName).Cells(i, Sheets("References").Range("pnr").Value) & vbCrLf
.body = .body & "Recruitment date: " & Sheets(sheetName).Cells(i, Sheets("References").Range("recruitment_date").Value) & vbCrLf
.body = .body & "Education: " & Sheets(sheetName).Cells(i, Sheets("References").Range("educations").Value) & vbCrLf
.body = .body & "Languages: " & Sheets(sheetName).Cells(i, Sheets("References").Range("speaking_language_info_list").Value) & vbCrLf
.body = .body & "Specialty skills: " & Sheets(sheetName).Cells(i, Sheets("References").Range("specialty_skills").Value) & vbCrLf
End If
End With
'mark as done
Sheets(sheetName).Cells(i, Sheets("References").Range("processed").Value).Value = "OK"
fullFilePath = Replace(Sheets(sheetName).Cells(i, Sheets("References").Range("pictureurl").Value), "http://someimageurl", "C:\Users\username\Documents\Pictures\profilephotos\")
If FileExists(fullFilePath) Then
oCItem.AddPicture (fullFilePath)
Else
'MsgBox ("Missing picture: " + fullFilePath + ", for member: " + oCItem.firstName + " " + oCItem.lastname)
Debug.Print ("Missing picture: " & fullFilePath + ", for member: " & oCItem.firstName & " " & oCItem.lastName)
End If
'close the new contact item form after saving:
'The numerical value of olSave is 0. The following code has replaced the Outlook's built-in constant olSave by its numerical value 0.
oCItem.Close 0
End If
Next i
'quit the Oulook application:
oApplOutlook.Quit
Application.StatusBar = "Outlook " & lLastRow & " contacts exported"
Application.ScreenUpdating = True
'clear the variables:
Set oApplOutlook = Nothing
Set oNsOutlook = Nothing
Set oCFolder = Nothing
Set oDelFolder = Nothing
Set oCItem = Nothing
Set oDelItems = Nothing
Set olContactItem = Nothing
Set olItems = Nothing
MsgBox "Successfully Exported Worksheet Data to the Default Outlook Contacts Folder."
End Sub
Function FileExists(fullFileName As String) As Boolean
FileExists = VBA.Len(VBA.Dir(fullFileName)) > 0
End Function