I found this VBA Outlook code that meets my purpose in theory. objHyperlink seems to return Nothing when I debug.
The outputs are always empty and during debug I get
Runtime error: "13" and Type mismatch
at the line - For Each objHyperlink In objMailDocument.Hyperlinks
Dim objExcelApp As Excel.Application
Dim objExcelWorkbook As Excel.Workbook
Dim objExcelWorksheet As Excel.Worksheet
Sub ExportAllHyperlinksInMultipleEmailsToExcel()
Dim objSelection As Selection
Dim objMail As MailItem
Dim objMailDocument As Document
Dim objHyperlink As Hyperlink
Dim i As Long
Set objSelection = Outlook.Application.ActiveExplorer.Selection
If Not (objSelection Is Nothing) Then
Set objExcelApp = CreateObject("Excel.Application")
Set objExcelWorkbook = objExcelApp.Workbooks.Add
Set objExcelWorksheet = objExcelWorkbook.Sheets(1)
objExcelApp.Visible = True
objExcelWorkbook.Activate
With objExcelWorksheet
.Cells(1, 1) = "Email"
.Cells(1, 2) = "Text"
.Cells(1, 3) = "Link"
.Cells(1, 4) = "Source"
End With
i = 0
For Each objMail In objSelection
Set objMailDocument = objMail.GetInspector.WordEditor
If objMailDocument.Hyperlinks.Count > 0 Then <- Correct # of links shown here
For Each objHyperlink In objMailDocument.Hyperlinks <- Debug highlights this
If InStr(objHyperlink.Address, "www.") > 0 Then
i = i + 1
Call ExportToExcel(i, objMail, objHyperlink)
End If
Next
End If
objMail.Close olDiscard
Next
objExcelWorksheet.Columns("A:D").AutoFit
End If
End Sub
Sub ExportToExcel(n As Long, objCurrentMail As MailItem, objCurrentHyperlink As Hyperlink)
Dim nLastRow As Integer
nLastRow = objExcelWorksheet.Range("A" & objExcelWorksheet.Rows.Count).End(xlUp).Row + 1
objExcelWorksheet.Range("A" & nLastRow) = n
objExcelWorksheet.Range("B" & nLastRow) = objCurrentHyperlink.TextToDisplay
objExcelWorksheet.Range("C" & nLastRow) = objCurrentHyperlink.Address
objExcelWorksheet.Range("D" & nLastRow) = objCurrentMail.Subject
End Sub
Thanks to #CDP1802 for pointing out a couple of changes to try. This does work with the following code:
Dim objExcelApp As Excel.Application
Dim objExcelWorkbook As Excel.Workbook
Dim objExcelWorksheet As Excel.Worksheet
Sub ExportAllHyperlinksInMultipleEmailsToExcel()
Dim objSelection As Selection
Dim objMail As MailItem
Dim objMailDocument As Word.Document << Added Word. here
Dim objHyperlink As Word.Hyperlink << Added Word. here
Dim i As Long
Set objSelection = Outlook.Application.ActiveExplorer.Selection
If Not (objSelection Is Nothing) Then
Set objExcelApp = CreateObject("Excel.Application")
Set objExcelWorkbook = objExcelApp.Workbooks.Add
Set objExcelWorksheet = objExcelWorkbook.Sheets(1)
objExcelApp.Visible = True
objExcelWorkbook.Activate
With objExcelWorksheet
.Cells(1, 1) = "Email"
.Cells(1, 2) = "Text"
.Cells(1, 3) = "Link"
.Cells(1, 4) = "Source"
End With
i = 0
For Each objMail In objSelection
Set objMailDocument = objMail.GetInspector.WordEditor
If objMailDocument.Hyperlinks.Count > 0 Then
For Each objHyperlink In objMailDocument.Hyperlinks
If InStr(objHyperlink.Address, "www.") > 0 Then
i = i + 1
Call ExportToExcel(i, objMail, objHyperlink)
End If
Next
End If
objMail.Close olDiscard
Next
objExcelWorksheet.Columns("A:D").AutoFit
End If
End Sub
Sub ExportToExcel(n As Long, objCurrentMail As MailItem, objCurrentHyperlink As Word.Hyperlink) << Added Word. here
Dim nLastRow As Integer
nLastRow = objExcelWorksheet.Range("A" & objExcelWorksheet.Rows.Count).End(xlUp).Row + 1
objExcelWorksheet.Range("A" & nLastRow) = n
objExcelWorksheet.Range("B" & nLastRow) = objCurrentHyperlink.TextToDisplay
objExcelWorksheet.Range("C" & nLastRow) = objCurrentHyperlink.Address
objExcelWorksheet.Range("D" & nLastRow) = objCurrentMail.Subject
End Sub
Related
I am trying output a list of everyone that has emailed me, and the count of emails they sent.
I have two email accounts set up on Outlook (account A and account B). The below VBA outputs a count of users from the inbox folder for account A.
Is there a way to retrieve this data from a folder called 'Done' for Account B?
Sub CountInboxEmailsbySender()
Dim objDictionary As Object
Dim objInbox As Outlook.Folder
Dim i As Long
Dim objMail As Outlook.MailItem
Dim strSender As String
Dim objExcelApp As Excel.Application
Dim objExcelWorkbook As Excel.Workbook
Dim objExcelWorksheet As Excel.Worksheet
Dim varSenders As Variant
Dim varItemCounts As Variant
Dim nLastRow As Integer
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objInbox = Outlook.Application.Session.Accounts.Item("edr.hub#bt.com")
For i = objInbox.Items.Count To 1 Step -1
If objInbox.Items(i).Class = olMail Then
Set objMail = objInbox.Items(i)
strSender = objMail.SenderEmailAddress
If objDictionary.Exists(strSender) Then
objDictionary.Item(strSender) = objDictionary.Item(strSender) + 1
Else
objDictionary.Add strSender, 1
End If
End If
Next
Set objExcelApp = CreateObject("Excel.Application")
objExcelApp.Visible = True
Set objExcelWorkbook = objExcelApp.Workbooks.Add
Set objExcelWorksheet = objExcelWorkbook.Sheets(1)
With objExcelWorksheet
.Cells(1, 1) = "Sender"
.Cells(1, 2) = "Count"
End With
varSenders = objDictionary.Keys
varItemCounts = objDictionary.Items
For i = LBound(varSenders) To UBound(varSenders)
nLastRow = objExcelWorksheet.Range("A" & objExcelWorksheet.Rows.Count).End(xlUp).Row + 1
With objExcelWorksheet
.Cells(nLastRow, 1) = varSenders(i)
.Cells(nLastRow, 2) = varItemCounts(i)
End With
Next
objExcelWorksheet.Columns("A:B").AutoFit
End Sub
I'm trying to parse Outlook emails into an Excel spreadsheet.
All of the "vText"s are being output in column B and not B through E.
Original email text:
Caller: First Last
Phone: 123-456-7890
For: Company Name - Address
City: Metropolis
MSGID: 3068749608
I extract the Caller, Phone and MSGID fields just fine, but parsing the Company Name hasn't worked. It randomly pastes the Phone or MSGID values into that column instead.
Option Explicit
Private Const xlUp As Long = -4162
Sub CopyAllMessagesToExcel()
Dim objOL As Outlook.Application
Dim objItems As Outlook.Items
Dim objFolder As Outlook.MAPIFolder
Dim olItem As Outlook.MailItem
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim vText, vText2, vText3, vText4, vText5 As Variant
Dim sText As String
Dim rCount As Long
Dim bXStarted As Boolean
Dim enviro As String
Dim strPath As String
Dim Reg1 As Object
Dim M1 As Object
Dim M As Object
Dim OutlookNamespace As NameSpace
enviro = CStr(Environ("USERPROFILE"))
'the path of the workbook
strPath = enviro & "file path"
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Application.StatusBar = "Please wait while Excel source is opened ... "
Set xlApp = CreateObject("Excel.Application")
bXStarted = True
End If
On Error GoTo 0
'Open the workbook to input the data
Set xlWB = xlApp.Workbooks.Open(strPath)
Set xlSheet = xlWB.Sheets("Sheet1")
'Find the next empty line of the worksheet
'rCount = xlSheet.Range("B" & xlSheet.Rows.Count).End(xlUp).Row 'original code
rCount = xlSheet.Range("A" & xlSheet.Rows.Count).End(xlUp).Row
rCount = rCount + 1
Set objOL = Outlook.Application
Set OutlookNamespace = objOL.GetNamespace("MAPI")
Set objFolder = OutlookNamespace.GetDefaultFolder(olFolderInbox).Folders("SubFolder").Folders("SubSubFolder")
Set objItems = objFolder.Items
For Each olItem In objItems
On Error Resume Next
With olItem
sText = olItem.Body
Set Reg1 = CreateObject("VBScript.RegExp")
' \s* = invisible spaces
' \d* = match digits
' \w* = match alphanumeric
Dim i As Integer
For i = 1 To 4
With Reg1
'.IgnoreCase = True
Select Case i 'each Case = one specific string parsed
Case 1
'pull everything after Caller (separated by :), and stop at line end \n
.Pattern = "(Caller[:]([\w-\s]*)\s*)\n"
Case 2
.Pattern = "(Phone[:]([\d-\s]*)\s*)\n"
'#### CASE 3 NOT WORKING
Case 3
'pull everything after For (separated by :), and stop at the dash [-]
.Pattern = "(For[:]([\w-\s]*)\s*)[-]"
Case 4
'pull everything after MSGID, and stop at the dash [-]
.Pattern = "(MSGID[:]([\w-\s]*)\s*)[-]"
End Select
End With
If Reg1.Test(sText) Then
' each "(\w*)" and the "(\s)" are assigned a vText variable
Set M1 = Reg1.Execute(sText)
For Each M In M1
vText = Trim(M.SubMatches(1))
vText2 = Trim(M.SubMatches(2))
vText3 = Trim(M.SubMatches(3))
vText4 = Trim(M.SubMatches(4))
Next
xlSheet.Range("a" & rCount) = .ReceivedTime
xlSheet.Range("b" & rCount) = vText
xlSheet.Range("c" & rCount) = vText2
xlSheet.Range("d" & rCount) = vText3
xlSheet.Range("e" & rCount) = vText4
'xlSheet.Range("D" & rCount) = .Subject
'xlSheet.Range("f" & rCount) = vText5
'##Checking on output per iteration:
'MsgBox ("inputting data in row #" & rCount)
' next line
rCount = rCount + 1
End If
Next i
' do whatever
Debug.Print .Subject
End With
Next
'xlWB.Close 1
'If bXStarted Then
' xlApp.Quit
'End If
Set M = Nothing
Set M1 = Nothing
Set Reg1 = Nothing
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
Set objItems = Nothing
Set objFolder = Nothing
Set objOL = Nothing
End Sub
I'd move the regex into a separate function:
Function ExtractText(txt As String, patt As String)
Static reg As Object
Dim matches, rv As String 'EDIT: moved from Static line
If reg Is Nothing Then
Set reg = CreateObject("VBScript.RegExp")
'set up IgnoreCase etc here...
End If
reg.Pattern = patt
If reg.Test(txt) Then
Set matches = reg.Execute(txt)
rv = matches(0).submatches(1)
End If
ExtractText = rv
End Function
Then the core of your main code becomes something like this:
Set objOL = Outlook.Application
Set OutlookNamespace = objOL.GetNamespace("MAPI")
Set objFolder = OutlookNamespace.GetDefaultFolder(olFolderInbox).Folders("SubFolder").Folders("SubSubFolder")
Set objItems = objFolder.Items
For Each olItem In objItems
sText = olItem.Body
xlSheet.Range("a" & rCount) = .ReceivedTime
xlSheet.Range("b" & rCount) = ExtractText(sText, "(Caller[:]([\w-\s]*)\s*)\n")
xlSheet.Range("c" & rCount) = ExtractText(sText, "(Phone[:]([\d-\s]*)\s*)\n")
xlSheet.Range("d" & rCount) = ExtractText(sText, "(For[:]([\w-\s]*)\s*)[-]")
xlSheet.Range("e" & rCount) = ExtractText(sText, "(MSGID:\s?(\d{1,})-)")'<<edit
'xlSheet.Range("D" & rCount) = .Subject
'xlSheet.Range("f" & rCount) = vText5
'MsgBox ("inputting data in row #" & rCount)
rCount = rCount + 1
Next olItem
I've been trying to export details about my incoming emails to an Excel spreadsheet. The code works as it should except for returning display names for the recipients in the "To" and "CC" fields.
I tried several variations.
I'm using the below code that I found online:
Public WithEvents objMails As Outlook.Items
Private Sub Application_Startup()
Set objMails = Outlook.Application.Session.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub objMails_ItemAdd(ByVal Item As Object)
Dim objMail As Outlook.MailItem
Dim Recipient As Outlook.Recipient
Dim strExcelFile As String
Dim objExcelApp As Excel.Application
Dim objExcelWorkBook As Excel.Workbook
Dim objExcelWorkSheet As Excel.Worksheet
Dim nNextEmptyRow As Integer
Dim strColumnB As String
Dim strColumnC As String
Dim strColumnD As String
Dim strColumnE As String
Dim strColumnF As String
Dim strColumnG As String
If Item.Class = olMail Then
Set objMail = Item
End If
'Specify the Excel file which you want to auto export the email list
'You can change it as per your case
strExcelFile = "C:\Users\yakir.machluf\Documents\Outlook automation test.xlsx"
'Get Access to the Excel file
On Error Resume Next
Set objExcelApp = GetObject(, "Excel.Application")
If Error <> 0 Then
Set objExcelApp = CreateObject("Excel.Application")
End If
Set objExcelWorkBook = objExcelApp.Workbooks.Open(strExcelFile)
Set objExcelWorkSheet = objExcelWorkBook.Sheets("Sheet1")
'Get the next empty row in the Excel worksheet
nNextEmptyRow = objExcelWorkSheet.Range("B" & objExcelWorkSheet.Rows.Count).End(xlUp).Row + 1
'Specify the corresponding values in the different columns
strColumnB = objMail.SenderName
strColumnC = objMail.SenderEmailAddress
strColumnD = objMail.Subject
strColumnE = objMail.ReceivedTime
strColumnF = objMail.To
strColumnG = objMail.CC
'Add the vaules into the columns
objExcelWorkSheet.Range("A" & nNextEmptyRow) = nNextEmptyRow - 1
objExcelWorkSheet.Range("B" & nNextEmptyRow) = strColumnB
objExcelWorkSheet.Range("C" & nNextEmptyRow) = strColumnC
objExcelWorkSheet.Range("D" & nNextEmptyRow) = strColumnD
objExcelWorkSheet.Range("E" & nNextEmptyRow) = strColumnE
objExcelWorkSheet.Range("F" & nNextEmptyRow) = strColumnF
objExcelWorkSheet.Range("G" & nNextEmptyRow) = strColumnG
'Fit the columns from A to G
objExcelWorkSheet.Columns("A:G").AutoFit
'Save the changes and close the Excel file
objExcelWorkBook.Close SaveChanges:=True
End Sub
.Recipient has an .Address property.
Recipient.Address property (Outlook) https://learn.microsoft.com/en-us/office/vba/api/outlook.recipient.address
Option Explicit
Public WithEvents objMails As Items
Private Sub Application_Startup()
Set objMails = Session.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub objMails_ItemAdd(ByVal Item As Object)
Dim objMail As MailItem
Dim i As Long
Dim recipAddresses As String
If Item.Class = olMail Then
Set objMail = Item
For i = 1 To objMail.Recipients.Count
recipAddresses = recipAddresses & objMail.Recipients(i).Address & " "
Next
Debug.Print Trim(recipAddresses)
End If
End Sub
Private Sub test_objMails_ItemAdd()
objMails_ItemAdd ActiveInspector.CurrentItem
End Sub
Code in detail:
Option Explicit
Private Sub objMails_ItemAdd(ByVal Item As Object)
Dim objMail As MailItem
Dim recip As Recipient
Dim recipAddressesTo As String
Dim recipAddressesCC As String
Dim i As Long
Dim strExcelFile As String
' Early binding - Set reference to Excel XX.X Object Library
Dim objExcelApp As Excel.Application
Dim objExcelWorkBook As Excel.Workbook
Dim objExcelWorkSheet As Excel.Worksheet
Dim nNextEmptyRow As Long
If Item.Class = olMail Then
Set objMail = Item
'Specify the Excel file
strExcelFile = "C:\Users\yakir.machluf\Documents\Outlook automation test.xlsx"
'Get the Excel file
' Bypass normal error handling
On Error Resume Next ' To be used for a specific purpose
Set objExcelApp = GetObject(, "Excel.Application")
' ?
Debug.Print " Error: " & Error
'If Error <> 0 Then
Debug.Print " Err..: " & Err
If Err <> 0 Then
Set objExcelApp = CreateObject("Excel.Application")
End If
' Return to normal error handling
On Error GoTo 0 ' Consider mandatory after On Error Resume Next
Set objExcelWorkBook = objExcelApp.Workbooks.Open(strExcelFile)
Set objExcelWorkSheet = objExcelWorkBook.Sheets("Sheet1")
With objExcelWorkSheet
'Get the next empty row in the Excel worksheet
nNextEmptyRow = .Range("B" & .Rows.Count).End(xlUp).Row + 1
'Specify the corresponding values in the different columns
.Range("A" & nNextEmptyRow) = nNextEmptyRow - 1
.Range("B" & nNextEmptyRow) = objMail.senderName
.Range("C" & nNextEmptyRow) = objMail.SenderEmailAddress
.Range("D" & nNextEmptyRow) = objMail.Subject
.Range("E" & nNextEmptyRow) = objMail.ReceivedTime
For i = 1 To objMail.Recipients.Count
Set recip = objMail.Recipients(i)
If recip.Type = olTo Then
recipAddressesTo = recipAddressesTo & recip.Address & " "
ElseIf recip.Type = olCC Then
recipAddressesCC = recipAddressesCC & recip.Address & " "
End If
Next
' Trim the space character at the end
objExcelWorkSheet.Range("F" & nNextEmptyRow) = Trim(recipAddressesTo)
objExcelWorkSheet.Range("G" & nNextEmptyRow) = Trim(recipAddressesCC)
'Fit the columns from A to G
objExcelWorkSheet.Columns("A:G").AutoFit
End With
'Save the changes and close the Excel file
objExcelWorkBook.Close SaveChanges:=True
End If
End Sub
Thanks to niton, I ended up tweaking the code and using the following.
The new problem I'm facing is trying to get the exchange addresses to appear as regular email addresses.
Any hints?
Public WithEvents objMails As Outlook.Items
Private Sub Application_Startup()
Set objMails = Outlook.Application.Session.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub objMails_ItemAdd(ByVal Item As Object)
Dim objMail As Outlook.MailItem
Dim Recipient As Outlook.Recipient
Dim recipAddressesTo As String
Dim recipAddressesCC As String
Dim i As Long
Dim strExcelFile As String
Dim objExcelApp As Excel.Application
Dim objExcelWorkBook As Excel.Workbook
Dim objExcelWorkSheet As Excel.Worksheet
Dim nNextEmptyRow As Integer
Dim strColumnB As String
Dim strColumnC As String
Dim strColumnD As String
Dim strColumnE As String
Dim strColumnF As String
Dim strColumnG As String
If Item.Class = olMail Then
Set objMail = Item
End If
'Specify the Excel file which you want to auto export the email list
'You can change it as per your case
strExcelFile = "C:\Users\yakir.machluf\Documents\Outlook automation test.xlsx"
'Get Access to the Excel file
On Error Resume Next
Set objExcelApp = GetObject(, "Excel.Application")
If Error <> 0 Then
Set objExcelApp = CreateObject("Excel.Application")
End If
Set objExcelWorkBook = objExcelApp.Workbooks.Open(strExcelFile)
Set objExcelWorkSheet = objExcelWorkBook.Sheets("Sheet1")
'Get the next empty row in the Excel worksheet
nNextEmptyRow = objExcelWorkSheet.Range("B" & objExcelWorkSheet.Rows.Count).End(xlUp).Row + 1
'Add the vaules into the columns
objExcelWorkSheet.Range("A" & nNextEmptyRow) = nNextEmptyRow - 1
objExcelWorkSheet.Range("B" & nNextEmptyRow) = objMail.SenderName
objExcelWorkSheet.Range("C" & nNextEmptyRow) = objMail.SenderEmailAddress
objExcelWorkSheet.Range("D" & nNextEmptyRow) = objMail.Subject
objExcelWorkSheet.Range("E" & nNextEmptyRow) = objMail.ReceivedTime
For i = 1 To objMail.Recipients.Count
Set recip = objMail.Recipients(i)
If recip.Type = olTo Then
recipAddressesTo = recipAddressesTo & recip.Address & " "
ElseIf recip.Type = olCC Then
recipAddressesCC = recipAddressesCC & recip.Address & " "
End If
Next
' Trim the space character at the end
objExcelWorkSheet.Range("F" & nNextEmptyRow) = Trim(recipAddressesTo)
objExcelWorkSheet.Range("G" & nNextEmptyRow) = Trim(recipAddressesCC)
'Fit the columns from A to G
objExcelWorkSheet.Columns("A:G").AutoFit
'Save the changes and close the Excel file
objExcelWorkBook.Close SaveChanges:=True
End Sub
I have the following macro in Outlook, and would like to use it frm Excel, how can I rewrite it that it will work from excel without an outlook macro being included?
Dim objExcelApp As Excel.Application
Dim objExcelWorkbook As Excel.Workbook
Dim objExcelWorksheet As Excel.Worksheet
Public Sub ExportAllFlaggedEmailsToExcel()
Dim objOutlookFile As Outlook.Folder
Dim objFolder As Outlook.Folder
Dim objNameSpace As NameSpace
Dim mailboxowner As Outlook.Recipient
Dim Shared_email_address As Folder
Dim outlookAPP As Outlook.Application
Set outlookAPP = Outlook.Application
Set objOutlookFile = Outlook.Application.Session.PickFolder
Set objNameSpace = Application.GetNamespace("MAPI")
'If Not (objOutlookFile Is Nothing) Then
'Create a new Excel file
Set objExcelApp = CreateObject("Excel.Application")
Set objExcelWorkbook = objExcelApp.Workbooks.Add
Set objExcelWorksheet = objExcelWorkbook.Sheets("sheet1")
objExcelApp.Visible = True
'Name_of_the_excel_file_created_by_the_vba = ActiveWorkbook.Name
'Name_of_the_excel_file_created_by_the_vba.Select
With objExcelWorksheet
.Cells(1, 1) = "Subject"
.Cells(1, 1).Font.Bold = True
.Cells(1, 2) = "Email was sent On"
.Cells(1, 2).Font.Bold = True
.Cells(1, 3) = "From"
.Cells(1, 3).Font.Bold = True
.Cells(1, 4) = "To"
.Cells(1, 4).Font.Bold = True
.Cells(1, 5) = "Categroy"
.Cells(1, 5).Font.Bold = True
End With
For Each objFolder In objOutlookFile.Folders
If objFolder.DefaultItemType = olMailItem Then
Call ProcessMailFolders(objFolder)
End If
Next
objExcelWorksheet.Columns("A:F").AutoFit
MsgBox "Completed!", vbInformation + vbOKOnly, "Export Emails"
'End If
End Sub
Public Sub ProcessMailFolders(ByVal objCurrentFolder As Outlook.Folder)
Dim i As Long
Dim objMail As Outlook.MailItem
Dim objFlaggedMail As Outlook.MailItem
Dim nLastRow As Integer
Dim objSubfolder As Outlook.Folder
'***********************
'Outlook to export categorised emails to excel
'***********************
amount_of_emails = objCurrentFolder.Items.Count
For i = 1 To objCurrentFolder.Items.Count
If objCurrentFolder.Items(i).Class = olMail Then
'Export the information of each flagged email to Excel
Set objMail = objCurrentFolder.Items(i)
On Error Resume Next
If objMail.Categories = "Category_Name" Then
Set objFlaggedMail = objMail
With objExcelWorksheet
nLastRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
.Range("A" & nLastRow) = objFlaggedMail.Subject
.Range("B" & nLastRow) = objFlaggedMail.SentOn
'.Range("C" & nLastRow) = objFlaggedMail.ReceivedTime
.Range("C" & nLastRow) = objFlaggedMail.SenderName
.Range("D" & nLastRow) = objFlaggedMail.To
.Range("E" & nLastRow) = "Category_Name"
End With
End If
End If
Next i
If objCurrentFolder.Folders.Count > 0 Then
For Each objSubfolder In objCurrentFolder.Folders
Call ProcessMailFolders(objSubfolder)
Next
End If
end sub
I know that it is not supported to call an outlook function/macro from excel, so therefore I would like to implement this on excel level, how could I start it?
See if you can modify this to do what you want (run from Excel).
Option Explicit On
Const fPath As String = "C:\Users\your_path_here\" 'The path to save the messages
Sub Download_Outlook_Mail_To_Excel()
Dim olApp As Object
Dim olFolder As Object
Dim olNS As Object
Dim xlBook As Workbook
Dim xlSheet As Worksheet
Dim NextRow As Long
Dim i As Long
Dim olItem As Object
Set xlBook = Workbooks.Add
Set xlSheet = xlBook.Sheets(1)
On Error Resume Next
Set olApp = GetObject(, "Outlook.Application")
If Err() <> 0 Then
Set olApp = CreateObject("Outlook.Application")
End If
On Error GoTo 0
With xlSheet
.Cells(1, 1) = "Sender"
.Cells(1, 2) = "Subject"
.Cells(1, 3) = "Date"
.Cells(1, 4) = "Size"
.Cells(1, 5) = "EmailID"
.Cells(1, 6) = "Body"
CreateFolders fPath
Set olNS = olApp.GetNamespace("MAPI")
Set olFolder = olNS.PickFolder
For Each olItem In olFolder.Items
NextRow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
If olItem.Class = 43 Then
.Cells(NextRow, 1) = olItem.Sender
.Cells(NextRow, 2) = olItem.Subject
.Cells(NextRow, 3) = olItem.SentOn
'.Cells(NextRow, 4) =
.Cells(NextRow, 5) = SaveMessage(olItem)
'.Cells(NextRow, 6) = olItem.Body 'Are you sure?
End If
Next olItem
End With
MsgBox "Outlook Mails Extracted to Excel"
lbl_Exit:
Set olApp = Nothing
Set olFolder = Nothing
Set olItem = Nothing
Set xlBook = Nothing
Set xlSheet = Nothing
Exit Sub
End Sub
Function SaveMessage(olItem As Object) As String
Dim Fname As String
Fname = Format(olItem.ReceivedTime, "yyyymmdd") & Chr(32) &
Format(olItem.ReceivedTime, "HH.MM") & Chr(32) & olItem.sendername & " - " & olItem.Subject
Fname = Replace(Fname, Chr(58) & Chr(41), "")
Fname = Replace(Fname, Chr(58) & Chr(40), "")
Fname = Replace(Fname, Chr(34), "-")
Fname = Replace(Fname, Chr(42), "-")
Fname = Replace(Fname, Chr(47), "-")
Fname = Replace(Fname, Chr(58), "-")
Fname = Replace(Fname, Chr(60), "-")
Fname = Replace(Fname, Chr(62), "-")
Fname = Replace(Fname, Chr(63), "-")
Fname = Replace(Fname, Chr(124), "-")
SaveMessage = SaveUnique(olItem, fPath, Fname)
lbl_Exit:
Exit Function
End Function
Private Function SaveUnique(oItem As Object,
strPath As String,
strFileName As String) As String
Dim lngF As Long
Dim lngName As Long
lngF = 1
lngName = Len(strFileName)
Do While FileExists(strPath & strFileName & ".msg") = True
strFileName = Left(strFileName, lngName) & "(" & lngF & ")"
lngF = lngF + 1
Loop
oItem.SaveAs strPath & strFileName & ".msg"
SaveUnique = strPath & strFileName & ".msg"
lbl_Exit:
Exit Function
End Function
Private Sub CreateFolders(strPath As String)
Dim strTempPath As String
Dim iPath As Long
Dim vPath As Variant
vPath = Split(strPath, "\")
strPath = vPath(0) & "\"
For iPath = 1 To UBound(vPath)
strPath = strPath & vPath(iPath) & "\"
If Not FolderExists(strPath) Then MkDir strPath
Next iPath
End Sub
Private Function FolderExists(ByVal PathName As String) As Boolean
Dim nAttr As Long
On Error GoTo NoFolder
nAttr = GetAttr(PathName)
If (nAttr And vbDirectory) = vbDirectory Then
FolderExists = True
End If
NoFolder:
End Function
Private Function FileExists(filespec) As Boolean
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(filespec) Then
FileExists = True
Else
FileExists = False
End If
lbl_Exit:
Exit Function
End Function
Could you advise please how to export emails from excel files?
I have an excel files with column called emails - this is a list of emails.
How can VBA script check every email from excel file in outlook and export emails with subject, data, sender from these excel file to new excel file or new sheet in current excel.
I have this script:
Const MACRO_NAME = "Export Messages to Excel (Rev 4)"
Sub ExportMessagesToExcelbyDate()
Dim olkLst As Object, _
olkMsg As Object, _
excApp As Object, _
excWkb As Object, _
excWks As Object, _
intRow As Integer, _
intVersion As Integer, _
strFilename As String, _
strDateRange As String, _
arrTemp As Variant, _
datStart As Date, _
datEnd As Date
strFilename = InputBox("Enter a filename to save the exported messages to.", , MICRO_NAME)
If strFilename <> "" Then
strDateRange = InputBox("Enter the date range of the messages to export in the form ""mm/dd/yyyy to mm/dd/yyyy""", MACRO_NAME, Date & " to " & Date)
arrTemp = Split(strDateRange, "to")
datStart = IIf(IsDate(arrTemp(0)), arrTemp(0), Date) & " 12:00am"
datEnd = IIf(IsDate(arrTemp(1)), arrTemp(1), Date) & " 11:59pm"
intVersion = GetOutlookVersion()
Set excApp = CreateObject("Excel.Application")
Set excWkb = excApp.Workbooks.Add()
Set excWks = excWkb.ActiveSheet
'Write Excel Column Headers
With excWks
.Cells(1, 1) = "Subject"
.Cells(1, 2) = "Received"
.Cells(1, 3) = "Sender"
End With
intRow = 2
'Write messages to spreadsheet
Set olkLst = Application.ActiveExplorer.CurrentFolder.Items.Restrict("[ReceivedTime] >= '" & Format(datStart, "ddddd h:nn AMPM") & "'" & " AND [ReceivedTime] <= '" & Format(datEnd, "ddddd h:nn AMPM") & "'")
For Each olkMsg In olkLst
'Only export messages, not receipts or appointment requests, etc.
If olkMsg.Class = olMail Then
'Add a row for each field in the message you want to export
excWks.Cells(intRow, 1) = olkMsg.Subject
excWks.Cells(intRow, 2) = olkMsg.ReceivedTime
excWks.Cells(intRow, 3) = GetSMTPAddress(olkMsg, intVersion)
intRow = intRow + 1
End If
Next
Set olkMsg = Nothing
excWkb.SaveAs strFilename
excWkb.Close
End If
Set olkLst = Nothing
Set excWks = Nothing
Set excWkb = Nothing
Set excApp = Nothing
MsgBox "Process complete. A total of " & intRow - 2 & " messages were exported.", vbInformation + vbOKOnly, MICRO_NAME
End Sub
Private Function GetSMTPAddress(Item As Outlook.MailItem, intOutlookVersion As Integer) As String
Dim olkSnd As Outlook.AddressEntry, olkEnt As Object
On Error Resume Next
Select Case intOutlookVersion
Case Is < 14
If Item.SenderEmailType = "EX" Then
GetSMTPAddress = SMTP2007(Item)
Else
GetSMTPAddress = Item.SenderEmailAddress
End If
Case Else
Set olkSnd = Item.Sender
If olkSnd.AddressEntryUserType = olExchangeUserAddressEntry Then
Set olkEnt = olkSnd.GetExchangeUser
GetSMTPAddress = olkEnt.PrimarySmtpAddress
Else
GetSMTPAddress = Item.SenderEmailAddress
End If
End Select
On Error GoTo 0
Set olkPrp = Nothing
Set olkSnd = Nothing
Set olkEnt = Nothing
End Function
Function GetOutlookVersion() As Integer
Dim arrVer As Variant
arrVer = Split(Outlook.Version, ".")
GetOutlookVersion = arrVer(0)
End Function
Function SMTP2007(olkMsg As Outlook.MailItem) As String
Dim olkPA As Outlook.PropertyAccessor
On Error Resume Next
Set olkPA = olkMsg.PropertyAccessor
SMTP2007 = olkPA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x5D01001E")
On Error GoTo 0
Set olkPA = Nothing
End Function
But this script export only selected folder in outlook.
What is the more important it should be exported from conversation history. For example in excel file there is mailbox YourMailbox#gmail.com. Script should find all conversation history and emails with this person and export information from emails. Information such as Subject, sender, date. Also script should check all list emails from excel file, not one.
Thanks for advices.
Application.ActiveExplorer.CurrentFolder will get current select folder, If you want to get all folder, you could refer to the below code:
Option Explicit
Sub repopulate3()
Dim olApp As Outlook.Application
Dim olNs As Outlook.Namespace
Dim olparentfolder As Outlook.Folder
Dim olMail As Object
Dim eFolder As Object
Dim i As Long
Dim wb As Workbook
Dim ws As Worksheet
Dim iCounter As Long
Dim lrow As Long
Dim lastrow As Long
'Set wb = ActiveWorkbook
'Set ws = wb.Worksheets("vlookup")
On Error Resume Next
Set olApp = GetObject(, "Outlook.Application")
On Error GoTo 0
If olApp Is Nothing Then
Set olApp = CreateObject("Outlook.Application")
End If
Set olNs = olApp.GetNamespace("MAPI")
Set olparentfolder = olNs.GetDefaultFolder(olFolderInbox)
'wb.Sheets("vlookup").range("A2:C500").ClearContents
'i think you want column E here, not L?
'lastrow = ThisWorkbook.Worksheets("vlookup").Cells(Rows.count, "E").End(xlUp).Row
ProcessFolder olparentfolder
ExitRoutine:
Set olparentfolder = Nothing
Set olNs = Nothing
Set olApp = Nothing
End Sub
Private Sub ProcessFolder(ByVal oParent As Outlook.Folder)
Dim olFolder As Outlook.Folder
Dim olMail As Object
Dim i As Long
Dim wb As Workbook
Dim ws As Worksheet
Dim iCounter As Long
Dim lrow As Long
Dim lastrow As Long
'Set wb = ActiveWorkbook
'Set ws = wb.Worksheets("vlookup")
'lastrow = ThisWorkbook.Worksheets("vlookup").Cells(Rows.count, "E").End(xlUp).Row
For i = oParent.Items.Count To 1 Step -1
Debug.Print oParent
If TypeOf oParent.Items(i) Is MailItem Then
Set olMail = oParent.Items(i)
Debug.Print " " & olMail.Subject
Debug.Print " " & olMail.ReceivedTime
Debug.Print " " & olMail.SenderEmailAddress
Debug.Print
'For iCounter = 2 To lastrow
'If InStr(olMail.SenderEmailAddress, ws.Cells(iCounter, 5).Value) > 0 Then 'qualify the cell
'With ws
' lrow = .range("A" & .Rows.count).End(xlUp).Row
' .range("C" & lrow + 1).Value = olMail.body
' .range("B" & lrow + 1).Value = olMail.ReceivedTime
' .range("A" & lrow + 1).Value = olMail.SenderEmailAddress
'End With
'End If
'Next iCounter
End If
Next i
If (oParent.Folders.Count > 0) Then
For Each olFolder In oParent.Folders
ProcessFolder olFolder
Next
End If
End Sub
For more information, Please refer to the below link:
VBA code to loop through every folder and subfolder in Outlook