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
Related
This code runs on my friend's Excel.
On mine it throws an error on the line Range("C" & i).Value = olMail.To.
This is the code.
Sub Trial()
Dim olApp As Outlook.Application
Dim olNS As Namespace
Dim Fldr As MAPIFolder
Dim olMail As Object
Dim i As Integer, j As Integer
Set olApp = New Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")
Set Fldr = olNS.GetDefaultFolder(olFolderInbox)
Sheets("Sheet1").Select
i = [Counta(Sheet1!A:A)]
Dim lastMail As String
If i = 1 Then
lastMail = 0
Else
lastMail = Range("B" & i).Value
End If
For Each olMail In Fldr.Items
If olMail.UnRead = True Then
i = i + 1
Range("C" & i).Value = olMail.To
If Range("C" & i).Value Like "*MailID comes here*" Then
Range("A" & i).Value = olMail.Subject
Range("B" & i).Value = olMail.SentOn
Range("D" & i).Value = olMail.CC
Range("E" & i).Value = olMail.Body
olMail.UnRead = False
Call Macro1(i)
Else
Range("C" & i).Select
Selection.ClearContents
i = i - 1
End If
End If
Next olMail
ActiveWorkbook.Save
Set olApp = Nothing
Set olNS = Nothing
Set Fldr = Nothing
End Sub
i think you miss handle to workbook, if wasnt active return error. try this code I add handle to workbook and worksheet
Sub Trial()
Dim olApp As Outlook.Application
Dim olNS As Namespace
Dim Fldr As MAPIFolder
Dim olMail As Object
Dim i As Integer, j As Integer
dim wb as workbook
dim ws as worksheet
Set olApp = New Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")
Set Fldr = olNS.GetDefaultFolder(olFolderInbox)
set wb= thisworkbook
set ws = wb.worksheets("Sheet1")
i = ws.cells(rows.count,1).end(xlup).row
Dim lastMail As String
If i = 1 Then
lastMail = 0
Else
lastMail = ws.Range("B" & i).Value
End If
For Each olMail In Fldr.Items
If olMail.UnRead = True Then
i = i + 1
ws.Range("C" & i).Value = olMail.To
If ws.Range("C" & i).Value Like "*MailID comes here*" Then
ws.Range("A" & i).Value = olMail.Subject
ws.Range("B" & i).Value = olMail.SentOn
ws.Range("D" & i).Value = olMail.CC
ws.Range("E" & i).Value = olMail.Body
olMail.UnRead = False
Call Macro1(i)
Else
ws.Range("C" & i).ClearContents
i = i - 1
End If
End If
Next olMail
wb.Save
Set olApp = Nothing
Set olNS = Nothing
Set Fldr = Nothing
set wb = nothing
set ws = nothing
End Sub
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
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
I want to export mails from a shared mailbox into Excel.
Here is a code which is exporting mails from my default mailbox.
Sub ExportEmailsfromSpecificSender()
Dim objOutlook As Object
Dim objnSpace As Object
Dim objFolder As MAPIFolder
Dim objSubFolder As MAPIFolder
Dim objSubSubFolder As MAPIFolder
Dim EmailCount As Integer
' Dim dateStr As String
Dim myItems As Outlook.Items
Dim myFilterItems As Outlook.Items
' Dim dict As Object
' Dim msg As String
Dim excApp As Object
Dim excWkb As Object
Dim excWks As Object
' Dim intVersion As Integer
' Dim intMessages As Integer
Dim lngRow As Long
Dim strFilename As String
Dim objCategory As Category
Dim strFilter As String
Dim objEmails, objSpecificEmails As Outlook.Items
Dim objItem As Object
Dim strSpecificSender As String
Dim nRow As Integer
Dim strFilePath As String
Set objOutlook = CreateObject("Outlook.Application")
Set objnSpace = objOutlook.GetNamespace("MAPI")
Set excApp = CreateObject("Excel.Application")
Set excWkb = excApp.Workbooks.Add
On Error Resume Next
'Get the emails from a specific sender
'Set Items = GetFolderPath("PD Services\RetainPermanently\07 July 2018\").Items
Set objEmails = Application.Session.GetDefaultFolder(olFolderInbox).Items
strSpecificSender = InputBox("Input the name of the specific sender:", "Specify Sender")
strFilter = "[From] = '" & strSpecificSender & "'"
Set objSpecificEmails = objEmails.Restrict(strFilter)
Set objExcelApplication = CreateObject("Excel.Application")
Set objExcelWorkbook = objExcelApplication.Workbooks.Add
'Export the specific emails to worksheet
Set objExcelWorksheet = objExcelWorkbook.Worksheets(1)
With objExcelWorksheet
.Cells(1, 1) = "Subject"
.Cells(1, 2) = "Received"
.Cells(1, 3) = "Body"
End With
nRow = 2
For Each objItem In objSpecificEmails
With objExcelWorksheet
.Name = "From " & strSpecificSender
.Cells(nRow, 1) = objItem.Subject
.Cells(nRow, 2) = objItem.ReceivedTime
.Cells(nRow, 3) = objItem.Body
End With
nRow = nRow + 1
Next
objExcelWorksheet.Columns("A:E").AutoFit
'Save the Excel workbook
strFilePath = "H:\WINDOWS\system\Mitushi Documents " & strSpecificSender & ".xlsx"
objExcelWorkbook.Close True, strFilePath
'Notify you of the export complete
MsgBox ("Export Complete!")
End Sub
I am receiving a blank Excel file with only the column headers.
What should I modify here to get the emails from a shared mailbox called "PD Services" and a folder named "RetainPermanently"?
I'm not sure what a 'shared folder' is, but try the script below and see if you get the results you want.
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
This is a follow up from a previous question (VBA to save attachments (based on defined criteria) from an email with multiple accounts)
Scenario: I have a code that loops through all e-mails in a certain outlook account, and saves the attachments to a selected folder. Previously, my problem was selecting which folder (and account) from where to extract the attachments (this was solved with a suggestion from the previous question).
Issue 1: The code is presenting a "Type Mismatch" error at the line:
Set olMailItem = olFolder.Items(i)
Issue 2: As stated in the question title, my main objective is to loop through all the attachments and save only those that have a given criteria (excel file, with one sheet name "ASK" and one named "BID"). More than a simple If to account for these criteria, I have to either download all files to "temp folder", to the selection and put the final resulting files in the output folder, or download everything to the final folder and delete the files that do not meet the criteria.
Problem: I can't seem to find the way to do either of those operations.
Question: How would one do that? And which of those two would be more efficient?
Code:
Sub email()
Application.ScreenUpdating = False
Dim olApp As New Outlook.Application
Dim olNameSpace As Object
Dim olMailItem As Outlook.MailItem
Dim olFolder As Object
Dim olFolderName As String
Dim olAtt As Outlook.Attachments
Dim strName As String
Dim sPath As String
Dim i As Long
Dim j As Integer
Dim olSubject As String
Dim olSender As String
Dim sh As Worksheet
Dim LastRow As Integer
'delete content except from row 1
ThisWorkbook.Worksheets("FileNames").Rows(2 & ":" & ThisWorkbook.Worksheets("FileNames").Rows.count).Delete
'set foldername and subject
olFolderName = ThisWorkbook.Worksheets("Control").Range("D10")
'olSubject = ThisWorkbook.Worksheets("Control").Range("D16")
olSender = ThisWorkbook.Worksheets("Control").Range("D16")
sPath = Application.FileDialog(msoFileDialogFolderPicker).Show
sPathstr = Application.FileDialog(msoFileDialogFolderPicker).SelectedItems(1)
Set olNameSpace = olApp.GetNamespace("MAPI")
'check if folder is subfolder or not and choose olFolder accordingly
'Set olFolder = olNameSpace.GetDefaultFolder(olFolderInbox).Folders(olFolderName)
Set olFolder = olNameSpace.Folders("email#email.com").Folders("Inbox")
If (olFolder = "") Then
Set olFolder = olNameSpace.Folders("email#email.com").Folders("Inbox")
End If
'loop through mails
h = 2
For i = 1 To olFolder.Items.count
Set olMailItem = olFolder.Items(i)
'check if the search name is in the email subject
'If (InStr(1, olMailItem.Subject, olSubject, vbTextCompare) <> 0) Then
If (InStr(1, olMailItem.Sender, olSender, vbTextCompare) <> 0) Then
With olMailItem
strName = .Attachments.Item(j).DisplayName
'check if file already exists
If Not Dir(sPathstr & "\" & strName) = "" Then
.Attachments(j).SaveAsFile sPathstr & "\" & "(1)" & strName
ThisWorkbook.Worksheets("FileNames").Range("A" & h) = "(1)" & strName
Else
.Attachments(j).SaveAsFile sPathstr & "\" & strName
ThisWorkbook.Worksheets("FileNames").Range("A" & h) = strName
End If
h = h + 1
Next
End With
End If
Next
Application.ScreenUpdating = True
MsgBox "Download complete!", vbInformation + vbOKOnly, "Done"
End Sub
Issue 1 :
You probably have so meeting invites or something other than a regular mail in your folder.
Check the Class property of the Item to see if it's olMail
Issue 2 :
I'll go with error handling, here :
Save in temp folder with the appropriate name
Open the file
Try to get to the sheets
If there is an error, just close the file
If there is no error, save the file in destination folder
Full code :
Sub email_DGMS89()
Application.ScreenUpdating = False
Dim olApp As New Outlook.Application
Dim olNameSpace As Object
Dim olMailItem As Outlook.MailItem
Dim olFolder As Object
Dim olFolderName As String
Dim olAtt As Outlook.Attachments
Dim strName As String
Dim sPath As String
Dim i As Long
Dim j As Integer
Dim olSubject As String
Dim olSender As String
Dim sh As Worksheet
Dim LastRow As Integer
Dim TempFolder As String: TempFolder = VBA.Environ$("TEMP")
Dim wB As Excel.Workbook
'delete content except from row 1
ThisWorkbook.Worksheets("FileNames").Rows(2 & ":" & ThisWorkbook.Worksheets("FileNames").Rows.Count).Delete
'set foldername and subject
olFolderName = ThisWorkbook.Worksheets("Control").Range("D10")
'olSubject = ThisWorkbook.Worksheets("Control").Range("D16")
olSender = ThisWorkbook.Worksheets("Control").Range("D16")
sPath = Application.FileDialog(msoFileDialogFolderPicker).Show
sPathstr = Application.FileDialog(msoFileDialogFolderPicker).SelectedItems(1)
Set olNameSpace = olApp.GetNamespace("MAPI")
'check if folder is subfolder or not and choose olFolder accordingly
'Set olFolder = olNameSpace.GetDefaultFolder(olFolderInbox).Folders(olFolderName)
Set olFolder = olNameSpace.Folders("email#email.com").Folders("Inbox")
If (olFolder = "") Then
Set olFolder = olNameSpace.Folders("email#email.com").Folders("Inbox")
End If
'loop through mails
h = 2
For i = 1 To olFolder.items.Count
'''Const olMail = 43 (&H2B)
If olFolder.items(i).Class <> olMail Then
Else
Set olMailItem = olFolder.items(i)
'check if the search name is in the email subject
'If (InStr(1, olMailItem.Subject, olSubject, vbTextCompare) <> 0) Then
If (InStr(1, olMailItem.Sender, olSender, vbTextCompare) <> 0) Then
With olMailItem
For j = 1 To .Attachments.Count
strName = .Attachments.Item(j).DisplayName
'check if file already exists
If Not Dir(sPathstr & "\" & strName) = vbNullString Then
strName = "(1)" & strName
Else
End If
'''Save in temp
.Attachments(j).SaveAsFile TempFolder & "\" & strName
ThisWorkbook.Worksheets("FileNames").Range("A" & h) = strName
'''Open file as read only
Set wB = workbooks.Open(TempFolder & "\" & strName, True)
DoEvents
'''Start error handling
On Error Resume Next
Set sh = wB.sheets("ASK")
Set sh = wB.sheets("BID")
If Err.Number <> 0 Then
'''Error = At least one sheet is not detected
Else
'''No error = both sheets found
.Attachments(j).SaveAsFile sPathstr & "\" & strName
End If
Err.Clear
Set sh = Nothing
wB.Close
On Error GoTo 0
h = h + 1
Next j
End With
End If
End If
Next i
Application.ScreenUpdating = True
MsgBox "Download complete!", vbInformation + vbOKOnly, "Done"
End Sub