I am trying to extract email addresses of all emails in my Outlook inbox. I found this code on the Internet.
Sub GetALLEmailAddresses()
Dim objFolder As MAPIFolder
Dim strEmail As String
Dim strEmails As String
''' Requires reference to Microsoft Scripting Runtime
Dim dic As New Dictionary
Dim objItem As Object
''Set objFolder = Application.ActiveExplorer.Selection
Set objFolder = Application.GetNamespace("Mapi").PickFolder
For Each objItem In objFolder.Items
If objItem.Class = olMail Then
strEmail = objItem.SenderEmailAddress
If Not dic.Exists(strEmail) Then
strEmails = strEmails + strEmail + vbCrLf
dic.Add strEmail, ""
End If
I am using outlook 2007. When I run this code from the Outlook Visual Basic Editor with F5 I get an error on the following line.
Dim dic As New Dictionary
"user defined type not defined"
I have provided updated code below
to dump the Inbox email addresses to a CSV file "c:\emails.csv" (the current code provides no "outlook" for the collected addresses
the code above works on a selected folder rather than Inbox as per your request
[Update: For clarity this is your old code that uses "early binding", setting this reference is unnecessary for my updated code below which uses "late binding"]
Part A: Your existing code (early binding)
In terms of the error you received:
The code sample aboves uses early binding, this comment "Requires reference to Microsoft Scripting Runtime" indciates that you need to set the reference
Goto the Tools menu
Select 'References'
check "Microdoft Scripting Runtime"
Part B: My new code (late binding - setting the reference is unnecessary)
Working Code
Sub GetALLEmailAddresses()
Dim objFolder As MAPIFolder
Dim strEmail As String
Dim strEmails As String
Dim objDic As Object
Dim objItem As Object
Dim objFSO As Object
Dim objTF As Object
Set objDic = CreateObject("scripting.dictionary")
Set objFSO = CreateObject("scripting.filesystemobject")
Set objTF = objFSO.createtextfile("C:\emails.csv", 2)
Set objFolder = Application.GetNamespace("Mapi").GetDefaultFolder(olFolderInbox)
For Each objItem In objFolder.Items
If objItem.Class = olMail Then
strEmail = objItem.SenderEmailAddress
If Not objDic.Exists(strEmail) Then
objTF.writeline strEmail
objDic.Add strEmail, ""
End If
End If
Next
objTF.Close
End Sub
export the file to C:\Users\Tony\Documents\sent file.CSV
Then use ruby
email_array = []
r = Regexp.new(/\b[a-zA-Z0-9._%+-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}\b/)
CSV.open('C:\Users\Tony\Documents\sent file.CSV', 'r') do |row|
email_array << row.to_s.scan(r)
end
puts email_array.flatten.uniq.inspect
Here's an updated version for those using Exchange. It converts Exchange format addresses to normal email addresses (with the # symbol).
' requires reference to Microsoft Scripting Runtime
Option Explicit
Sub Write_Out_Email_Addresses()
' dictionary for storing email addresses
Dim email_list As New Scripting.Dictionary
' file for output
Dim fso As New Scripting.FileSystemObject
Dim out_file As Scripting.TextStream
Set out_file = fso.CreateTextFile("C:\emails.csv", True)
' open the inbox
Dim ns As Outlook.NameSpace
Set ns = Application.GetNamespace("MAPI")
Dim inbox As MAPIFolder
Set inbox = ns.GetDefaultFolder(olFolderInbox)
' loop through all items (some of which are not emails)
Dim outlook_item As Object
For Each outlook_item In inbox.Items
' only look at emails
If outlook_item.Class = olMail Then
' extract the email address
Dim email_address As String
email_address = GetSmtpAddress(outlook_item, ns)
' add new email addresses to the dictionary and write out
If Not email_list.Exists(email_address) Then
out_file.WriteLine email_address
email_list.Add email_address, ""
End If
End If
Next
out_file.Close
End Sub
' get email address form a Mailoutlook_item
' this entails converting exchange format addresses
' (like " /O=ROOT/OU=ADMIN GROUP/CN=RECIPIENTS/CN=FIRST.LAST")
' to proper email addresses
Function GetSmtpAddress(outlook_item As Outlook.MailItem, ns As Outlook.NameSpace) As String
Dim success As Boolean
success = False
' errors can happen if a user has subsequently been removed from Exchange
On Error GoTo err_handler
Dim email_address As String
email_address = outlook_item.SenderEmailAddress
' if it's an Exchange format address
If UCase(outlook_item.SenderEmailType) = "EX" Then
' create a recipient
Dim recip As Outlook.Recipient
Set recip = ns.CreateRecipient(outlook_item.SenderEmailAddress)
' extract the email address
Dim user As Outlook.ExchangeUser
Set user = recip.AddressEntry.GetExchangeUser()
email_address = user.PrimarySmtpAddress
email_address = user.Name + " <" + user.PrimarySmtpAddress + ">"
success = True
End If
err_handler:
GetSmtpAddress = email_address
End Function
Kudos to http://forums.codeguru.com/showthread.php?441008-Extract-sender-s-email-address-from-an-Exchange-email and Brettdj
In outlook, export a folder to a csv file, then open in Excel. A simple MID function should be able to extract the email address if it's not been placed in a "from" column already.
Related
I would like to run a macro to do follow steps:
- save PDF only attachment to hard drive
- save it with a revise name filename & domain name.
Here is the code I search from open source and mix it together. any help is appreciated. thanks
Public Sub Download_Attachments()
Dim ns As NameSpace
Dim olFolder_Inbox As Folder
Dim olMail As MailItem
Dim olAttachment As Attachment
Dim strFolderPath As String
Dim strFileName As String
Dim strSenderAddress As String
Dim strSenderDomain As String
Dim fso As Object
strFolderPath = "C:\"
Set ns = GetNamespace("MAPI")
Set fso = CreateObject("Scripting.FileSystemObject")
Set olFolder_Inbox = Application.ActiveExplorer.CurrentFolder
Set olMail = Application.ActiveWindow.CurrentItem
'Get sender domain
strSenderAddress = olMail.SenderEmailAddress
strSenderDomain = Right(strSenderAddress, Len(strSenderAddress) - InStr(strSenderAddress, "#"))
For Each olMail In olFolder_Inbox.Items
If TypeName(olMail) = "MailItem" And olMail.Attachments.Count > 0 Then
For Each olAttachment In olMail.Attachments
Select Case UCase(fso.GetExtensionName(olAttachment.FileName))
Case "PDF", "pdf"
olAttachment.SaveAsFile strFolderPath & strFileName
Case Else
'skip
End Select
Next olAttachment
End If
Next olMail
Set olFolder_Inbox = Nothing
Set fso = Nothing
Set ns = Nothing
End Sub
The following line of code retrieves the active folder in the Explorer window, not the Inbox one. Outlook can be started with any active folder, you can specify the folder name to the Outlook.exe file. To get the default folders (Inbox) you need to use the NameSpace.GetDefaultFolder method which returns a Folder object that represents the default folder of the requested type for the current profile; for example, obtains the default Calendar folder for the user who is currently logged on. For example, the following sample code uses the CurrentFolder property to change the displayed folder to the user's default Inbox folder.
Sub ChangeCurrentFolder()
Dim myNamespace As Outlook.NameSpace
Set myNamespace = Application.GetNamespace("MAPI")
Set Application.ActiveExplorer.CurrentFolder = myNamespace.GetDefaultFolder(olFolderInbox)
End Sub
Then it is not really recommended to iterate over all items in the folder.
For Each olMail In olFolder_Inbox.Items
Instead, you need to use the Find/FindNext or Restrict methods of the Items class to get only items that correspond to your conditions. Read more about these methods in the following articles:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder
Finally, the part you are interested in is the SaveAsFile method of the Attachment class which saves the attachment to the specified path:
olAttachment.SaveAsFile strFolderPath & domainName & strFileName
Make sure a qualified file path is passed as a parameter. I'd recommend running the code under the debugger and see what values are passed.
I have developed a form in excel, which is sending an email to a mailbox. This part is working fine.
Now i'm looking to develop an "back-office" excel workbook Which would allow to :
Drag and drop email from outlook to an excel button
Save this email to a folder
Reading this email, and saving all parts (sender's email, subject, body, ...) in an excel spreadsheet.
I'm trying to do the import phase (drag and drop from outlook) but didn't find the way to do this...
Thanks for your help
You cannot drop an email on a button (well, you can but ...)
Instead create an editbox (Outlookbox) and tie it to an event handler.
Here's some code to get you started:
Private Sub Outlookbox_Change()
Dim olApp As Object 'Outlook.Application
Dim olExp As Object 'Outlook.Explorer
Dim olSel As Object 'Outlook.Selection
Dim i As Integer
Dim theSender as String
Dim theDate as String
Dim theRecipient as String
Dim theSubject as String
Dim theMessage as String
Set olApp = GetObject("", "Outlook.Application")
Set olExp = olApp.ActiveExplorer
Set olSel = olExp.Selection
For i = 1 To olSel.Count ' If multiple emails dropped
With olSel.Item(i) ' For each email
theSender = .Sender
theDate = .ReceivedTime
theRecipient = .To
theSubject = .Subject
theMessage = .Body
End With
Next i
End Sub
Regretfully I have no formal background in VBA, but I have been able to learn quite a bit from sites like this.
Problem Statement:
I have a few emails with contain information that needs to be stored in excel. Fortunately I do have working script for that. Not provided to keep this somewhat shorter
The problem that I am facing is that capturing the right email from Microsoft Outlook 2010 and storing the data WITHOUT manual intervention.
The Email will contain a specific word/phrase, "EVEREST". Obviously it is not the only email received. It contains no attachments, and will come from various senders.
I have tried various macros I have found on-line to pull the message from the inbox, but none of them have worked for me.
So I have a macros that will pull messages from a personal folder, that macro then runs another macros that stores the contents of the email to excel, then it moves the message to its final resting place (another personal Folder) currently they all work fine together, but require manual intervention to complete the task. After the message is moved to the personal folder I simply click on a Quick Access Toolboar Icon mapped to a macro
To get the message moved over the personal folder i have a rule set up to move the message based on the word "EVEREST" and runs the initial script.
The problem with all of this is that the message will get moved to the folder, but needs manual intervention to complete the task. I would like it to run automatically.
I have been fumbling around with this for the past 2 months and seem to be in a stalemate. I would greatly appreciate your feedback and assistance.
The following is what I have so far.
My outlook rule set is:
Apply this rule after the message arrives
with "EVEREST" in the subject
and on this computer only
move it to the "EVEREST PRI" folder
and run "Project1.ThisOutlookSession.Everest"
' I believe these were put here when I was trying to run '
' everything via VBA macros, vice using the rule set above '
CLass Module (1)
Option Explicit
Private WithEvents Items As Outlook.Items
Private WithEvents olInboxItems As Items
' ThisOutlookSession contains the following scripts '
'This is the script that is run from the outlook rules '
' all it does is calls the "OCF" Sub below '
Sub Everest(email As MailItem)
OCF
End Sub
'This scipt opens the "EVEREST PRI" personal sub folder'
' and calls the "Prepwork" sub below '
Sub OCF()
Dim objOlApp As Outlook.Application
Dim Ns As Outlook.NameSpace
Dim objFolder As Outlook.Folder
Dim EmailCount As Integer
Set objOlApp = CreateObject("Outlook.Application")
Set Ns = Session.Application.GetNamespace("MAPI")
Set objFolder = Ns.Folders("Personal Folders").Folders("Archives").Folders("EVEREST PRI")
Set objOlApp.ActiveExplorer.CurrentFolder = objFolder
Set objFolder = Nothing
Set objOlApp = Nothing
Prepwork
End Sub
'I had hoped that the following routine would do the rest of the work '
'but it doesn't do it all the time. Most the time the message hasn't been '
'moved to the personal folder before its kicked off. '
'So I thought I would call another macro to play catch up "Wait" below '
Sub Prepwork()
Dim objOlApp As Outlook.Application
Dim Ns As Outlook.NameSpace
Dim objFolder As Outlook.Folder
Dim EmailCount As Integer
Set objOlApp = CreateObject("Outlook.Application")
Set Ns = Session.Application.GetNamespace("MAPI")
Set objFolder = Ns.Folders("Personal Folders").Folders("Archives").Folders("EVEREST PRI")
Set objOlApp.ActiveExplorer.CurrentFolder = objFolder
EmailCount = objFolder.Items.count
If EmailCount = 1 Then
'MsgBox "A COMSPOT has been recieved, acknowledge to update the chart'
' I tried adding this msgbox to provide some time delay, although '
' it has worked from time to time, it still requires manual '
' intervention, which is not desired. '
CopyToExcel
' CopyToExcel is the macro that writes my information to the '
' Spreadsheet. This script has been flawless and I have created '
' a Clickable ICON in the Quick Access Toolboar. '
ElseIf EmailCount = 0 Then
Wait
End If
End Sub
'The following "Wait Script was added, hoping to give time for the other '
'macros to finish, but i suspect they are all linked together, and wont '
'finish until all macroshave finished including the previously mentioned '
' "CopyToExcel" macro. '
' I have also tried to run this macro from the outlook rules, no joy......'
Sub Wait() '(email As MailItem)
' this provides a 5 second wait'
Sleep (5000)
Dim objOlApp As Outlook.Application
Dim Ns As Outlook.NameSpace
Dim objFolder As Outlook.Folder
Dim EmailCount As Integer
Set objOlApp = CreateObject("Outlook.Application")
Set Ns = Session.Application.GetNamespace("MAPI")
Set objFolder = Ns.Folders("Personal Folders").Folders("Archives").Folders("EVEREST PRI")
Set objOlApp.ActiveExplorer.CurrentFolder = objFolder
EmailCount = objFolder.Items.count
If EmailCount = 1 Then
'MsgBox "A COMSPOT has been recieved, acknowledge to update the chart"
CopyToExcel
ElseIf EmailCount = 0 Then
' MsgBox "The second Marco (Wait) did not locate a Message in the PRI Folder. Run the script from the Quick Access Toolboar"
End If
End Sub
' The following macro moves each of the selected items on the screen to an'
' Archive folder. I have not had any problems with this macro '
' This macro is called from the "CopyToExcel" macro. (not shown as it '
' has also worked fine since incorporating it '
Sub ArchiveItems() ' Moves each of the selected items on the screen to an Archive folder.
Dim olApp As New Outlook.Application
Dim olExp As Outlook.Explorer
Dim olSel As Outlook.Selection
Dim olNameSpace As Outlook.NameSpace
Dim olArchive As Outlook.Folder
Dim intItem As Integer
Set olExp = olApp.ActiveExplorer
Set olSel = olExp.Selection
Set olNameSpace = olApp.GetNamespace("MAPI")
' This assumes that you have an Inbox subfolder named Archive.
Set olArchive = olNameSpace.Folders("Personal Folders").Folders("Archives").Folders("EVEREST Archive")
For intItem = 1 To olSel.count
olSel.Item(intItem).Move olArchive
Next intItem
OIB
End Sub
' The following macro simply returns the view to the inbox folder, '
' Thus returning everything to Normal '
' The Ideal of returning to which every folder, or message was open at '
' the time the EVEREST message first arrived I thought would be to '
' complicated, but if any body could solve that... AMAZING.... '
Sub OIB()
Dim objOlApp As Outlook.Application
Dim Ns As Outlook.NameSpace
Dim objFolder As Outlook.Folder
Set objOlApp = CreateObject("Outlook.Application")
Set objFolder = Session.GetDefaultFolder(olFolderInbox)
Set objOlApp.ActiveExplorer.CurrentFolder = objFolder
Set objFolder = Nothing
Set objOlApp = Nothing
End Sub
There is no need to select, you already have the required "email" passed as a parameter by the rule.
The run a script code will look something like this.
Sub Everest(email As MailItem)
Dim Ns As NameSpace
'Dim inboxFolder As Folder
Dim olArchive As Folder
Set Ns = GetNamespace("MAPI")
CopyToExcelWithParameter email
'ArchiveItems
Set olArchive = Ns.Folders("Personal Folders")
Set olArchive = olArchive.Folders("Archives")
Set olArchive = olArchive.Folders("EVEREST Archive")
email.Move olArchive
' Edit: Just realized this was due to
' unnecessary folder selecting that is now gone
' This is unnecessary now as well
'OIB
'Set inboxFolder = Ns.GetDefaultFolder(olFolderInbox)
'Set ActiveExplorer.CurrentFolder = inboxFolder
Set Ns = Nothing
Set olArchive = Nothing
'Set inboxFolder = Nothing
End Sub
You will have to rewrite CopyToExcel to take email as a parameter
Sub CopyToExcelWithParameter (email as mailitem)
' code that processes "email" directly, not a selection
Debug.Print "Do something with " & email.subject
End Sub
Is there a way to extract the details in this dialog box via VBA?
Details Dialog Box http://i.msdn.microsoft.com/dynimg/IC84336.gif
I need, especially the content in the E-Mail address tab.
You can pretty much get the fields easily, the E-mail Addresses is the harder part. References: Microsoft Exchange Property Tags
This code exports some details but most importantly the Email addresses to a text file.
Sub ListGAL()
On Error Resume Next
Const LogFile = "C:\Test\OLK_GAL.log"
Const sSCHEMA = "http://schemas.microsoft.com/mapi/proptag/0x"
Const PR_EMS_AB_PROXY_ADDRESSES = &H800F101E
Dim oNameSpace As NameSpace, oGAL As AddressList, oEntry As AddressEntry
Dim oFSO As Variant, oLF As Variant, oExUser As ExchangeUser, i As Long
' Oulook objects
Set oNameSpace = Outlook.Application.GetNamespace("MAPI")
' Global Address List object
Set oGAL = oNameSpace.AddressLists("Global Address List")
'----------
' Log file objects
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oLF = oFSO.CreateTextFile(LogFile)
'----------
For Each oEntry In oGAL.AddressEntries
i = i + 1
Debug.Print i & vbTab & oEntry.Name
If oEntry.AddressEntryUserType = olExchangeUserAddressEntry Then
oLF.WriteLine "Entry " & i & " (olExchangeUserAddressEntry)"
oLF.WriteLine "Name: " & oEntry.Name
oLF.WriteLine "Address: " & oEntry.Address
Set oExUser = oEntry.GetExchangeUser
' SMTP ADDRESSES
oLF.WriteLine "SMTP Addresses:"
oLF.WriteLine vbTab & Join(oExUser.PropertyAccessor.GetProperty(sSCHEMA & Hex(PR_EMS_AB_PROXY_ADDRESSES)), vbCrLf & vbTab)
Set oExUser = Nothing
oLF.WriteLine String(50, Chr(151)) ' Separator
End If
Next
'----------
' Close Log File, clean up
oLF.Close
Set oGAL = Nothing
Set oNameSpace = Nothing
Set oLF = Nothing
Set oFSO = Nothing
End Sub
i have go a function of reading the address-book:
Function Get_mail(Absender As String)
Dim OutApp As Outlook.Application
Dim OutTI As Outlook.TaskItem
Dim OutRec As Outlook.Recipient
Set OutApp = New Outlook.Application
Set OutTI = OutApp.CreateItem(3)
OutTI.Assign
Set OutRec = OutTI.Recipients.Add(Absender)
OutRec.Resolve
If OutRec.Resolved Then
On Error GoTo exit_function
Get_mail = OutRec.AddressEntry.GetExchangeUser.PrimarySmtpAddress
End If
exit_function: Exit Function
Set OutApp = Nothing
Set OutTI = Nothing
End Function
as far as I know you can only read out the Primary Mail-address from the mail-addresses-tab; to see what else there ist delete the part ".PrimarySmtpAddress", mahe the dot and you should get the list of other properties.
I am quite sure you need the reference on Microsoft Outlook 14.0 Object Library.
The Input "Absender" can be any string . if this string can be resolved as address book-entry in an outlook-mail, you will also have a positive result from the code above.
To call the function, if for example you have a string "mail_adress_from_adressbook" you would put:
mail_adress_from_adressbook = get_mail("Joe Smith")
I hope this helps,
Max
Sure, you can access any GAL object property shown by Outlook (and then some) even if the properties are not explicitly exposed by the AddressEntry or ExchangeUser objects using AddressEntry.PropertyAccessor.GetProperty as long as you know the MAPI property's DASL name
The DASL property names can be retrieved using OutlookSpy (I am its author): either click IAddrBook button to drill down to a particular address entry or, if you have a message addressed to one of the GAL recipients, click IMessage button, go to the GetRecipientTable tab, double click on the recipient to open it as IMailUser:
In your particular case, you need PR_EMS_AB_PROXY_ADDRESSES (DASL name "http://schemas.microsoft.com/mapi/proptag/0x800F101F") - it is a multivalued string property, which means AddressEntry.PropertyAccessor.GetProperty will return an array of strings. Each value is prefixed with the address type (e.g. "EX:" or "smtp:"), the default SMTP address will be prefixed with "SMTP:" (note the upper case):
Set User = Application.session.CurrentUser.AddressEntry
AddressList = User.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x800F101F")
If IsArray(AddressList) Then
For i = LBound(AddressList) To UBound(AddressList)
MsgBox AddressList(i)
Next
End If
I got a code VBA code for extracting email addresses from PST files.
It is very useful as I can choose the folder to have the addresses extracted.
The code is extracting from the "To" field.
I need it to extract from the message body and also the "From" field.
What must I change in the code?
Sub ExtractEmail()
Dim OlApp As Outlook.Application
Dim Mailobject As Object
Dim Email As String
Dim NS As NameSpace
Dim Folder As MAPIFolder
Set OlApp = CreateObject("Outlook.Application")
' Setup Namespace
Set NS = ThisOutlookSession.Session
' Display select folder dialog
Set Folder = NS.PickFolder
' Create Text File
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.CreateTextFile("c:\email addresses.txt", True)
' loop to read email address from mail items.
For Each Mailobject In Folder.Items
Email = Mailobject.To
a.WriteLine (Email)
Next
Set OlApp = Nothing
Set Mailobject = Nothing
a.Close
End Sub
Thank you.
You have the mailItem object so use it to get the fields. Mailobject.Sender, Mailobject.SenderEmailAddress, Mailobject.SenderName and Mailobject.Body, Mailobject.HTMLBody or Mailobject.RTFBody – Sorceri
You are extracting the value of the To property, whcih is a ";" separated list of recipient names. You need to loop through all items in the MailItem.Recipients.Collection and for each recipient read the Recipient.Address property. – Dmitry Streblechenko
Question with no answers, but issue solved in the comments