Modify Existing VBA Code

legalhustler

Well-known Member
Joined
Jun 5, 2014
Messages
1,171
Office Version
  1. 365
Platform
  1. Windows
Hi,

The following VBA code works well for the most part but just need slight changes to it and I don't know how to make them. The code basically extracts the field Email, Name, and Phone Number from Outlook GAL based on a defined name range with a list of alias names.

Example:
Alias (column A)……….Column B...……………………...Column C...………..Column D
STYPEGHE ………………..joe.smith@outlook.com.... smith, joe...…….914-270-0010

Changes needed:

1) Code is returning a # N/A for the three extracted fields/columns from row 65,0001 to the last row of the worksheet. This should be blank since there is no alias listed (in the adjacent column A)
2) Add a header for each column of the three fields such as Email, Name and Phone Number.
3) Some emails comes like joe.smith@outlook.com (there is always a period between the first and last name) and would like to capitalize the "J"and "S", some are already come in correct form so those shouldn't change.

Thanks in advance!

VBA Code:
Option Explicit

Sub GetExchangeUserDetailsFromAlias()
  
    Dim str As String
    Dim olApp As Object 'Outlook.Application
    Dim olNameSpace As Object 'Outlook.Namespace
    Dim olRecipient As Object 'Outlook.Recipient
    Dim oEU As Object 'Outlook.ExchangeUser
    Dim arrUsers(1 To 65000, 1 To 3) As String
    Dim lngUser As Long
    Dim rngAlias As Range, rngAliasList As Range
  
    On Error Resume Next
    Set olApp = GetObject(, "Outlook.Application")
    If olApp Is Nothing Then
        Set olApp = CreateObject("Outlook.Application")
    End If
    On Error GoTo 0
  
    Set olNameSpace = olApp.GetNamespace("MAPI")
  
    With Worksheets("Users")
        Set rngAliasList = .Range("rngAliasList")
    End With
    For Each rngAlias In rngAliasList
        lngUser = lngUser + 1
        If Len(rngAlias.Value) > 0 Then
            str = rngAlias.Value
            Set olRecipient = olNameSpace.CreateRecipient(str)
            olRecipient.Resolve
            If olRecipient.Resolved Then
                If olRecipient.AddressEntry.AddressEntryUserType = 0 Then 'olExchangeUserAddressEntry
                    Set oEU = olRecipient.AddressEntry.GetExchangeUser
                    If Not (oEU Is Nothing) Then
                        With oEU
                            arrUsers(lngUser, 1) = .PrimarySmtpAddress
                            arrUsers(lngUser, 2) = .Name
                            arrUsers(lngUser, 3) = .MobileTelephoneNumber
                        End With
                    End If
                End If
            End If
        End If
    Next rngAlias
    rngAliasList.Offset(, 1).Resize(, 3).Value = arrUsers
  
    Set olApp = Nothing 'Outlook.Application
    Set olNameSpace = Nothing 'Outlook.Namespace
    Set olRecipient = Nothing 'Outlook.Recipient
    Set oEU = Nothing 'Outlook.ExchangeUser
    If lngUser Then Erase arrUsers
    Set rngAlias = Nothing
    Set rngAliasList = Nothing
  
End Sub
 

Excel Facts

Select a hidden cell
Somehide hide payroll data in column G? Press F5. Type G1. Enter. Look in formula bar while you arrow down through G.
Hi

The code below should solve issues 2 and 3.
  • For Issue 2, the code below assumes that there is empty row above the list of aliases in which to put the header for each of the three fields. There is nothing in your code to give any indication as to where on the spreadsheet (in terms of absolute addresses) the data output will go, so I've followed the relative referencing already in the code. Note however that this will inevitably break if the data is being output to row 1 (resulting in my code trying to put the headers in row 0, which doesn't exist).

  • As for Issue 3, I cobbled together a function - ConvertProperCase - which (hopefully) accomplishes what you've asked for (i.e., converts the first letters of the first/last name in the email to upper case). This function assumes that all the emails are structured the way you've set out: nameone.nametwo@domain.com

