View Full Version : [SOLVED:] Retrieve data(Time, From, subject, category) from Outlook inbox to Execl
FrancisZheng
02-08-2017, 08:35 AM
Hello everybody,
I want to retrieve data from new mail received since the last execution of the macro. In this way I wouldn't need to retrieve all datas over and over again but just the new ones.
Personally I have no experience in VBA Outlook. So I was wondering if there is any good tutorial on this for Outlook beginers.
Thank you in advance.
Francis.
mancubus
02-09-2017, 10:30 AM
clears the existing list and creates a new list based on last execution date.
when running the macro for the first time make sure to insert a start date after which received emails will be listed.
see attached file.
you may clear the existing data and create a new list based on last execution date:
Sub vbax_58526_retrieve_email_info_after_specific_data_time_overwrite()
Dim i As Long
Dim it As Object
Dim lastexec As Date
lastexec = Worksheets("macro_log").Range("A2").Value
On Error Resume Next
Worksheets("mail_data").UsedRange.Offset(1).Clear
i = 2
With CreateObject("Outlook.Application").GetNamespace("MAPI").Folders("MyNameAtMyDomain.com").Folders("Inbox")
For Each it In .Items
If it.ReceivedTime > lastexec Then
Select Case TypeName(it)
Case Is = "MailItem"
With Worksheets("mail_data")
.Cells(i, 1).Value = it.SenderName
.Cells(i, 2).Value = Format(it.ReceivedTime, "mm/dd/yyyy hh:mm:ss")
.Cells(i, 3).Value = it.Subject
.Cells(i, 4).Value = it.Categories
End With
i = i + 1
End Select
End If
Next it
End With
With Worksheets("macro_log")
.Cells(.Rows.Count, 1).End(xlUp).Offset(1).Value = Now
.Cells(1).Sort Key1:=.Range("A2"), Order1:=xlDescending, Header:=xlYes
.Range("A2").NumberFormat = "mm/dd/yyyy hh:mm:ss"
End With
End Sub
or you may add to existing data based on last execution date:
Sub vbax_58526_retrieve_email_info_after_specific_data_time_add()
Dim i As Long
Dim it As Object
Dim lastexec As Date
lastexec = Worksheets("macro_log").Range("A2").Value
On Error Resume Next
i = Worksheets("mail_data").UsedRange.Offset(1).Row
With CreateObject("Outlook.Application").GetNamespace("MAPI").Folders("MyNameAtMyDomain.com").Folders("Inbox")
For Each it In .Items
If it.ReceivedTime > lastexec Then
Select Case TypeName(it)
Case Is = "MailItem"
With Worksheets("mail_data")
.Cells(i, 1).Value = it.SenderName
.Cells(i, 2).Value = Format(it.ReceivedTime, "mm/dd/yyyy hh:mm:ss")
.Cells(i, 3).Value = it.Subject
.Cells(i, 4).Value = it.Categories
End With
i = i + 1
End Select
End If
Next it
End With
With Worksheets("macro_log")
.Cells(.Rows.Count, 1).End(xlUp).Offset(1).Value = Now
.Cells(1).Sort Key1:=.Range("A2"), Order1:=xlDescending, Header:=xlYes
.Range("A2").NumberFormat = "mm/dd/yyyy hh:mm:ss"
End With
End Sub
FrancisZheng
02-10-2017, 03:50 AM
Hello Mancubus,
Thank you for your time and your code.
I ran it. The sheet macro_log works great. However, in the mail_data sheet, it's still empty after I executed. I adapted my email adress in the code :
...Folders("***@***.com").Folders("Inbox")...
Maybe I should also enter my mailbox name somewhere?
It's an interesting code and has potential to be working.
Regards,
Francis
mancubus
02-10-2017, 04:15 AM
you are welcome
type in the name of the Outlook parent folder of Inbox as displayed in the application. it may be different than email address.
gmayor
02-10-2017, 05:14 AM
I think I might be inclined to run the process from Outlook - maybe something like the following which will create a suitable workbook and write the data to it. It adds a category to the message as it is processed and only processes messages without the category. It has limitations, that may or may not be relevant, but it is faster than writing to an open workbook.
Option Explicit
Sub CopyToExcel()
Dim xlApp As Object
Dim xlWb As Object
Dim xlSheet As Object
Dim olFolder As Outlook.Folder
Dim olitem As Object
Dim strValues As String
Const strPath As String = "C:\Path\EMail_Log.xlsx" 'the path of the workbook
'The folder must exist or you will have to add code to create it.
If Not FileExists(strPath) Then
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Set xlApp = CreateObject("Excel.Application")
End If
On Error GoTo 0
'Open the workbook to input the data
Set xlWb = xlApp.workbooks.Add
Set xlSheet = xlWb.sheets("Sheet1")
xlSheet.Range("A1") = "Sender"
xlSheet.Range("B1") = "Received Time"
xlSheet.Range("C1") = "Subject"
xlWb.SaveAs strPath
xlWb.Close
xlApp.Quit
End If
Set olFolder = Session.PickFolder
For Each olitem In olFolder.Items
If TypeName(olitem) = "MailItem" Then
If Not olitem.Categories = "Logged" Then
strValues = ""
strValues = strValues & olitem.Sender.Name & "', '"
strValues = strValues & olitem.ReceivedTime & "', '"
strValues = strValues & Replace(olitem.Subject, "'", "")
WriteToWorksheet strPath, "Sheet1", strValues
olitem.Categories = "Logged"
olitem.Save
End If
End If
DoEvents
Next olitem
MsgBox "Processing Complete"
lbl_Exit:
Set xlApp = Nothing
Set xlWb = Nothing
Set xlSheet = Nothing
Set olitem = Nothing
Exit Sub
End Sub
Public Function WriteToWorksheet(strWorkbook As String, _
strRange As String, _
strValues As String)
Dim ConnectionString As String
Dim strSQL As String
Dim CN As Object
ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & strWorkbook & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=YES;"";"
strSQL = "INSERT INTO [" & strRange & "$] VALUES('" & strValues & "')"
Set CN = CreateObject("ADODB.Connection")
Call CN.Open(ConnectionString)
Call CN.Execute(strSQL, , 1 Or 128)
CN.Close
lbl_Exit:
Set CN = Nothing
Exit Function
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
FrancisZheng
02-10-2017, 05:46 AM
you are welcome
type in the name of the Outlook parent folder of Inbox as displayed in the application. it may be different than email address.
It worked perfectly except that the category column is still empty. Do you have an idea what might be the problem?
Regards,
Francis
mancubus
02-10-2017, 06:14 AM
when i first run the code, it didn't return the categories as well.
i checked it and saw that there were no categorized emails in my Inbox.
after assigning color categories to some emails it worked as expected.
so make sure there are categorized emails in your Inbox after specific date.
FrancisZheng
02-10-2017, 06:28 AM
when i first run the code, it didn't return the categories as well.
i checked it and saw that there were no categorized emails in my Inbox.
after assigning color categories to some emails it worked as expected.
so make sure there are categorized emails in your Inbox after specific date.
Yes, you are right. Thank you.
I found out that in the column A of macro_log, the dates are fixed on 02/02... even though their real values are different.
Do you also have this problem?
Francis
FrancisZheng
02-10-2017, 06:45 AM
I think I might be inclined to run the process from Outlook - maybe something like the following which will create a suitable workbook and write the data to it. It adds a category to the message as it is processed and only processes messages without the category. It has limitations, that may or may not be relevant, but it is faster than writing to an open workbook.
Option Explicit
Sub CopyToExcel()
Dim xlApp As Object
Dim xlWb As Object
Dim xlSheet As Object
Dim olFolder As Outlook.Folder
Dim olitem As Object
Dim strValues As String
Const strPath As String = "C:\Path\EMail_Log.xlsx" 'the path of the workbook
'The folder must exist or you will have to add code to create it.
If Not FileExists(strPath) Then
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Set xlApp = CreateObject("Excel.Application")
End If
On Error GoTo 0
'Open the workbook to input the data
Set xlWb = xlApp.workbooks.Add
Set xlSheet = xlWb.sheets("Sheet1")
xlSheet.Range("A1") = "Sender"
xlSheet.Range("B1") = "Received Time"
xlSheet.Range("C1") = "Subject"
xlWb.SaveAs strPath
xlWb.Close
xlApp.Quit
End If
Set olFolder = Session.PickFolder
For Each olitem In olFolder.Items
If TypeName(olitem) = "MailItem" Then
If Not olitem.Categories = "Logged" Then
strValues = ""
strValues = strValues & olitem.Sender.Name & "', '"
strValues = strValues & olitem.ReceivedTime & "', '"
strValues = strValues & Replace(olitem.Subject, "'", "")
WriteToWorksheet strPath, "Sheet1", strValues
olitem.Categories = "Logged"
olitem.Save
End If
End If
DoEvents
Next olitem
MsgBox "Processing Complete"
lbl_Exit:
Set xlApp = Nothing
Set xlWb = Nothing
Set xlSheet = Nothing
Set olitem = Nothing
Exit Sub
End Sub
Public Function WriteToWorksheet(strWorkbook As String, _
strRange As String, _
strValues As String)
Dim ConnectionString As String
Dim strSQL As String
Dim CN As Object
ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & strWorkbook & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=YES;"";"
strSQL = "INSERT INTO [" & strRange & "$] VALUES('" & strValues & "')"
Set CN = CreateObject("ADODB.Connection")
Call CN.Open(ConnectionString)
Call CN.Execute(strSQL, , 1 Or 128)
CN.Close
lbl_Exit:
Set CN = Nothing
Exit Function
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
Hello Gmayor,
Thank you for your code.
I'm still trying to understand it. I would like a program to add new data to the sheet, so I don't know if this does the same thing.
Regards,
Francis
FrancisZheng
02-10-2017, 07:12 AM
Yes, you are right. Thank you.
I found out that in the column A of macro_log, the dates are fixed on 02/02... even though their real values are different.
Do you also have this problem?
Francis
Also, I would like to have the data in the descending order(newest mail on top, oldest on bottom). So I added this line between the two "With" unit :
Range("B2").CurrentRegion.Sort key1:=Range("B2"), order1:=xlDescending, Header:=xlGuess
But it didn't work so well. Could you see where's the problem?
Francis
mancubus
02-10-2017, 08:25 AM
pls dont quote previous messages.
1) no. when i run the code, current date and time is placed on top of the table in macro_log
for sorting, add:
With Worksheets("mail_data")
.Cells(1).Sort Key1:=.Range("B2"), Order1:=xlDescending, Header:=xlYes
End With
before End Sub.
FrancisZheng
02-10-2017, 08:52 AM
pls dont quote previous messages.
1) no. when i run the code, current date and time is placed on top of the table in macro_log
for sorting, add:
With Worksheets("mail_data")
.Cells(1).Sort Key1:=.Range("B2"), Order1:=xlDescending, Header:=xlYes
End With
before End Sub.
It works ! Thank you. I will figure out the date problem.
FrancisZheng
02-10-2017, 09:03 AM
18317
FrancisZheng
02-10-2017, 09:31 AM
I still can't figure it out ...
mancubus
02-10-2017, 02:37 PM
the code inserts the system date & time at the bottom of the list in macro_log sheet, then sorts the values in column A in descending order.
if you run the code two or more times on the same day it's clear that it will the same dates into column A.
check if your system date is 02/02/2017.
and don't quote previous messages. they are still in the thread and we can read them without your quote.
we can examine your workbook if you upload it.
FrancisZheng
02-21-2017, 03:54 AM
Problem is solved. In the code the line : ...mm/mm/yyyy should be dd/mm/yyyy.
Thank you very much mancubus !
mancubus
02-21-2017, 04:27 AM
you are welcome.
mark the thread as solved from Threadtools for future references pls.
FrancisZheng
02-22-2017, 06:33 AM
Problem solved ! (How do I mark the thread?)
mancubus
02-22-2017, 01:34 PM
from Thread Tools dropdown which is above the first post on the right.
FrancisZheng
02-23-2017, 02:39 AM
Thank you !
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.