Windows IT Pro is the leading independent community for IT professionals deploying Microsoft Windows server and client applications and technologies.
  
  
  Advanced Search 


Return to article

Making Contact
 

Reestablish links to Outlook contacts after exporting a mailbox

Sooner or later, every administrator of a Microsoft Exchange Server 5.5 (or earlier) system needs to move a mailbox from one site or container to another. A classic solution is to export the entire mailbox to a personal store (.pst) file, add the new mailbox, then import the .pst data into the new mailbox. Alternatively, you can use the Microsoft BackOffice Resource Kit's Exmerge utility to help automate that process.

Many administrators discover only after the fact that exporting to a .pst file and importing into a new mailbox breaks all the links between Microsoft Outlook items and related contacts. (Moving items within a mailbox doesn't break the links, as importing and exporting does.) For example, if after importing you double-click a link in the Contacts box on a task item, you get the error message The name or distribution list has been deleted and is no longer a valid Address Book entry. The operation failed. An object could not be found.

The message is accurate if not particularly helpful. By exporting and importing, you've actually created new contact items, and Outlook no longer has the original contact items that you linked to. Outlook provides no way to reconnect the links to their related contact items, other than to retype the contact names in the Contacts box.

In most cases, you can restore the links with the VBA ReconnectLinks subroutine in Listing 1, page 110, which examines all the items in a folder that the user selects and attempts to find the related contacts in the user's default Contacts folder. The code gets the name of each link and tries to find a matching contact in the Contacts folder. If the code finds a match, it deletes the old link and creates a new link to that matching contact. (The code can't find links that the user might have made to contacts in a different folder; you'll still need to fix those manually.)

Reading Listing 1's code gives you a fine opportunity to learn about the Links collection, which stores all the connections to contacts and displays them in an Outlook item's Contacts box. (In an email message, you must click View, Options to see the Contacts box.)

If you look in the Object Browser (press F2 while you're working in VBA), you'll see that every Outlook item object (e.g., AppointmentItem, MailItem) supports a Links collection, even NoteItem (the Outlook equivalent of sticky notes). Like other collections, Links has a Count property that lets you know how many links the item has, and the three standard collection methods: Add, Item, and Remove.

To get an object reference to a particular Link object in the Links collection, you use the Item method. At callout A in Listing 1, the code gets the Count from the Links collection, then counts down from that number to 1, using the Item method to obtain each Link in turn.

The code counts down in a For ... Next loop instead of a For Each ... Next loop because later the code removes the broken Link objects. If you remove an item inside a For Each ...Next loop, you end up skipping items because the parent application resets the index counter. I start with the Link that has the highest index number and work down so that I can replace each one in turn. To remove a Link from the Links collection, you need to specify its index:

colLinks.Remove i

A user can simply type a name into the Contacts box and create a link, even if no matching contact exists. However, a program that needs to add a Link to the Links collection must first obtain a valid ContactItem object. The Add method requires a ContactItem as an argument:

colLinks.Add objContact

A Link object has two primary properties: Name and Item. If the link is connected to a valid Outlook contact, the Item property returns the linked ContactItem. In the case of disconnected links, however, trying to access the Item results in a runtime error because the link is broken. (That's why Listing 1 contains the On Error Resume Next statement.)

Even though the Item property causes a problem, the program can still get the value of the Name property. After a little experimentation, I found that the text that Outlook uses for the Name property for a Link object is the FullName property of the corresponding ContactItem. This clue is what you need to find the item in the current default Contacts folder that corresponds to the broken link. The code at callout B assumes that just one contact has that name and uses the Find method to locate that contact. The Find method returns the first match for the search string that you provide as an argument (strFind, in this example).

One caution about using the ReconnectLinks routine: Outlook has a known memory-leak problem when processing large Items collections in a For Each ... Next loop. If you have folders with thousands of items that need to be relinked, you might want to move a few hundred items at a time into a temporary folder, run ReconnectLinks, then move the items back into their original folder. Increasing your Windows pagefile size might also help you avoid the memory leak. The Microsoft article "OL2000: Memory or Performance Problems Looping Through Items" (http://support.microsoft.com/support/kb/articles/q293/7/96.asp) also suggests a possible solution if the items you need to process use custom forms.

To learn more about using the Links collection to link items to contacts, see the following Exchange & Outlook UPDATE newsletter articles at http://www.win2000mag.com: "Linking Outlook Contacts," InstantDoc ID 20353, and "More About Links," InstantDoc ID 20475.







Reader Comments

Change the vb code to allow for a manual pick of contacts folder, ie not hardcoded. If you have contacts stored in another folder, this is very appriciated.

Sub ReconnectLinks()
  Dim objApp As Application
  Dim objNS As NameSpace
  Dim objFolder As MAPIFolder
  Dim colItems As Items
  Dim objItem As Object
  Dim colLinks As Links
  Dim objLink As Link
  Dim colContacts As Items
  Dim objContact As ContactItem
  Dim strFind As String
  Dim intCount As Integer
  Dim myFolder1 As MAPIFolder


  Set objApp = CreateObject("Outlook.Application")
  Set objNS = objApp.GetNamespace("MAPI")
  'set contacts folder
  Set myFolder1 = objNS.PickFolder
  'set tasks folder
  Set objFolder = objNS.PickFolder
  If TypeName(objFolder) <> "Nothing" Then
    'Set colContacts = objNS.GetDefaultFolder(olFolderContacts).Items     Set colContacts = myFolder1.Items
    Set colItems = objFolder.Items
    For Each objItem In colItems

      Set colLinks = objItem.Links
      intCount = colLinks.Count
      If intCount > 0 Then
        For i = intCount To 1 Step -1
          Set objLink = colLinks.Item(i)
          On Error Resume Next

          If objLink.Item Is Nothing Then

            strFind = "[FullName] = " & AddQuotes(objLink.Name)
            Set objContact = colContacts.Find(strFind)

            If Not objContact Is Nothing Then
            ' remove the old link
            colLinks.Remove i
            ' add the replacement link
            colLinks.Add objContact
            End If
          End If
        Next
        If Not objItem.Saved Then
          objItem.Save
        End If
      End If
    Next
  End If

  Set objLink = Nothing
  Set colLinks = Nothing
  Set objItem = Nothing
  Set objItems = Nothing
  Set objFolder = Nothing
  Set objNS = Nothing
    Set objApp = Nothing
End Sub

Private Function AddQuotes(MyText) As String
    AddQuotes = Chr(34) & MyText & Chr(34)
End Function

Göran Eriksson -October 10, 2002

Running XP Home Edition with XP Office Pro: Gave very erratic results -- some worked, others didn't. Blanked out names, etc. Changed the REGISTRY as suggested, but there was no difference. Standard form replaced custom form here and there, etc.

norm hadley -June 29, 2003

Hello! I was very pleased to find this article, since the hundreds of links in my OL2002 .pst file were lost when I was required to export/import everything to fix another problem. However, not being a Visual Basic expert, I can't figure out how to actually run the code you provide with this article. I tried renaming the .txt file to .vbs and that didn't work. Can you tell me how to run the code? Thank you!

Don Ferguson -November 28, 2003

Goran, take a look at the Namespace.PickFolder method, which returns a MAPIFolder that the user selects.

Sue Mosher -January 28, 2004

Don, copy and paste the code from the .txt file into an Outlook VBA module. If you need really, really basic info, see http://www.win2000mag.com/Articles/Index.cfm?ArticleID=21522

Sue Mosher -January 28, 2004

Hi Sue Mosher, I see that Object Link name doesn't contain the Preffix Name, In this case the script doesn't work because objLink.Name <> FullName. So one suggestion is to parse ObjLink.name into FirstName, MiddleName, LastName and use them as criteria for search. I hope this is not just an error in My outlook contacts. Thanks for your Article.

Alami -April 07, 2004

I ran the script, but nothing seems to happen. The script says it's running and finishes in less than 30 seconds. I have thousands of contacts so I expected it to run for a while. The error is not fixed after running the script. I'm running OL 2000 SP-3 under Win2K. I ran the script by importing it into OL's VB engine, using Run Macro, and clicking my Contacts folder. Do I need to do anything else?

Robert -July 07, 2004

I found another fix that worked perfectly: http://support.microsoft.com/?kbid=242074 This is a utility to clear OL's nickname cache.

Robert -July 07, 2004

Check out this great tutorial on using Microsoft Outlook for managing your ebay & amazon sales, or use it as an Outlook programming quickstart: http://www.321books.co.uk/ebooks/outlook-vba-tutorial.htm

mal4mac -September 17, 2004
Windows IT Pro Home Register FAQ for Windows WinInfo News
Europe Edition About Us Contact Us/Customer Service Media Kit Affiliates / Licensing  
SQL Server Magazine Office & SharePoint Pro DevProConnections IT Job Hound
Left-Brain.com Technology Resource Directory asp.netPRO ITTV Windows SuperSite 
 
 Windows IT Pro is a Division of Penton Media Inc.
 © 2009 Penton Media, Inc. Terms of Use | Privacy Statement