I am trying find e-mail that matches body text and sender.
Each day I check if 300/400 emails were already sent.
I need to iterate through more than 4500 emails.
Sub Check()
Application.Calculation = xlManual
Dim OutApp As Object
Dim OutNameSpace As Object
Dim OutFolder As Object
Dim OutItms As Object
Dim OutMail As Object
Dim Last As Long
Last = ThisWorkbook.Worksheets(2).Cells(Rows.Count, 2).End(xlUp).Row
Set OutApp = CreateObject("Outlook.Application")
Set OutNameSpace = OutApp.GetNamespace("MAPI")
Set OutFolder = OutNameSpace.GetDefaultFolder(6).Folders("Inne")
Set OutItms = OutFolder.Items
Set numbers = ThisWorkbook().Sheets(2).Range(Cells(2, 2), Cells(Last, 2))
Dim numer As Range
For Each number In numbers
Z = 1
If numer = "" Then GoTo nastepny
For Each OutMail In OutFolder.Items
If InStr(1, OutMail.Body, number, vbTextCompare) <> 0 Then
If InStr(1, OutMail.Sender, "Sender Name", vbTextCompare) <> 0 Then
number.Offset(0, 7) = "Yes"
GoTo nastepny
End If
Else
number.Offset(0, 7) = "No"
End If
nastepny:
Next OutMail, number
Application.Calculation = xlAutomatic
End Sub
This code runs through all e-mails and checks if there is e-mail with correct number in body and correct sender. For more then 4500 e-mails it takes a lot of time to do it one by one.
With Restrict determine whether any item contains applicable text.
https://learn.microsoft.com/en-us/office/client-developer/outlook/pia/how-to-search-for-a-phrase-in-the-body-of-items-in-a-folder
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
' If desperate declare as Variant
Sub Check()
Application.Calculation = xlManual
' Late binding.
' Reference to Microsoft Outlook XX.X Object Library not required.
Dim OutApp As Object
Dim OutNameSpace As Object
Dim OutFolder As Object
Dim OutItms As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutNameSpace = OutApp.GetNamespace("MAPI")
' Assumptions:
' 1 - Inne is the sender
' 2 - Applicable items from Inne in subfolder Inne
Set OutFolder = OutNameSpace.GetDefaultFolder(6).Folders("Inne")
Set OutItms = OutFolder.Items
Debug.Print " OutItms.Count.....: " & OutItms.Count
Dim wB As Workbook
Set wB = ThisWorkbook
Dim wS As Worksheet
Set wS = wB.Worksheets(2)
Dim Last As Long
Dim numbers As Range
With wS
'Entries in column 2
Last = .Cells(.Rows.Count, 2).End(xlUp).Row
Set numbers = .Range(.Cells(2, 2), .Cells(Last, 2))
End With
Dim numBer As Range
For Each numBer In numbers
If numBer <> "" Then
Dim strFilter As String
' https://learn.microsoft.com/en-us/office/client-developer/outlook/pia/how-to-search-for-a-phrase-in-the-body-of-items-in-a-folder
strFilter = "#SQL=" & Chr(34) & "urn:schemas:httpmail:textdescription" & Chr(34) & " like '%" & numBer & "%'"
Debug.Print strFilter
Dim numBerResults As Object
Set numBerResults = OutFolder.Items.Restrict(strFilter)
Debug.Print " numBerResults.Count.....: " & numBerResults.Count
If numBerResults.Count > 0 Then
numBer.Offset(0, 7) = "Yes"
Else
numBer.Offset(0, 7) = "No"
End If
End If
Next numBer
Application.Calculation = xlAutomatic
Debug.Print "Done."
End Sub
Related
I have the following code and keep having the error "application-defined or object-defined error" and cannot understand why. The tool Microsoft Office 16.0 Object library is activated, I am confident that the error is liked with the line Set outlookMail = outlookApp.CreateItem(0). For sure I am missing something in the connection with outlook.
Sub send_emails()
Dim outlookApp As Object
Dim outlookMail As Object
Dim cell As Range
Dim lastRow As Long
' Create Outlook object
Set outlookApp = CreateObject("Outlook.Application")
' Determine the last row in the worksheet
lastRow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row
' Loop through each cell in column D
For Each cell In Range("D2:D" & lastRow)
' Check if the date in the cell is 15 days from today
If cell.Value = Date + 15 Then
' Retrieve the corresponding email address, name, and surname
Email = cell.Offset(0, 2).Value
Name = cell.Offset(0, 1).Value
surname = cell.Offset(0, -1).Value
' Create a new email
Set outlookMail = outlookApp.CreateItem(0)
' Set the recipient, subject, and body of the email
outlookMail.To = Email
outlookMail.Subject = "Reminder"
outlookMail.Body = "Dear " & Name & " " & surname & ", this is a reminder that your event is coming up in 15 days. Please make sure to prepare accordingly."
' Set the sender and send the email
outlookMail.SendUsingAccount = outlookApp.Session.Accounts.Item("YOUR EMAIL ADDRESS")
outlookMail.Send
' If the email was sent successfully, color the cell in column E green
cell.Offset(0, 1).Interior.Color = vbGreen
End If
Next cell
' Clean up
Set outlookMail = Nothing
Set outlookApp = Nothing
End Sub
The tool Microsoft Office 16.0 Object library is activated
I suppose you have added a reference to the Outlook object model (a COM reference) in Excel VBA environment. In the code I see that the late-binding technology is used:
Dim outlookApp As Object
Dim outlookMail As Object
' Create Outlook object
Set outlookApp = CreateObject("Outlook.Application")
But at the same time you added a COM object reference for using the early-binding in the code. So, I'd suggest using the New operator and declare all Outlook objects in the code with specific types instead:
Dim outlookApp As Outlook.Application
Dim outlookMail As Outlook.MailItem
Set outlookApp = New Outlook.Application()
You can read more about early and late binding technologies in the Using early binding and late binding in Automation article.
Send Emails From Excel
Option Explicit
Private Enum eCols
ecSurName = 1 ' C
ecDate = 2 ' D
ecName = 3 ' E
ecEmail = 4 ' F
End Enum
Sub SendEmails()
Const MY_EMAIL As String = "YOUR EMAIL ADDRESS"
On Error GoTo ClearError
' Reference the worksheet.
If ActiveSheet Is Nothing Then Exit Sub ' no visible workbooks open
If Not TypeOf ActiveSheet Is Worksheet Then Exit Sub ' not a worksheet
Dim ws As Worksheet: Set ws = ActiveSheet
' Reference the range.
Dim LastRow As Long: LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
If LastRow < 2 Then Exit Sub ' no data
Dim rg As Range: Set rg = ws.Range("C2", ws.Cells(LastRow, "F"))
' Write the values from the range to an array.
Dim Data(): Data = rg.Value
' Write the matching rows to a collection.
Dim coll As Collection: Set coll = New Collection
Dim r As Long, rDate As Variant
For r = 1 To UBound(Data, 1)
rDate = Data(r, eCols.ecDate)
If IsDate(rDate) Then
If rDate = Date + 15 Then coll.Add r
End If
Next r
If coll.Count = 0 Then Exit Sub ' no matches
' Send the emails.
Dim olApp As Object: Set olApp = CreateObject("Outlook.Application")
Dim crg As Range, rItem, ErrNum As Long, emCount As Long
Dim olMail As Object, mEmail As String, mName As String, mSurName As String
For Each rItem In coll
mEmail = Data(rItem, eCols.ecEmail)
mName = Data(rItem, eCols.ecName)
mSurName = Data(rItem, eCols.ecSurName)
Set olMail = olApp.CreateItem(0)
With olMail
.To = mEmail
.Subject = "Reminder"
.Body = "Dear " & mName & " " & mSurName _
& ", this is a reminder that your event is coming up " _
& "in 15 days. Please make sure to prepare accordingly."
.SendUsingAccount = olApp.Session.Accounts.Item(MY_EMAIL)
On Error Resume Next ' suppress send error e.g. if invalid email
olMail.Send
ErrNum = Err.Number
On Error GoTo ClearError
End With
' Count and combine cells to be highlighted.
If ErrNum = 0 Then
emCount = emCount + 1
If crg Is Nothing Then
Set crg = rg.Cells(rItem, eCols.ecName)
Else
Set crg = Union(crg, rg.Cells(rItem, eCols.ecName))
End If
End If
Next rItem
ProcExit:
On Error Resume Next
' Highlight cells.
If Not crg Is Nothing Then crg.Interior.Color = vbGreen
' Clean up.
If Not olMail Is Nothing Then Set olMail = Nothing
If Not olApp Is Nothing Then Set olApp = Nothing
' Inform.
MsgBox IIf(emCount = 0, "No", emCount) & " email" _
& IIf(emCount = 1, "", "s") & " sent.", _
IIf(emCount = 0, vbExclamation, vbInformation)
On Error GoTo 0
Exit Sub
ClearError:
Debug.Print "Run-time error '" & Err.Number & "':" & Err.Description
Resume ProcExit
End Sub
I want to export e-mail data from a specific folder by a range of dates.
The macro exports the received date and the body of the email.
The objective is to search for certain data that comes from the extracted body and show them in other rows.
Due to the 32767 character limit that Excel has in a cell, the bodies of some emails are not being fully exported.
Is there a way to export the body in two rows instead of one to avoid the Excel limitation?
Other suggestions to accomplish this process are appreciated.
Sub ImportEmails()
Dim OutlookApp As Outlook.Application
Dim OutlookNamespace As Outlook.Namespace
Dim IFolder As Outlook.MAPIFolder
Dim OutlookMail As Variant
Dim i As Integer
Dim wb As Workbook
Dim ws As Worksheet
Dim rng As Range
Set OutlookApp = New Outlook.Application
'Outlook connection
Set OutlookNamespace = OutlookApp.GetNamespace("MAPI")
Set wb = ThisWorkbook
'Select the folder to export emails, depending on the userĀ“s folder name you must change it
Set IFolder = OutlookNamespace.GetDefaultFolder(olFolderInbox).Folders("Test")
Set ws = wb.Sheets("Imported")
i = 0
Application.ScreenUpdating = False
ws.Cells.Clear
'Create headers
ws.Range("A1").Value = "Date Time"
ws.Range("B1").Value = "Body"
'Condition to select the today date in case of blank and export the emails
If IsEmpty(Range("end_date").Value) = True Then
Range("end_date").Value = "=today()"
End If
'Exporting proccedure
For Each OutlookMail In IFolder.Items
'Date validation
If DateValue(OutlookMail.ReceivedTime) >= DateValue(Range("start_date")) And DateValue(OutlookMail.ReceivedTime) <= DateValue(Range("end_date")) Then
'Fill the worksheet cells with the emails
ws.Range("A2").Offset(i, 0).Value = OutlookMail.ReceivedTime
ws.Range("B2").Offset(i, 0).Value = OutlookMail.Body
i = i + 1
End If
Next OutlookMail
Application.ScreenUpdating = True
Set IFolder = Nothing
Set OutlookNamespace = Nothing
Set OutlookApp = Nothing
LRimpr = LastRow(ws)
Set rng = ws.Range("A2:B" & LRimpr)
'Sort the columns by newest to oldest using the worksheet last row
With rng
.Sort Key1:=.Cells(1), Order1:=xlDescending, _
Orientation:=xlTopToBottom, Header:=xlNo
End With
MsgBox "Emails are successfully imported", vbInformation, "Import complete"
ws.Activate
End Sub
If you would be happy exporting the email body in multiple cells in a single row then replace your line
ws.Range("B2").Offset(i, 0).Value = OutlookMail.Body
with
Const CHUNK_SIZE As Long = 32000
Dim segment As Long
segment = 0
Do While True
ws.Range("B2").Offset(i, segment).Value = Mid$(OutlookMail.Body, segment * CHUNK_SIZE + 1, CHUNK_SIZE)
segment = segment + 1
If segment * CHUNK_SIZE > Len(OutlookMail.Body) Then Exit Do
Loop
Adjust the value for CHUNK_SIZE to your requirements ... it controls the number of characters that will be put into each cell, with the last cell having the 'remaining' characters (or all the characters if the body has less characters than CHUNK_SIZE)
To split the body into cells in a column.
Option Explicit
Sub ImportEmails_SplitBody_MultipleRows()
' Reference Microsoft Outlook nn.n Object Library
Dim OutlookApp As Outlook.Application
Dim iFolder As Outlook.Folder
Dim iFolderItems As Outlook.Items
Dim j As Long
Dim OutlookItem As Object
Dim lenBody As Long
Dim maxLen As Long
Dim i As Long
Dim wb As Workbook
Dim ws As Worksheet
Dim rng As Range
Set OutlookApp = New Outlook.Application
' Select folder
Set iFolder = Session.GetDefaultFolder(olFolderInbox).Folders("Test")
' Sort items
Set iFolderItems = iFolder.Items
iFolderItems.Sort "[ReceivedTime]", True
Set wb = ThisWorkbook
Set ws = wb.Sheets("Imported")
i = 0
' Application is Excel. No impact on Outlook
'Application.ScreenUpdating = False
ws.Cells.Clear
'Create headers
ws.Range("A1").Value = "Date Time"
ws.Range("B1").Value = "Body"
'Condition to select today's date in case of blank
If IsEmpty(Range("end_date").Value) = True Then
Range("end_date").Value = "=today()"
End If
'Debug.Print Range("start_date")
'Debug.Print Range("end_date")
'Exporting procedure
maxLen = 32767
'Debug.Print " maxLen: " & maxLen
For j = 1 To iFolderItems.Count
'Date validation
If iFolderItems(j).Class = olMail Then
Set OutlookItem = iFolderItems(j)
'Debug.Print OutlookItem.Subject
If DateValue(OutlookItem.ReceivedTime) >= DateValue(Range("start_date")) And _
DateValue(OutlookItem.ReceivedTime) <= DateValue(Range("end_date")) Then
lenBody = Len(OutlookItem.Body)
Dim txt As String
txt = OutlookItem.Body
Dim lenTxt As Long
lenTxt = Len(txt)
Do Until lenTxt = 0
'Fill the worksheet cells with the emails
'Debug.Print " Len(txt): " & Len(txt)
If lenTxt > maxLen Then
ws.Range("A2").Offset(i, 0).Value = OutlookItem.ReceivedTime
ws.Range("B2").Offset(i, 0).Value = Left(txt, maxLen)
txt = Right(txt, Len(txt) - maxLen)
Else
ws.Range("A2").Offset(i, 0).Value = OutlookItem.ReceivedTime
ws.Range("B2").Offset(i, 0).Value = txt
txt = ""
End If
i = i + 1
lenTxt = Len(txt)
Loop
Set OutlookItem = Nothing
End If
End If
Next
Application.ScreenUpdating = True
Set iFolder = Nothing
Set iFolderItems = Nothing
Set OutlookApp = Nothing
MsgBox "Emails are successfully imported", vbInformation, "Import complete"
ws.Activate
End Sub
I'm currently working on a vba excel macro that filters particular rows (based on values in one column), then copies particular columns from the filtered rows & paste them as a table into the outlook email body.
I'd like the table to be pasted after the text in the email body. However, it seems that the table is the only thing that is in the mail body & I can't put the text before the table.
Would much appreciate your advice on how to display the text in the email body before the pasted table. My current: "OutMail.Body = "The body text I want to put before the table" does not work.
EDIT 1 = adjusted according to CDP1802 + added moving rows to archive feature
Code:
Option Explicit Public ws As Worksheet
Public ol As ListObject
Public olRng As Range
Sub CopyTableToEmail()
Dim olCol As Integer, datCol As Integer
Set ws = Sheets("Test1")
Set ol = ws.ListObjects("TbClient")
Set olRng = ol.Range
'remove table filters
ol.ShowAutoFilter = False
'get Valid column
olCol = ol.ListColumns("Valid").Index
'filter table
ol.Range.AutoFilter field:=olCol, Criteria1:="<0", Operator:=xlOr
'select table to copy
Set olRng = ol.Range
'create mail
Call CreateMail
'Change values on Deactivation e-mail sent column
datCol = ol.ListColumns("Deactivation e-mail sent").Index
ol.ListColumns(datCol).DataBodyRange.SpecialCells(xlCellTypeVisible).Value = Range("H1")
'clear table filters
ol.AutoFilter.ShowAllData
'Move rows to the Archive
Call MoveRows
End Sub
Sub CreateMail()
On Error GoTo errHandler
Dim olCol As Integer, rCell As Range, addRng As Range
Dim mailBcc As String, mailCC As String
'Outlook
Dim OutApp As Object, OutInsp As Object, OutMail As Object
'Declare Word Variables
Dim oWrdDoc As Word.Document, oWdEditor As Word.Editors
Dim sText As String
'Range of mail adresses
olCol = ol.ListColumns("Requestor (email)").Index
Set addRng = ol.ListColumns(olCol).DataBodyRange.SpecialCells(xlCellTypeVisible)
'get the mail addresses
For Each rCell In addRng
mailBcc = mailBcc & rCell.Value & ";"
mailCC = mailCC & rCell.Offset(0, 1).Value & ";"
Next rCell
' copy table colmns B,J,L
ws.Columns.Hidden = False
ws.Range("A:A,C:I,K:K,M:Z").EntireColumn.Hidden = True
olRng.Copy
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
Dim signature As String
With OutMail
.display ' or send
signature = .body
.cc = mailCC
.Bcc = mailBcc
.Subject = "Openings Tracker"
End With
' Text
sText = "Ladies and gentlemen," & vbCrLf & vbCrLf
'Get the Active Inspector
'Get the document within the inspector
Set OutInsp = OutMail.GetInspector
Set oWrdDoc = OutInsp.WordEditor
With oWrdDoc
.Content.Delete
.Paragraphs.Add.Range.Text = sText
.Paragraphs.Add.Range.Paste
.Paragraphs.Add.Range.Text = signature
End With
ws.Columns.Hidden = False
Application.CutCopyMode = False
exitRoutine:
'clear
Set OutMail = Nothing
Set OutApp = Nothing
Set ws = Nothing
Exit Sub
errHandler:
'Open immediate window to see the error
Debug.Print Err.Number, Err.Description
Resume exitRoutine
End Sub
Sub MoveRows()
Dim xRg As Range
Dim xCell As Range
Dim A As Long
Dim B As Long
Dim O As Long
A = Worksheets("Test1").UsedRange.Rows.Count
B = Worksheets("Archive").UsedRange.Rows.Count
If B = 1 Then
If Application.WorksheetFunction.CountA(Worksheets("Archive").UsedRange) = 0 Then B = 0
End If
Set xRg = Worksheets("Test1").Range("O1:O" & A)
On Error Resume Next
Application.ScreenUpdating = False
For O = 1 To xRg.Count
If CStr(xRg(O).Value) = "OK" Then
xRg(O).EntireRow.Copy Destination:=Worksheets("Archive").Range("A" & B + 1)
xRg(O).EntireRow.Delete
If CStr(xRg(O).Value) = "OK" Then
O = O - 1
End If
B = B + 1
End If
Next
Application.ScreenUpdating = True
End Sub
Add a paragraph to the word document.
update1 - Filter table, add signature to the end.
update2 - Show only columns B J L
update3 - Added AchiveRows()
Option Explicit
Public ws As Worksheet
Public ol As ListObject
Public olRng As Range
Sub CopyTableToEmail()
Dim olCol As Integer, datCol As Integer
Set ws = Sheets("Test1")
Set ol = ws.ListObjects("tbClient")
Set olRng = ol.Range
'remove table filters
ol.ShowAutoFilter = False
'get Valid column
olCol = ol.ListColumns("Valid").Index
'filter table
ol.Range.AutoFilter field:=olCol, Criteria1:="<0", Operator:=xlOr
'select table to copy
Set olRng = ol.Range
'create mail
Call CreateMail
'clear table filters
ol.AutoFilter.ShowAllData
End Sub
Sub CreateMail()
On Error GoTo errHandler
Dim olCol As Integer, rCell As Range, addRng As Range
Dim mailBcc As String, mailCC As String
' Outlook
Dim OutApp As Object, OutInsp As Object, OutMail As Object
'Declare Word Variables
Dim oWrdDoc As Word.Document, oWdEditor As Word.Editors
Dim sText As String
'Range of mail adresses
olCol = ol.ListColumns("Requestor email").Index
Set addRng = ol.ListColumns(olCol).DataBodyRange.SpecialCells(xlCellTypeVisible)
'get the mail addresses
For Each rCell In addRng
mailBcc = mailBcc & rCell.Value & ";"
mailCC = mailCC & rCell.Offset(0, 1).Value & ";"
Next rCell
' copy table colmns B,J,L
ws.Columns.Hidden = False
ws.Range("A:A,C:I,K:K,M:Z").EntireColumn.Hidden = True
olRng.Copy
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
Dim signature As String
With OutMail
.display ' or send
signature = .body
.cc = mailCC
.Bcc = mailBcc
.Subject = "Generic Subject"
End With
' Text
sText = "The body text I want to put before the table" & vbCrLf & vbCrLf
'Get the Active Inspector
'Get the document within the inspector
Set OutInsp = OutMail.GetInspector
Set oWrdDoc = OutInsp.WordEditor
With oWrdDoc
.Content.Delete
.Paragraphs.Add.Range.Text = sText
.Paragraphs.Add.Range.Paste
.Paragraphs.Add.Range.Text = signature
End With
ws.Columns.Hidden = False
Application.CutCopyMode = False
exitRoutine:
'clear
Set OutMail = Nothing
Set OutApp = Nothing
Set ws = Nothing
Exit Sub
errHandler:
'Open immediate window to see the error
Debug.Print Err.Number, Err.Description
Resume exitRoutine
End Sub
Sub ArchiveRows()
Dim ol As ListObject, rng As Range
Dim r As Long, olCol As Long, n As Long
Set ol = Sheets("Test1").ListObjects("tbClient")
olCol = ol.ListColumns("Valid").Index
With ol.DataBodyRange
For r = 1 To .Rows.Count
If UCase(Trim(.Cells(r, olCol).Value)) = "OK" Then
If rng Is Nothing Then
Set rng = .Rows(r)
Else
Set rng = Union(rng, .Rows(r))
End If
End If
Next
End With
If rng Is Nothing Then
n = 0
Else
n = rng.Rows.Count
With Sheets("Archive")
rng.Copy
With .Cells(.Rows.Count, 1).End(xlUp).Offset(1)
.PasteSpecial xlPasteValues
End With
End With
rng.Rows.Delete
Application.CutCopyMode = False
End If
MsgBox n & " rows moved to Archive and deleted"
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 have a workbook where I am building an automated e-mail but I want that e-mail to contain data that is stored in a second workbook. Please see my code below, I did change some variable names/data just for confidentiality so hopefully that doesn't make it too difficult to read.
Option Explicit
Sub Button1_Click()
Dim objExcel As Object
Dim wb1 As Workbook
Dim ws1 as Worksheet
Set objExcel = CreateObject("Excel.Application")
Set wb1 = objExcel.Workbooks.Open(ThisWorkbook.Path & "\wb1.xls")
Set ws1 = wbStoreList.Worksheets("Sheet1")
Dim filePaths As Variant
Dim msg As String
Dim i As Integer
Dim objApp As Object
Dim objMail As Object
Dim fileName As String
Dim emailAddress As String
Dim subject As String
Dim name As String
Dim otherName As String
Dim rowNumber As Range
Set objApp = CreateObject("Outlook.Application")
filePaths = Application.GetOpenFilename(MultiSelect:=True)
If (IsArray(filePaths)) Then
For i = LBound(filePaths) To UBound(filePaths)
Set objMail = objApp.CreateItem(olMailItem)
fileName = Dir(filePaths(i))
If (Len(fileName) = 8) Then
emailAddress = "email" & Mid(fileName, 1, 3) & "#emailaddress.ca"
ElseIf (Len(fileName) = 9) Then
emailAddress = "email" & Mid(fileName, 1, 4) & "#emailaddress.ca"
End If
subject = "Confidential"
With ws1
'On Error Resume Next
Set rowNumber = .Range(.Cells(8, 1), .Cells(8, 10000)).Find(What:="311", LookIn:=xlValues).Row
End With
MsgBox rowNumber
dataFound:
objMail.Recipients.Add emailAddress
objMail.subject = subject
objMail.Attachments.Add filePaths(i)
objMail.Body = name & ", " & "(" & otherName & ")" & vbNewLine & vbNewLine & "Please see attached file."
objMail.Display
Next i
Else
MsgBox "No files were selected"
End If
End Sub
The error is on the line with:
Set rowNumber = .Range(.Cells(8, 1), .Cells(8, 10000)).Find(What:="311", LookIn:=xlValues).Row
Not sure if you can directly get the row number like that because rowNumber is a Range (according to your dim statement). Give it a try and break it down into two lines:
Set rowNumber = .Range(.Cells(1, 8), .Cells(10000, 8)).Find(What:="311", LookIn:=xlValues)
and then
If Not rowNumber is Nothing then lngNumber = rowNumber.Row
Note that I am using a new variable which should be of type long.
Dim lngRowNumber as Long
By the way: in your case Integer would actually suffice over Long.