I want to code a VBA such that the mail can be sent only if the user fills in details in rows. If not, an alert showing "Cannot send update. Fill the details completely" should pop up on the users screen.
Eg: The user has to fil Columns "A to J" and "M". If not they cannot send mail and pop up should ask them to enter it.
I have the following code as below,
Sub MAIL()
Dim EmailApp As Outlook.Application
Dim Source As String
Set EmailApp = New Outlook.Application
Dim EmailItem As Outlook.MailItem
Set EmailItem = EmailApp.CreateItem(olMailItem)
EmailItem.To = "abc#gmail.com"
EmailItem.Subject = " "
EmailItem.HTMLBody = ""
Source = ThisWorkbook.FullName
EmailItem.Attachments.Add Source
EmailItem.Send
End Sub
Please help me provide alerts to users. I am completely new to this.
Please, use the next function. It will check if at least a cell is filled in all columns of the range ("A:J, M:M"). In such a case it returns True. Otherwise, it send a relevant message and returns false, stopping the mail sending:
Function checkIfOK() As Boolean
Dim rng As Range, ar As Range, i As Long
Set rng = Range("A:J,M:M")
For Each ar In rng.Areas
For i = 1 To ar.Columns.count
If WorksheetFunction.CountA(ar.Columns(i)) > 1 Then
MsgBox "Column " & Split(ar.Columns(i).cells(1).Address, "$")(1) & " is empty..."
Exit Function
End If
Next i
Next ar
checkIfOK = True
End Function
You have to use it in your code in the next way:
Sub MAIL()
If Not checkIfOK Then Exit Sub 'it stop the code here if the function returns False
Dim EmailApp As Outlook.Application, Source As String
Set EmailApp = New Outlook.Application
Dim EmailItem As Outlook.MailItem
Set EmailItem = EmailApp.CreateItem(olMailItem)
EmailItem.To = "abc#gmail.com"
EmailItem.Subject = " "
EmailItem.HtmlBody = ""
Source = ThisWorkbook.fullName
EmailItem.Attachments.Add Source
EmailItem.Send
End Sub
The function has been built on the above mentioned assumption. I asked you in my comment "How this to be appreciated?" and you did not answer anything...
Related
I am looking for VBA code in excel to reply to a selected mail but the below code creates seperate mail which does not have previous messages in conversation (thread) in body. I searched online, but most of them are old codes which are not working currently. Please help.
Sub Test_template()
Dim emailApplication As Object
Dim emailItem As Object
Set emailApplication = CreateObject("Outlook.Application")
Set emailItem = emailApplication.ActiveExplorer.Selection.Item(1).ReplyAll
emailItem.bcc = "XYZ.com"
emailItem.Body = "Hi, have a nice day "
emailItem.Display
Set emailItem = Nothing
Set emailApplication = Nothing
End Sub
Is this what you are trying? I have commented the code and provided relevant MSDN links. If you still get stuck then simply ask.
Option Explicit
Sub Sample()
Dim OutlookApp As Object
Dim OutlookMail As Object
Set OutlookApp = CreateObject("Outlook.Application")
Set OutlookMail = OutlookApp.ActiveExplorer.Selection.Item(1)
'~~> Get MailItem.GetConversation method (Outlook)
' https://learn.microsoft.com/en-us/office/vba/api/outlook.mailitem.getconversation
Dim OutlookConversation As Object
Set OutlookConversation = OutlookMail.GetConversation
'~~> Conversation.GetTable method (Outlook)
' https://learn.microsoft.com/en-us/office/vba/api/outlook.conversation.gettable
Dim OutlookTable As Object
Set OutlookTable = OutlookConversation.GetTable
'~~> Obtains a 2D array from the Table.
' https://learn.microsoft.com/en-us/office/vba/api/outlook.table.getarray
Dim OutlookAr As Variant
OutlookAr = OutlookTable.GetArray(OutlookTable.GetRowCount)
Dim OutlookReplyToThisMail As Object
Set OutlookReplyToThisMail = OutlookMail.Session.GetItemFromID(OutlookAr(UBound(OutlookAr), 0))
Dim MyMessage As String: MyMessage = "Hi, have a nice day "
With OutlookReplyToThisMail.ReplyAll
.BCC = "XYZ.com"
.HTMLBody = MyMessage & .HTMLBody
.Display
End With
End Sub
.ReplyAll produces the expected result but is overwritten by emailItem.Body = "Hi, have a nice day ".
Option Explicit
Sub Test_template()
Dim emailApplication As Object
Dim emailItem As Object
'Set emailApplication = CreateObject("Outlook.Application")
' mail has to be slelected in Outlook application so it has to be open already
Set emailApplication = GetObject(, "Outlook.Application")
Set emailItem = emailApplication.ActiveExplorer.Selection.Item(1).ReplyAll
emailItem.BCC = "XYZ.com"
'emailItem.Body = "Hi, have a nice day "
emailItem.Body = "Hi, have a nice day " & emailItem.Body
' or
'emailItem.htmlBody = "Hi, have a nice day " & emailItem.htmlBody
emailItem.Display
Set emailItem = Nothing
Set emailApplication = Nothing
End Sub
The code below doesn't execute reply all property, hence, I am not able to edit the body of the email and keep the conversation of the email chain.
I think the best option is to use Application.advancesearch as it gives you latest email by searching through all folders. But I do not know how to run it through Excel.
Objective:
1) Search the inbox and subfolders (multiple) and Sent items folder for the latest email for selected "Subject"
2) select the latest email and reply to all
Sub ReplyMail()
' Variables
Dim OutlookApp As Object
Dim IsOutlookCreated As Boolean
Dim sFilter As String, sSubject As String
Dim SentTime As Long
Dim IndoxTime As Long
Dim olEmailIndox As Outlook.MailItem
Dim olEmailSent As Outlook.MailItem
' Get/create outlook object
On Error Resume Next
Set OutlookApp = GetObject(, "Outlook.Application")
If Err Then
Set OutlookApp = CreateObject("Outlook.Application")
IsOutlookCreated = True
End If
On Error GoTo 0
Set olEmailIndox = OutlookApp.CreateItem(olMailItem)
Set olEmailSent = OutlookApp.CreateItem(olMailItem)
' Restrict items
sSubject = "Subject 1"
sFilter = "[Subject] = '" & sSubject & "'"
' Main
With OutlookApp.Session.GetDefaultFolder(olFolderSentMail).Items.Restrict(sFilter)
If .Count > 0 Then
.Sort "ReceivedTime", True
Set olEmailSent = .Item(1)
SentTime = olEmailSent.SentOn
End If
End With
With OutlookApp.Session.GetDefaultFolder(olFolderInbox).Items.Restrict(sFilter)
If .Count > 0 Then
.Sort "ReceivedTime", True
Set olEmailInbox = .Item(1)
InboxTime = olEmailInbox.ReceivedTime
End If
End With
If SentTime > InboxTime Then
With olEmailSent
.ReplyAll
.Display
'.body
'.Send
End With
Else
With olEmailInbox
.ReplyAll
.Display
'.body
'.Send
End With
End If
' Quit Outlook instance if it was created by this code
If IsOutlookCreated Then
OutlookApp.Quit
Set OutlookApp = Nothing
End If
End Sub
I have tested the code below and even though you can polish it, should get you started.
Let me know and mark the answer if it helps.
Add in a vba module this code:
Public Sub ProcessEmails()
Dim testOutlook As Object
Dim oOutlook As clsOutlook
Dim searchRange As Range
Dim subjectCell As Range
Dim searchFolderName As String
' Start outlook if it isn't opened (credits: https://stackoverflow.com/questions/33328314/how-to-open-outlook-with-vba)
On Error Resume Next
Set testOutlook = GetObject(, "Outlook.Application")
On Error GoTo 0
If testOutlook Is Nothing Then
Shell ("OUTLOOK")
End If
' Initialize Outlook class
Set oOutlook = New clsOutlook
' Get the outlook inbox and sent items folders path (check the scope specification here: https://learn.microsoft.com/en-us/office/vba/api/outlook.application.advancedsearch)
searchFolderName = "'" & Outlook.Session.GetDefaultFolder(olFolderInbox).FolderPath & "','" & Outlook.Session.GetDefaultFolder(olFolderSentMail).FolderPath & "'"
' Loop through excel cells with subjects
Set searchRange = ThisWorkbook.Worksheets("Sheet1").Range("A2:A4")
For Each subjectCell In searchRange
' Only to cells with actual subjects
If subjectCell.Value <> vbNullString Then
Call oOutlook.SearchAndReply(subjectCell.Value, searchFolderName, False)
End If
Next subjectCell
MsgBox "Search and reply completed"
' Clean object
Set testOutlook = Nothing
End Sub
Then add a class module and name it: clsOutlook
To the class module add the following code:
Option Explicit
' Credits: Based on this answer: https://stackoverflow.com/questions/31909315/advanced-search-complete-event-not-firing-in-vba
' Event handler for outlook
Dim WithEvents OutlookApp As Outlook.Application
Dim outlookSearch As Outlook.Search
Dim outlookResults As Outlook.Results
Dim searchComplete As Boolean
' Handler for Advanced search complete
Private Sub outlookApp_AdvancedSearchComplete(ByVal SearchObject As Search)
'MsgBox "The AdvancedSearchComplete Event fired."
searchComplete = True
End Sub
Sub SearchAndReply(emailSubject As String, searchFolderName As String, searchSubFolders As Boolean)
' Declare objects variables
Dim customMailItem As Outlook.MailItem
Dim searchString As String
Dim resultItem As Integer
' Variable defined at the class level
Set OutlookApp = New Outlook.Application
' Variable defined at the class level (modified by outlookApp_AdvancedSearchComplete when search is completed)
searchComplete = False
' You can look up on the internet for urn:schemas strings to make custom searches
searchString = "urn:schemas:httpmail:subject like '" & emailSubject & "'" ' Use: subject like '%" & emailSubject & "%'" if you want to include words see %
' Perform advanced search
Set outlookSearch = OutlookApp.AdvancedSearch(searchFolderName, searchString, searchSubFolders, "SearchTag")
' Wait until search is complete based on outlookApp_AdvancedSearchComplete event
While searchComplete = False
DoEvents
Wend
' Get the results
Set outlookResults = outlookSearch.Results
If outlookResults.Count = 0 Then Exit Sub
' Sort descending so you get the latest
outlookResults.Sort "[SentOn]", True
' Reply only to the latest one
resultItem = 1
' Some properties you can check from the email item for debugging purposes
On Error Resume Next
Debug.Print outlookResults.Item(resultItem).SentOn, outlookResults.Item(resultItem).ReceivedTime, outlookResults.Item(resultItem).SenderName, outlookResults.Item(resultItem).Subject
On Error GoTo 0
Set customMailItem = outlookResults.Item(resultItem).ReplyAll
' At least one reply setting is required in order to replyall to fire
customMailItem.Body = "Just a reply text " & customMailItem.Body
customMailItem.Display
End Sub
Everyday I get emails with project numbers on them. I usually highlight and copy the project number from the email, click on my excel spreadsheet (WI_Design_Tracker), ctrl + F (to find) and paste the project number into the find field, then Find Next. I'm trying to create a macro that will shorten the process since I do it a hundred times a day. I found a macro that does the opposite (finds a highlighted number in Excel and searches through Outlook to find the email. I tried to amend it to fit my purposes but it's above my skill level. Any help would be greatly appreciated. Here's the code I'm trying to convert to search my Excel worksheet for the project number I have highlighted on an Outlook email.
'Code:
Option Explicit
Public Sub Search_Outlook_Emails()
Dim outApp As Outlook.Application
Dim outNs As Outlook.Namespace
Dim outStartFolder As Outlook.MAPIFolder
Dim foundEmail As Outlook.MailItem
Set outApp = New Outlook.Application
Set outNs = outApp.GetNamespace("MAPI")
'Start at Inbox's parent folder
Set outStartFolder = outNs.GetDefaultFolder(Outlook.olFolderInbox).Parent
'Or start at folder selected by user
'Set outStartFolder = outNs.PickFolder
If Not outStartFolder Is Nothing Then
Set foundEmail = Find_Email_In_Folder(outStartFolder, ActiveCell.Value)
If Not foundEmail Is Nothing Then
If MsgBox("Email subject: " & foundEmail.Subject & vbNewLine & vbNewLine & _
"Folder: " & foundEmail.Parent.FolderPath & vbNewLine & vbNewLine & _
"Open the email?", vbYesNo, "'" & ActiveCell.Value & "' found") = vbYes Then
foundEmail.Display
End If
Else
MsgBox "", vbOKOnly, "'" & ActiveCell.Value & "' not found"
End If
End If
End Sub
Private Function Find_Email_In_Folder(outFolder As Outlook.MAPIFolder, findText As String) As Outlook.MailItem
Dim outItem As Object
Dim outMail As Outlook.MailItem
Dim outSubFolder As Outlook.MAPIFolder
Dim i As Long
Debug.Print outFolder.FolderPath
Set Find_Email_In_Folder = Nothing
'Search emails in this folder
i = 1
While i <= outFolder.Items.Count And Find_Email_In_Folder Is Nothing
Set outItem = outFolder.Items(i)
If outItem.Class = Outlook.OlObjectClass.olMail Then
'Does the findText occur in this email's body text?
Set outMail = outItem
If InStr(1, outMail.Body, findText, vbTextCompare) > 0 Then Set Find_Email_In_Folder = outMail
End If
i = i + 1
Wend
DoEvents
'If not found, search emails in subfolders
i = 1
While i <= outFolder.Folders.Count And Find_Email_In_Folder Is Nothing
Set outSubFolder = outFolder.Folders(i)
'Only check mail item folders
If outSubFolder.DefaultItemType = Outlook.olMailItem Then Set Find_Email_In_Folder = Find_Email_In_Folder(outSubFolder, findText)
i = i + 1
Wend
End Function
Thanks for the link Tim. That was much simpler. I'd had seen that code before but wasn't able to make it work so I tried again. Here's what I ended up with. It could still use some tweaking and error handling, but this is what's working for now:
Sub FindOutlookValue()
Dim OutApp As Object
Dim OutMail As Object
Dim olInsp As Object
Dim WdDoc As Object
Dim strText As String
On Error Resume Next
'Get Outlook if it's running
Set OutApp = GetObject(, "Outlook.Application")
Set OutMail = OutApp.ActiveExplorer.Selection.Item(1)
With OutMail
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
strText = WdDoc.Application.Selection.Range.Text
End With
'Find strText in Excel
Dim cl As Range
With Worksheets("MyWorksheet").Cells
Set cl = .Find(strText, After:=.Range(A1), LookIn:=xlValues)
If Not cl Is Nothing Then
cl.Select
End If
End With
End Sub
My mails in Outlook has all specific subjects. I have a Excel Sheet which has subject and Folder Name.
I have already this code from Stackoverflow
Option Explicit
Public Sub Move_Items()
'// Declare your Variables
Dim Inbox As Outlook.MAPIFolder
Dim SubFolder As Outlook.MAPIFolder
Dim olNs As Outlook.NameSpace
Dim Item As Object
Dim lngCount As Long
Dim Items As Outlook.Items
On Error GoTo MsgErr
'// Set Inbox Reference
Set olNs = Application.GetNamespace("MAPI")
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Set Items = Inbox.Items
'// Loop through the Items in the folder backwards
For lngCount = Items.Count To 1 Step -1
Set Item = Items.Item(lngCount)
Debug.Print Item.Subject
If Item.Class = olMail Then
'// Set SubFolder of Inbox
Set SubFolder = Inbox.Folders("Temp")
'// Mark As Read
Item.UnRead = False
'// Move Mail Item to sub Folder
Item.Move SubFolder
End If
Next lngCount
MsgErr_Exit:
Set Inbox = Nothing
Set SubFolder = Nothing
Set olNs = Nothing
Set Item = Nothing
Exit Sub
'// Error information
MsgErr:
MsgBox "An unexpected Error has occurred." _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume MsgErr_Exit
End Sub
I want the code to read the active sheet columns, as follow:
Subject.mail folder_name
A 1
B 2
C 3
For example Mail in the Inbox with subject "A" then it has to place that mail in folder "1".
How do I loop? to look at the Sheet1 and to read to which sub folder it has to move ?
You have few options to do this, the painless one is to run Outlook VBA code from inside outlook so you don't need to go through a lot of referencing problem, but at the same time if you are insisting in having your list of subjects and folder in an Excel file, then it is better to run it from Excel, but here is the issue: You'd better not try to run the code from Excel because Microsoft is not supporting that method, so the best way is to write the code in Excel VBA, and again you can do late (runtime) binding or early binding, but I prefer early binding to use intellisence for better referencing outlook objects and avoid late binding performance and/or debugging problems.
Here is the code and how you should use it:
Go to the excel file that you have your subject and folders list or create a new one. Hit ALT+F11 to go to VBE. On the left panel (project explorer) right click and insert a module. Paste this code in there:
Option Explicit
Public Sub MoveEmailsToFolders()
'arr will be a 2D array sitting in an Excel file, 1st col=subject, 2nd col=folder name
' // Declare your Variables
Dim i As Long
Dim rowCount As Integer
Dim strSubjec As String
Dim strFolder As String
Dim olApp As Outlook.Application
Dim olNs As Outlook.Namespace
Dim myFolder As Outlook.Folder
Dim Item As Object
Dim Inbox As Outlook.MAPIFolder
Dim SubFolder As Outlook.MAPIFolder
Dim lngCount As Long
Dim Items As Outlook.Items
Dim arr() As Variant 'store Excel table as an array for faster iterations
Dim WS As Worksheet
'On Error GoTo MsgErr
'Set Excel references
Set WS = ActiveSheet
If WS.ListObjects.Count = 0 Then
MsgBox "Activesheet did not have the Excel table containing Subjects and Outlook Folder Names", vbCritical, "Error"
Exit Sub
Else
arr = WS.ListObjects(1).DataBodyRange.Value
rowCount = UBound(arr, 2)
If rowCount = 0 Then
MsgBox "Excel table does not have rows.", vbCritical, "Error"
Exit Sub
End If
End If
'Set Outlook Inbox Reference
Set olApp = New Outlook.Application
Set olNs = olApp.GetNamespace("MAPI")
Set myFolder = olNs.GetDefaultFolder(olFolderInbox)
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Set Items = Inbox.Items
' // Loop through the Items in the folder backwards
For lngCount = Items.Count To 1 Step -1
strFolder = ""
Set Item = Items.Item(lngCount)
'Debug.Print Item.Subject
If Item.Class = olMail Then
'Determine whether subject is among the subjects in the Excel table
For i = 1 To rowCount
If arr(i, 1) = Item.Subject Then
strFolder = arr(i, 2)
'// Set SubFolder of Inbox, read the appropriate folder name from table in Excel
Set SubFolder = Inbox.Folders(strFolder)
'// Mark As Read
Item.UnRead = False
'// Move Mail Item to sub Folder
Item.Move SubFolder
Exit For
End If
Next i
End If
Next lngCount
MsgErr_Exit:
Set Inbox = Nothing
Set SubFolder = Nothing
Set olNs = Nothing
Set Item = Nothing
Exit Sub
'// Error information
MsgErr:
MsgBox "An unexpected Error has occurred." _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume MsgErr_Exit
End Sub
Set Reference:
To use outlook objects, in Excel VBE go to Tools, References and check Microsoft Outlook object library.
Set Excel Sheet:
In an Excel sheet, create a table with two columns that the first column contains email subjects and the second column contains folders to which you want those emails to be moved.
Then, insert a shape and right click on that and Assign a Macro, find the name of the macro (MoveEmailsToFolders) and click ok.
Suggestions:
You can develop the code more to disregard matchcase. To do that replace this line:
arr(i, 1) = Item.Subject
with:
Ucase(arr(i, 1)) = Ucase(Item.Subject)
Also, you can move the emails that contain the subject rather than matching an exact title, for example if an email subject had "test", or begins with "test", or ends with "test", then move it to the corresponding folder. Then, the comparison clause would be:
If arr(i, 1) Like Item.Subject & "*" Then 'begins with
If arr(i, 1) Like "*" & Item.Subject & "*" Then 'contains
If arr(i, 1) Like "*" & Item.Subject Then 'ends with
Hope this helps! Please hit the check mark to make this as the right answer to your questions if it did
I would use an explicit reference to your sheet instead of ActiveSheet unless you are actually running the Macro on a bunch of different sheets. And I'm just assuming your data is in column A and B and starts at row 2 for examples sake. This is how you would loop through your data and trying to match the subject, then move it to a folder with the name in the next column if it matches.
If Item.Class = olMail Then
For i = 2 To ActiveSheet.Range("A" & ActiveSheet.Rows.Count).End(xlUp).Row
If ActiveSheet.Range("A" & i).Value = Item.Subject Then
'// Set SubFolder of Inbox
Set SubFolder = Inbox.Folders(ActiveSheet.Range("B" & i).Value)
'// Mark As Read
Item.UnRead = False
'// Move Mail Item to sub Folder
Item.Move SubFolder
End If
Next
End If
There are ways you could check without using a loop as well such as the Find method
Dim rnFind As Range
If Item.Class = olMail Then
Set rnFind = ActiveSheet.Range("A2", ActiveSheet.Range("A" & ActiveSheet.Rows.Count).End(xlUp)).Find(Item.Subject)
If Not rnFind Is Nothing Then
'// Set SubFolder of Inbox
Set SubFolder = Inbox.Folders(rnFind.Offset(, 1).Value)
'// Mark As Read
Item.UnRead = False
'// Move Mail Item to sub Folder
Item.Move SubFolder
End If
End If
Use Do Until IsEmpty loop, Make sure to set Excel Object Referees...
See Example on how to loop from Outlook...
Option Explicit
Public Sub Move_Items()
'// Declare your Variables
Dim Inbox As Outlook.MAPIFolder
Dim SubFolder As Outlook.MAPIFolder
Dim olNs As Outlook.NameSpace
Dim Items As Outlook.Items
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Dim Item As Object
Dim ItemSubject As String
Dim SubFldr As String
Dim lngCount As Long
Dim lngRow As Long
On Error GoTo MsgErr
'// Set Inbox Reference
Set olNs = Application.GetNamespace("MAPI")
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Set Items = Inbox.Items
'// Excel Book Reference
Set xlApp = New Excel.Application
Set xlBook = xlApp.Workbooks.Open("C:\Temp\Book1.xlsx") ' Excel Book Path
lngRow = 2 ' Start Row
With xlBook.Worksheets("Sheet1") ' Sheet Name
Do Until IsEmpty(.Cells(lngRow, 1))
ItemSubject = .Cells(lngRow, 1).Value ' Subject
SubFldr = .Cells(lngRow, 2).Value ' Folder Name
'// Loop through the Items in the folder backwards
For lngCount = Items.Count To 1 Step -1
Set Item = Items.Item(lngCount)
If Item.Class = olMail Then
If Item.Subject = ItemSubject Then
Debug.Print Item.Subject
Set SubFolder = Inbox.Folders(SubFldr) ' Set SubFolder
Debug.Print SubFolder
Item.UnRead = False ' Mark As Read
Item.Move SubFolder ' Move to sub Folder
End If
End If
Next
lngRow = lngRow + 1
Loop
End With
xlBook.Close
MsgErr_Exit:
Set Inbox = Nothing
Set SubFolder = Nothing
Set olNs = Nothing
Set Item = Nothing
Set xlApp = Nothing
Set xlBook = Nothing
Exit Sub
'// Error information
MsgErr:
MsgBox "An unexpected Error has occurred." _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume MsgErr_Exit
End Sub
I'm using VBA in Excel 2010, with Outlook 2010 (already open).
How could I write a sub such that:
1 Outlook address book opens;
2 The user selects a contact and clicks ok;
3 The contact's first name, last name and email address are stored in cells of the active worksheet?
I tried with this method without success: SelectNamesDialog Object
Also I'm not sure if I need to use: Application.GetNamespace("MAPI")
You are on the right avenue, the SelectNamesDialog is exactly what you are looking for. The GetNamepsace method equals to the Session property used in the sample code:
Sub ShowContactsInDialog()
Dim oDialog As SelectNamesDialog
Dim oAL As AddressList
Dim oContacts As Folder
Set oDialog = Application.Session.GetSelectNamesDialog
Set oContacts = _
Application.Session.GetDefaultFolder(olFolderContacts)
'Look for the address list that corresponds with the Contacts folder
For Each oAL In Application.Session.AddressLists
If oAL.GetContactsFolder = oContacts Then
Exit For
End If
Next
With oDialog
'Initialize the dialog box with the address list representing the Contacts folder
.InitialAddressList = oAL
.ShowOnlyInitialAddressList = True
If .Display Then
'Recipients Resolved
'Access Recipients using oDialog.Recipients
End If
End With
End Sub
You may find the following articles helpful:
How to automate Outlook from another program
Automating Outlook from a Visual Basic Application
Here is how to get all the details from a selected contact in the GAL:
You need to open the Global Address List and not the contacts from the contact folder, and use an Outlook.ExchangeUser object as explained on this page: see last answer from David Zemens.
Private Sub cmdSetProjectMember1_Click()
Dim olApp As Outlook.Application
Dim oDialog As SelectNamesDialog
Dim oGAL As AddressList
Dim myAddrEntry As AddressEntry
Dim exchUser As Outlook.ExchangeUser
Dim AliasName As String
Dim FirstName As String
Dim LastName As String
Dim EmailAddress As String
Set olApp = GetObject(, "Outlook.Application")
Set oDialog = olApp.Session.GetSelectNamesDialog
Set oGAL = olApp.GetNamespace("MAPI").AddressLists("Global Address List")
With oDialog
.AllowMultipleSelection = False
.InitialAddressList = oGAL
.ShowOnlyInitialAddressList = True
If .Display Then
AliasName = oDialog.Recipients.Item(1).Name
Set myAddrEntry = oGAL.AddressEntries(AliasName)
Set exchUser = myAddrEntry.GetExchangeUser
If Not exchUser Is Nothing Then
FirstName = exchUser.FirstName
LastName = exchUser.LastName
EmailAddress = exchUser.PrimarySmtpAddress
'...
MsgBox "You selected contact: " & vbNewLine & _
"FirstName: " & FirstName & vbNewLine & _
"LastName:" & LastName & vbNewLine & _
"EmailAddress: " & EmailAddress
End If
End If
End With
Set olApp = Nothing
Set oDialog = Nothing
Set oGAL = Nothing
Set myAddrEntry = Nothing
Set exchUser = Nothing
End Sub