Finally, in terms of Issue 1, the code indicates that there is a named range on the "Users" worksheet entitled "rngAliasList". Would you happen to know what the address range is for this? The reason you are getting the #N/A in the columns for rows 65,001 onwards is because the code (arbitrarily) checks against 65,000 aliases, and then wholesale pastes the results against a range that is clearly larger than 65,000 rows. Where the code has not looked for an alias, it fills the cells with #N/A. There is doubtless a means by which the resulting range can be resized against the final array, etc., but it's making my head hurt and I feel it would be a bit easier just to understand the parameters of the actual range and get a bit of understanding as to why it was coded that way to begin with to see if there is perhaps a better - and less headache inducing - solution...

Are you actually looking up 65,000 aliases each time? If not, there are a few things that can be adjusted in the code to optimise it.

Let me know if the code works for Issues 2 and 3, and if you can give me a bit more information, I might be able to help on Issue 1 as well.

VBA Code:
Sub GetExchangeUserDetailsFromAlias()
  
    Dim str As String
    Dim olApp As Object 'Outlook.Application
    Dim olNameSpace As Object 'Outlook.Namespace
    Dim olRecipient As Object 'Outlook.Recipient
    Dim oEU As Object 'Outlook.ExchangeUser
    Dim arrUsers(1 To 65000, 1 To 3) As String
    Dim lngUser As Long
    Dim rngAlias As Range, rngAliasList As Range
  
    On Error Resume Next
    Set olApp = GetObject(, "Outlook.Application")
    If olApp Is Nothing Then
        Set olApp = CreateObject("Outlook.Application")
    End If
    On Error GoTo 0
  
    Set olNameSpace = olApp.GetNamespace("MAPI")
  
    With Worksheets("Users")
        Set rngAliasList = .Range("rngAliasList")
    End With
    For Each rngAlias In rngAliasList
        lngUser = lngUser + 1
        If Len(rngAlias.value) > 0 Then
            str = rngAlias.value
            Set olRecipient = olNameSpace.CreateRecipient(str)
            olRecipient.Resolve
            If olRecipient.Resolved Then
                If olRecipient.AddressEntry.AddressEntryUserType = 0 Then 'olExchangeUserAddressEntry
                    Set oEU = olRecipient.AddressEntry.GetExchangeUser
                    If Not (oEU Is Nothing) Then
                        With oEU
                            arrUsers(lngUser, 1) = ConvertProperCase(CStr(.PrimarySmtpAddress))
                            arrUsers(lngUser, 2) = .Name
                            arrUsers(lngUser, 3) = .MobileTelephoneNumber
                        End With
                    End If
                End If
            End If
        End If
    Next rngAlias
    With rngAliasList
        .Offset(, 1).Resize(, 3).value = arrUsers
        .Cells(1).Offset(-1, 1).Resize(, 3).value = Array("Email", "Name", "Phone Number")
    End With
    
    Set olApp = Nothing 'Outlook.Application
    Set olNameSpace = Nothing 'Outlook.Namespace
    Set olRecipient = Nothing 'Outlook.Recipient
    Set oEU = Nothing 'Outlook.ExchangeUser
    If lngUser Then Erase arrUsers
    Set rngAlias = Nothing
    Set rngAliasList = Nothing
  
End Sub

Function ConvertProperCase(strSource As String) As String
    Dim varNames As Variant
    varNames = Split(Split(strSource, "@")(0), ".")
    ConvertProperCase = WorksheetFunction.Proper(CStr(varNames(0))) & "." & WorksheetFunction.Proper(CStr(varNames(1))) & Split(strSource, varNames(1))(1)
End Function

 
Upvote 0
Your code has some issues. I still get 1) #NA for the three fields from row 65,0001 to the last row of the worksheet 2) No header shows above the list of Email, Name, and Phone Number, 3) Your code makes for example joe.mcArthur@outlook.com into Joe.Mcauthor@outlook.com - it should be Joe.McAuthor@outlook.com (only the first letter of the first name and last name should be capitalized). Does a function mean I have to manually type it on the face of the worksheet like a formula for it to fix the cases? The code should automatically fix the cases.

