I am using VBA to manipulate the global address book in Outlook. My method takes a contact and returns a complete list of everyone who reports through that person based on the Outlook org structure.
Unfortunately it takes quite some time to run, even for a single manager. I'm not really sure what is the best way to improve the performance here - it sees the getDirectReports
method takes some time, but, I don't see an easy way to determine if a user has reports prior to calling it first.
Public Sub printAllReports()
Dim allReports As Collection
Set allReports = New Collection
Dim curLevelReports As Collection
Set curLevelReports = New Collection
Dim nextLevelReports As Collection
Set nextLevelReports = New Collection
Dim myTopLevelReport As ExchangeUser
'this method returns an exchange user from their "outlook name"
Set myTopLevelReport = getExchangeUserFromString("outlook resolvable name here")
'add to both the next level of reports as well as all reports
allReports.Add myTopLevelReport
curLevelReports.Add myTopLevelReport
Dim tempAddressEntries As AddressEntries
Dim newExUser As ExchangeUser
Dim i, j As Integer
'flag for when another sublevel is found
Dim keepLooping As Boolean
keepLooping = False
Dim requireValidUser As Boolean
requireValidUser = False
'this is where the fun begins
Do
'get current reports for the current level
For i = curLevelReports.Count To 1 Step -1
Set tempAddressEntries = curLevelReports.item(i).GetDirectReports
'add all reports (note .Count returns 0 on an empty collection)
For j = 1 To tempAddressEntries.Count
Set newExUser = tempAddressEntries.item(j).getExchangeUser
'isExchangeUserActualEmployee has some short boolean heuristics to make sure
'the user has at least a title and an email address
If (isExchangeUserActualEmployee(newExUser) = True Or requireValidUser = False) Then
allReports.Add newExUser
nextLevelReports.Add newExUser
keepLooping = True
End If
Next j
Set tempAddressEntries = Nothing
Next i
'reset for next iteration
Set curLevelReports = nextLevelReports
Set nextLevelReports = New Collection
'no more levels to keep going
If keepLooping = False Then
Exit Do
End If
'reset flag for next iteration
keepLooping = False
Loop
Dim oMail As Outlook.MailItem
Set oMail = Application.CreateItem(olMailItem)
'do stuff with this information (currently just write to new email, could do other cool stuff)
For i = 1 To allReports.Count
oMail.Body = oMail.Body + allReports.item(i).name + ";" + allReports.item(i).JobTitle
Next i
oMail.Display
End Sub
If (bool_expression) = true
can (read: should) be rewritten asIf (bool_expression)
andIf (bool_expression) = false
can (read: should) be rewritten asIf Not (bool_expression)
. \$\endgroup\$