Happy and code-full 2011!
In an earlier post, I was considering exporting my Outlook contacts as XHTML pages, and accessing these as a repository of free-format, but queryable, documents. After some time out for Christmas and New Year, not to mention my family’s seasonal cough-fest, I can report back.
I haven’t attempted a comprehensive export of all contact attributes, just the standard ones that I typically use. This still leaves information in the Contact’s body section, but I’ll migrate that manually, as and when.
Here’s an example contact page:
I just grabbed a standard style sheet, so the formatting is not up to much (for example, the cell text middle-aligns vertically, as you can see with “Address”).
In terms of the VBA code, all we need is an adapter class, ContactPage. Instances of this are created for each ContactItem that we export. A ContactPage is responsible for building the XHTML string corresponding to the ContactItem, and writing it out to a text file. Here’s the root procedure:
Const outdir As String = "C:\Temp\Contacts" Sub ExportContacts() Dim allcontacts As Items Set allcontacts = Session.Folders("Personal Folders"). _ Folders("Contacts").Items MsgBox "Exporting " & allcontacts.Count & " Contacts" Dim cn As ContactItem 'Outlook class Dim cp As ContactPage 'Custom class For Each cn In allcontacts Set cp = New ContactPage Set cp.Contact = cn 'Property Set cp.OutputToFile outdir Next End Sub
ContactPage has a function for PageTitle, which is taken from the ContactItem‘s Company or Full Name (in that order of preference). Functions PageId and PageFile are based on this (with a bit of cleaning up to remove characters such as ‘/’).
The sub OutputToFile uses the Microsoft Scripting Runtime library, specifically FileSystemObject and TextStream. You need to load the Scripting library manually, via >Tools >References.
The rest of ContactPage’s features are just functions that generate elements in the XHTML hierarchy. For example:
Public Function XhtmlPage() As String 'The XHTML representation of cp_contact XhtmlPage = Header_ & vbCrLf & _ Html_ End Function '... Public Function Html_() As String Html_ = "<html id=" & Chr(34) & PageId & Chr(34) '& ... Html_ = Html_ & vbCrLf & _ Head_ & vbCrLf & _ Body_ & vbCrLf & _ "</html>" End Function Public Function Body_() As String Body_ = "<body>" & vbCrLf & _ "<h1>" & PageTitle & "</h1>" & vbCrLf & _ Company_table_ & vbCrLf & _ Person_table_(1) & vbCrLf & _ Person_table_(2) & vbCrLf & _ Person_table_(3) & vbCrLf & _ Categories_ul_ & vbCrLf & _ "</body>" End Function '... Public Function LastName_td_() As String LastName_td_ = "<td class=" & Chr(34) & "LastName" & Chr(34) & ">" & _ cp_contact.LastName & "</td>" End Function
The lowest level functions, typically for <td> elements, access the ContactItem‘s properties. As you can see, there are a lot of quotation characters (Chr(34)) in XHTML. The trailing-underscore convention for the function names was so that I could call the functions after the XHTML tags they generate – without the underscore I got a name clash with something existing.
Minor complications where the Contacts folder contains Distribution Lists (class DistListItem), which is a different class from ContactItem – that is, a MAPIFolder.Items is a heterogeneous Collection. This makes the For Each loop throw a type mismatch error, although you can resume execution (>Debug, >Run).
Also a slight issue with duplicate filenames, since the file output overwrites by default. I used Round(Rnd * 1000, 0) to generate a temporary disambiguating suffiix for the filename.
Here’s the Class Module for ContactPage.