To clarify:

- The worksheet is called "Users"

- Column A has is a defined name called "rngAliasList" which has a address range of =Users!$A:$A

- Cell A1 has a header called "Alias" and below that is the list of each alias i.e. STYPEGHE (I don't have 65,000 aliases and it can vary based on what I type there, currently the last alias I have is on cell A87, so that's the last row of my data). Code should not be checking for aliases from 65,001 to end of the worksheet only to my last cell (i.e. A87)

- I would like cell B1, C1, and D1 to have the header Email, Name, and Phone Number or can you make it dynamic depending on where the define name "rngAliasList" is. So if I have "rngAliasList" moved to column B, then column C1, D1, and E1 will have those three field headers, if it'stoo complicated no worries just have them in B1, C1, and D1.
 
Last edited:
Upvote 0
Your code has some issues.
I'm not surprised. Your spreadsheet has an already defined range (rngAliasList) that covers the entire A column for the sheet! I hadn't expected that, though it explains the problems you've been experiencing with the spreadsheet.

I still get 1) #NA for the three fields from row 65,0001 to the last row of the worksheet
I told you this was the case from the outset. Right after "Hi", I wrote "The code below should solve issues 2 and 3." I then finished with "Let me know if the code works for Issues 2 and 3, and if you can give me a bit more information, I might be able to help on Issue 1 as well."

2) No header shows above the list of Email, Name, and Phone Number
Now that I know that the named range rngAliasList is A:A, it makes sense that it wouldn't work. If you're happy with the headers being at cells: B1. C1, and D1 for now, then this is a simple enough fix.

3) Your code makes for example joe.mcArthur@outlook.com into Joe.Mcauthor@outlook.com - it should be Joe.McAuthor@outlook.com (only the first letter of the first name and last name should be capitalized)
Ah. Understood. My function attempts to 'solve' this issue by converting everything to 'proper case' which, by default, converts the first character to upper case and every subsequent character to lower case. I've updated the code.

Does a function mean I have to manually type it on the face of the worksheet like a formula for it to fix the cases?
Not unless you desperately want to, no. My code already works the function into the process (resulting in the 'proper case' email addresses mentioned above), so there is nothing for you to do re: the function. I simply mention it because I thought you'd like to know.

The revised code below should (fingers crossed) solve all the issues, but please let me know if it doesn't.

VBA Code:
Sub GetExchangeUserDetailsFromAlias()
  
    Dim str As String
    Dim olApp As Object 'Outlook.Application
    Dim olNameSpace As Object 'Outlook.Namespace
    Dim olRecipient As Object 'Outlook.Recipient
    Dim oEU As Object 'Outlook.ExchangeUser
    Dim arrUsers() As String
    Dim lngUser As Long
    Dim rngAlias As Range, rngAliasList As Range
    Dim lngLastRow As Long
  
    On Error Resume Next
    Set olApp = GetObject(, "Outlook.Application")
    If olApp Is Nothing Then
        Set olApp = CreateObject("Outlook.Application")
    End If
    On Error GoTo 0
  
    Set olNameSpace = olApp.GetNamespace("MAPI")
  
    With Worksheets("Users")
        lngLastRow = .Range("A" & .Rows.Count).End(xlUp).Row
        Set rngAliasList = .Range("A2:A" & lngLastRow)
    End With
    ReDim arrUsers(1 To lngLastRow - 1, 1 To 3)
    
    Range("B1:D1").value = Array("Email", "Name", "Phone Number")
    
    For Each rngAlias In rngAliasList
        lngUser = lngUser + 1
        If Len(rngAlias.value) > 0 Then
            str = rngAlias.value
            Set olRecipient = olNameSpace.CreateRecipient(str)
            olRecipient.Resolve
            If olRecipient.Resolved Then
                If olRecipient.AddressEntry.AddressEntryUserType = 0 Then 'olExchangeUserAddressEntry
                    Set oEU = olRecipient.AddressEntry.GetExchangeUser
                    If Not (oEU Is Nothing) Then
                        With oEU
                            arrUsers(lngUser, 1) = ConvertCase(CStr(.PrimarySmtpAddress))
                            arrUsers(lngUser, 2) = .Name
                            arrUsers(lngUser, 3) = .MobileTelephoneNumber
                        End With
                    End If
                End If
            End If
        End If
    Next rngAlias
    rngAliasList.Offset(, 1).Resize(, 3).value = arrUsers
    'Range("B2").Resize(lngUser, 3).value = arrUser
    
    Set olApp = Nothing 'Outlook.Application
    Set olNameSpace = Nothing 'Outlook.Namespace
    Set olRecipient = Nothing 'Outlook.Recipient
    Set oEU = Nothing 'Outlook.ExchangeUser
    If lngUser Then Erase arrUsers
    Set rngAlias = Nothing
    Set rngAliasList = Nothing
  
End Sub

Function ConvertCase(strSource As String) As String
    Dim varNames As Variant, strFirstName As String, strLastName As String
    varNames = Split(Split(strSource, "@")(0), ".")
    strFirstName = CStr(varNames(0))
    strLastName = CStr(varNames(1))
    ConvertCase = UCase(Left(strFirstName, 1)) & Mid(strFirstName, 2) & "." & UCase(Left(strLastName, 1)) & Mid(strLastName, 2) & Split(strSource, strLastName)(1)
End Function
 
Upvote 0
I'm not surprised. Your spreadsheet has an already defined range (rngAliasList) that covers the entire A column for the sheet! I hadn't expected that, though it explains the problems you've been experiencing with the spreadsheet.


I told you this was the case from the outset. Right after "Hi", I wrote "The code below should solve issues 2 and 3." I then finished with "Let me know if the code works for Issues 2 and 3, and if you can give me a bit more information, I might be able to help on Issue 1 as well."


Now that I know that the named range rngAliasList is A:A, it makes sense that it wouldn't work. If you're happy with the headers being at cells: B1. C1, and D1 for now, then this is a simple enough fix.


Ah. Understood. My function attempts to 'solve' this issue by converting everything to 'proper case' which, by default, converts the first character to upper case and every subsequent character to lower case. I've updated the code.


Not unless you desperately want to, no. My code already works the function into the process (resulting in the 'proper case' email addresses mentioned above), so there is nothing for you to do re: the function. I simply mention it because I thought you'd like to know.

The revised code below should (fingers crossed) solve all the issues, but please let me know if it doesn't.

VBA Code:
Sub GetExchangeUserDetailsFromAlias()

    Dim str As String
    Dim olApp As Object 'Outlook.Application
    Dim olNameSpace As Object 'Outlook.Namespace
    Dim olRecipient As Object 'Outlook.Recipient
    Dim oEU As Object 'Outlook.ExchangeUser
    Dim arrUsers() As String
    Dim lngUser As Long
    Dim rngAlias As Range, rngAliasList As Range
    Dim lngLastRow As Long

    On Error Resume Next
    Set olApp = GetObject(, "Outlook.Application")
    If olApp Is Nothing Then
        Set olApp = CreateObject("Outlook.Application")
    End If
    On Error GoTo 0

    Set olNameSpace = olApp.GetNamespace("MAPI")

    With Worksheets("Users")
        lngLastRow = .Range("A" & .Rows.Count).End(xlUp).Row
        Set rngAliasList = .Range("A2:A" & lngLastRow)
    End With
    ReDim arrUsers(1 To lngLastRow - 1, 1 To 3)

    Range("B1:D1").value = Array("Email", "Name", "Phone Number")

    For Each rngAlias In rngAliasList
        lngUser = lngUser + 1
        If Len(rngAlias.value) > 0 Then
            str = rngAlias.value
            Set olRecipient = olNameSpace.CreateRecipient(str)
            olRecipient.Resolve
            If olRecipient.Resolved Then
                If olRecipient.AddressEntry.AddressEntryUserType = 0 Then 'olExchangeUserAddressEntry
                    Set oEU = olRecipient.AddressEntry.GetExchangeUser
                    If Not (oEU Is Nothing) Then
                        With oEU
                            arrUsers(lngUser, 1) = ConvertCase(CStr(.PrimarySmtpAddress))
                            arrUsers(lngUser, 2) = .Name
                            arrUsers(lngUser, 3) = .MobileTelephoneNumber
                        End With
                    End If
                End If
            End If
        End If
    Next rngAlias
    rngAliasList.Offset(, 1).Resize(, 3).value = arrUsers
    'Range("B2").Resize(lngUser, 3).value = arrUser

    Set olApp = Nothing 'Outlook.Application
    Set olNameSpace = Nothing 'Outlook.Namespace
    Set olRecipient = Nothing 'Outlook.Recipient
    Set oEU = Nothing 'Outlook.ExchangeUser
    If lngUser Then Erase arrUsers
    Set rngAlias = Nothing
    Set rngAliasList = Nothing

End Sub

Function ConvertCase(strSource As String) As String
    Dim varNames As Variant, strFirstName As String, strLastName As String
    varNames = Split(Split(strSource, "@")(0), ".")
    strFirstName = CStr(varNames(0))
    strLastName = CStr(varNames(1))
    ConvertCase = UCase(Left(strFirstName, 1)) & Mid(strFirstName, 2) & "." & UCase(Left(strLastName, 1)) & Mid(strLastName, 2) & Split(strSource, strLastName)(1)
End Function

This is excellent - just need the column widths to adjust once the email, name, and phone number is provided so I don't manually have to fix the column widths and if you can make those three headers bolded using fill RGB code 0, 32, 96 with white font.

This is my first time seeing a function being called in a sub procedure - pretty cool.
 
Last edited:
Upvote 0
Also, do you know why some alias names do not show the email, name, phone number even though they exist in Outlook GAL? I tried to see what I have typed in the alias name (column A) is equal to the alias that I copied/pasted from Outlook GAL via formula and they are both the same. The code returns the 3 fields and are not case sensitive based on the alias (I tested it). I even tried adding space at beginning, end, and both of the alias but when I run the code still no email, name, phone number....strange.
 
Upvote 0
Hi

I'm really glad it's working. I've updated it to include:
1. the colouring for the three column headers (are you sure you don't want the colour applied to the Alias column header?). I've made the headers bold too, but if you don't want that, just delete the line: .Font.Bold = True
2. the columns auto-adjust once all the details are filled in.

Out of curiosity, does it take long to run? Has the revised code made it any quicker?

In terms of why you're not getting all the details, I'm not entirely sure. According to the code, you'd get an error message if there was anything wrong with it, so I think Outlook just isn't able to 'resolve' the alias to the name in the GAL. For those aliases that aren't returning any information, what happens if you go to Outlook and manually type the alias into the To or CC field and press Ctrl-K? Does it show the name of the individual (underlined)? Or does it present you with a message box asking you to select from a number of individuals?

Ordinarily, I would suggest stepping through the code line by line (pressing F8) and checking the Locals window to see what the values of the various relevant variables are. Alternatively, I can adjust the code, if you like, to add some kind of debug logging to a file so you can try and work out what's going wrong.

Anyway, let me know if it's all working ok.

VBA Code:
Sub GetExchangeUserDetailsFromAlias()

    Dim str As String
    Dim olApp As Object 'Outlook.Application
    Dim olNameSpace As Object 'Outlook.Namespace
    Dim olRecipient As Object 'Outlook.Recipient
    Dim oEU As Object 'Outlook.ExchangeUser
    Dim arrUsers() As String
    Dim lngUser As Long
    Dim rngAlias As Range, rngAliasList As Range
    Dim lngLastRow As Long

    On Error Resume Next
    Set olApp = GetObject(, "Outlook.Application")
    If olApp Is Nothing Then
        Set olApp = CreateObject("Outlook.Application")
    End If
    On Error GoTo 0

    Set olNameSpace = olApp.GetNamespace("MAPI")

    With Worksheets("Users")
        lngLastRow = .Range("A" & .Rows.Count).End(xlUp).Row
        Set rngAliasList = .Range("A2:A" & lngLastRow)
    End With
    ReDim arrUsers(1 To lngLastRow - 1, 1 To 3)

    With Range("B1:D1")
        .value = Array("Email", "Name", "Phone Number")
        .Interior.Color = RGB(0, 32, 96)
        .Font.Color = vbWhite
        .Font.Bold = True
    End With
    
    For Each rngAlias In rngAliasList
        lngUser = lngUser + 1
        If Len(rngAlias.value) > 0 Then
            str = rngAlias.value
            Set olRecipient = olNameSpace.CreateRecipient(str)
            olRecipient.Resolve
            If olRecipient.Resolved Then
                If olRecipient.AddressEntry.AddressEntryUserType = 0 Then 'olExchangeUserAddressEntry
                    Set oEU = olRecipient.AddressEntry.GetExchangeUser
                    If Not (oEU Is Nothing) Then
                        With oEU
                            arrUsers(lngUser, 1) = ConvertCase(CStr(.PrimarySmtpAddress))
                            arrUsers(lngUser, 2) = .Name
                            arrUsers(lngUser, 3) = .MobileTelephoneNumber
                        End With
                    End If
                End If
            End If
        End If
    Next rngAlias
    rngAliasList.Offset(, 1).Resize(, 3).value = arrUsers
        
    Worksheets("Users").Columns("B:D").EntireColumn.AutoFit

    Set olApp = Nothing 'Outlook.Application
    Set olNameSpace = Nothing 'Outlook.Namespace
    Set olRecipient = Nothing 'Outlook.Recipient
    Set oEU = Nothing 'Outlook.ExchangeUser
    If lngUser Then Erase arrUsers
    Set rngAlias = Nothing
    Set rngAliasList = Nothing

End Sub

Function ConvertCase(strSource As String) As String
    Dim varNames As Variant, strFirstName As String, strLastName As String
    varNames = Split(Split(strSource, "@")(0), ".")
    strFirstName = CStr(varNames(0))
    strLastName = CStr(varNames(1))
    ConvertCase = UCase(Left(strFirstName, 1)) & Mid(strFirstName, 2) & "." & UCase(Left(strLastName, 1)) & Mid(strLastName, 2) & Split(strSource, strLastName)(1)
End Function
 
Upvote 0
That FUNCTION part of your code wasn't running so I just copied only that portion from the post above and it worked. Everything looks good. The code runs and returns the data in 3 secs, I think my original was like 10 secs.

I don't get an error message if the alias is not found, it returns blanks for the three extracted fields (which is what I want). When I manually enter the alias in the Outlook TO field and press Ctrl + K it returns two different individual names and they have different aliases, very similar but different like STYPEGHE and STYPEGHE1. Maybe the code disregards the "1" and doesn't know which data to return thus blank??

P.S. that's a pretty nimble way of checking out which name belongs to the alias in Outlook. Thanks!
 
Last edited:
Upvote 0
When I type the alias STYPEGHE and press Ctrl + K the Outlook message on top of the dialog says "Microsoft Outlook found more than one "STYPEGHE". I'm pretty sure this is why I'm seeing blank data for some aliases because the code cannot distinguish STYPEGHE from STYPEGHE1...it disregards the "1". I checked a few other aliases and they have different individuals with almost same alias except a number suffix at the end of it.
 
Upvote 0
When I manually enter the alias in the Outlook TO field and press Ctrl + K it returns two different individual names and they have different aliases,
I suspected that might be the case. When Outlook can't be certain as to which alias you're referencing (and STYPEGHE is similar enough to STYPEGHE1), Outlook will just avoid the problem and do nothing. As far as I'm aware, there is only one way of resolving this - that's to use the Redemption library (link). Redemption allows you to work with properties and functionality not exposed through the Outlook Object Model. The developer version is free, but it requires installation, and so if you're doing this on a work issued laptop, it will require a conversation with the IT department before you could use it. There is probably a clever hack around it, though, but nothing comes immediately to mind. Maybe if you tried to resolve against an email address rather than an alias... I'd need to think about it.
 
Upvote 0

Forum statistics

Threads
1,214,983
Messages
6,122,595
Members
449,089
Latest member
Motoracer88

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top