Send email from draft folder - excel

with the below VBA coding, I am able to send all the emails from outlook draft folder but the only problem is that I have to provide the parent folder name. Can we get this details through coding as this macro will be used by other user who is not familiar with VBA.
Dim lDraftItem As Long
Dim myOutlook As Outlook.Application
Dim myNameSpace As Outlook.NameSpace
Dim myFolders As Outlook.Folders
Dim myDraftsFolder As Outlook.MAPIFolder
Set myOutlook = Outlook.Application
Set myNameSpace = myOutlook.GetNamespace("MAPI")
Set myFolders = myNameSpace.Folders
Set myDraftsFolder = myFolders("Gaus_Shaikh2#syntelinc.com").Folders("Drafts")
For lDraftItem = myDraftsFolder.Items.Count To 1 Step -1
If Len(Trim(myDraftsFolder.Items.Item(lDraftItem).To)) > 0 Then
myDraftsFolder.Items.Item(lDraftItem).Send
End If
Next lDraftItem

This should work...
Set myDraftsFolder = myNamespace.GetDefaultFolder(olFolderDrafts)
* Edit *
The code below is probably a better function to use; it has error checking incorporated so any e-mails with invalid fields in the 'To' section shouldn't abort the function
Sub TestSendDrafts()
Call SendDraftMail
End Sub
Function SendDraftMail() As Boolean
On Error GoTo ExitFunction
Dim ThisNameSpace As Outlook.NameSpace: Set ThisNameSpace = Application.GetNamespace("MAPI")
Dim DraftFolder As Outlook.MAPIFolder: Set DraftFolder = ThisNameSpace.GetDefaultFolder(olFolderDrafts)
Dim Var As Variant, i As Long, Difference As Long, SentItems As Long
For i = DraftFolder.Items.Count To 1 Step -1
Set Var = DraftFolder.Items.Item(i)
DoEvents
If Var.Class = olMail Then
If Len(Trim(Var.To)) > 0 Then
On Error Resume Next
Var.Send
If Err.Number = 0 Then SentItems = SentItems + 1
On Error GoTo ExitFunction
End If
End If
Next i
Debug.Print "Sent " & SentItems & " message(s) from 'Draft E-mail'."
SendDraftMail = True
ExitFunction:
End Function

Replace this line:
Set myDraftsFolder = myFolders("Gaus_Shaikh2#syntelinc.com").Folders("Drafts")
With these three lines:
Dim sUser As String
sUser = myFolders.Item(2).Name
Set myDraftsFolder = myFolders(sUser).Folders("Drafts")
The 2nd folder name will be the user account name (e-mail address), which you can store as a string and pass into myFolders() to qualify their specific account.

Related

I want to read SenderAddress from office 365 Outlook mail using VBA in excel?

I have tried everything to read a mail from office 365 outlook but I am not able to read it. Every time Sender address is coming empty.
Error That I am getting is :
Run-time error: ‘287’
Application-defined or object-defined error.
Please find the code that I am using.
Option Explicit
Sub Mail()
Dim xNameSpace As Outlook.Namespace
Dim xFolder As Outlook.Folder
Dim xOutlookApp As Outlook.Application
Set xOutlookApp = New Outlook.Application
Set xNameSpace = xOutlookApp.Session
Set xFolder = xNameSpace.GetDefaultFolder(olFolderInbox)
Set xFolder = xFolder.Folders("Retail")
' Set Outlook application object.
Dim objOutlook As Object
Set objOutlook = CreateObject("Outlook.Application")
Dim objNSpace As Object ' Create and Set a NameSpace OBJECT.
' The GetNameSpace() method will represent a specified Namespace.
Set objNSpace = objOutlook.GetNamespace("MAPI")
Dim myFolder As Object ' Create a folder object.
Set myFolder = objNSpace.GetDefaultFolder(olFolderInbox)
Dim objItem As Object
Dim iRows, iCols As Integer
iRows = 2
' Loop through each item in the folder.
For Each objItem In xFolder.Items
If objItem.Class = olMail Then
Dim GetSenderAddress As String
Dim objMail As Outlook.MailItem
Set objMail = objItem
Dim mailType As String
mailType = objMail.SenderEmailType
If mailType = "EX" Then
' GetSenderAddress = GetExchangeSenderAddressNew(objMail)
FindAddress (objMail.SenderEmailAddress)
Else
GetSenderAddress = objMail.SenderEmailAddress
End If
Cells(iRows, 1) = objMail.SenderEmailAddress
Cells(iRows, 2) = objMail.To
Cells(iRows, 3) = objMail.Subject
Cells(iRows, 4) = objMail.ReceivedTime
End If
iRows = iRows + 1
Next
Set objMail = Nothing
' Release.
Set objOutlook = Nothing
Set objNSpace = Nothing
Set myFolder = Nothing
End Sub
Private Function GetExchangeSenderAddress(objMsg As MailItem) As String
Dim oSession As Object
Set oSession = CreateObject("MAPI.Session")
oSession.Logon "", "", False, False
Dim sEntryID As String
Dim sStoreID As String
Dim oCdoMsg As Object
Dim sAddress As String
Const g_PR_SMTP_ADDRESS_W = &H39FE001F
sEntryID = objMsg.EntryID
sStoreID = objMsg.Parent.StoreID
Set oCdoMsg = oSession.GetMessage(sEntryID, sStoreID)
sAddress = oCdoMsg.Sender.Fields(g_PR_SMTP_ADDRESS_W).Value
Set oCdoMsg = Nothing
oSession.Logoff
Set oSession = Nothing
GetExchangeSenderAddress = sAddress
End Function
Another Code is:
Sub Mail()
Dim jsObj As New ScriptControl
jsObj.Language = "JScript"
With jsObj
.AddCode "outlookApp = new ActiveXObject('Outlook.Application'); nameSpace = outlookApp.getNameSpace('MAPI'); nameSpace.logon('','',false,false); mailFolder = nameSpace.getDefaultFolder(6); var Inbox = mailFolder.Folders; var box = Inbox.Item('Retail').Items; "
End With
End Sub
Please let me know if i can read sender address of a mail in office 365 outlook.
First of all, the following lines of code iterates over all items in the folder:
' Loop through each item in the folder.
For Each objItem In xFolder.Items
If objItem.Class = olMail Then
Where you don't check whether it is received or composed item. Composed emails may not have the Sender-related properties set yet, so you can use the CurrentUser property which returns the display name of the currently logged-on user as a Recipient object.
Note, in case of Exchange accounts configured you may use the AddressEntry.GetExchangeUser property which returns an ExchangeUser object that represents the AddressEntry if the AddressEntry belongs to an Exchange AddressList object such as the Global Address List (GAL) and corresponds to an Exchange user.
The ExchangeUser.PrimarySmtpAddress property returns a string representing the primary Simple Mail Transfer Protocol (SMTP) address for the ExchangeUser.

Unable to find 'Type Mismatch Error" in VBA

Its works frist time when i am login to the system but for testing second time if i am going to run this code again it will gives me type mismatch error. can somebody help me on this.
Sub Saveattachment()
Application.DisplayAlerts = False
Dim ATMT As Outlook.Attachment
Dim OMAIL As Outlook.MailItem
Dim FOL As Outlook.Folder
Dim ONS As Outlook.Namespace
Dim OLOOK As Outlook.Application
Dim var As Date
Dim count As Long
count = 0
Dim name As String
Dim temp As Variant
Set OLOOK = New Outlook.Application
Set ONS = Outlook.GetNamespace("MAPI")
Set FOL = ONS.Folders("IM_DMBI").Folders("inbox")
Set OMAIL = OLOOK.CreateItem(olMailItem)
msgbox "Please remove old downloads, If already remove please ingore and press Ok to proceed", vbInformation
For Each OMAIL In FOL.items
For Each ATMAT In OMAIL.Attachments
var = Format(OMAIL.ReceivedTime, "MM/DD/YY")
name = Left(OMAIL.Subject, 3)
If name = "304" And var = Date And Err.Number = 13 Then
count = count + 1
ATMAT.SaveAsFile Sheet1.Cells(1, 1) & Application.PathSeparator & ATMAT.filename
End If
If var < Date Then
msgbox "Totlay:-" & count & " Files downloaded for today", vbInformation
Exit Sub
End If
Next
Next
Application.DisplayAlerts = True
End Sub
Screenshot of the error: https://i.stack.imgur.com/5dKPy.png
This helps you to ignore type mismatch error:
Sub GetAttachment()
Application.DisplayAlerts = False
Dim ATMT As Outlook.Attachment
Dim OMAIL As Outlook.MailItem
Dim FOL As Outlook.Folder
Dim ONS As Outlook.Namespace
Dim OLOOK As Outlook.Application
Dim var As Date
Dim count As Long
count = 0
Dim name As String
Dim temp As Variant
Set OLOOK = New Outlook.Application
Set ONS = Outlook.GetNamespace("MAPI")
Set FOL = ONS.Folders("IM_DMBI").Folders("inbox")
Set OMAIL = OLOOK.CreateItem(olMailItem)
'msgbox "Please remove old downloads, If already remove please ingore and press Ok to proceed", vbInformation
For Each OMAIL In FOL.items
On Error GoTo errorHandler
For Each ATMAT In OMAIL.Attachments
var = Format(OMAIL.ReceivedTime, "MM/DD/YY")
name = Left(OMAIL.Subject, 5)
If name = "304 r" And var = Date Then
count = count + 1
ATMAT.SaveAsFile Sheet1.Cells(1, 1) & Application.PathSeparator & ATMAT.filename
End If
If var < Date Then
'msgbox "Totlay:-" & count & " Files downloaded for today", vbInformation
Exit Sub
End If
Next
TypeMismatch:
Next
errorHandler:
If Err = 13 Then 'Type Mismatch
Resume TypeMismatch
End If
Application.DisplayAlerts = True
End Sub
There can be items other than mailitems in the inbox.
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
' If desperate declare as Variant
Sub Saveattachment()
Application.DisplayAlerts = False
'Dim ATMT As outlook.Attachment
Dim ATMAT As outlook.Attachment
Dim oObjItem As Object 'Any type, there can never be a mismatch
Dim OMAIL As outlook.MailItem
Dim FOL As outlook.folder
Dim ONS As outlook.namespace
Dim OLOOK As outlook.Application
Dim var As Date
Dim count As Long
count = 0
Dim name As String
Dim temp As Variant
Set OLOOK = New outlook.Application
'Set ONS = outlook.GetNamespace("MAPI")
Set ONS = OLOOK.GetNamespace("MAPI")
Set FOL = ONS.folders("IM_DMBI").folders("inbox")
'Set OMAIL = OLOOK.CreateItem(olMailItem)
For Each oObjItem In FOL.Items ' any type of item
'For Each OMAIL In FOL.Items
' One of at least three ways to verify
If TypeName(oObjItem) = "MailItem" Then
' Now that you have a mailitem
Set OMAIL = oObjItem
For Each ATMAT In OMAIL.Attachments
Debug.Print "Attachment found."
Next
Else
Debug.Print "This would have been a type mismatch."
End If
Next
Application.DisplayAlerts = True
End Sub

How can I copy every unread message from default inbox to a shared folder?

I'm trying to organize 10+ different mailboxes.
The problem is with UnreadMove. I want every time Outlook opens to look for unread mails in the default inbox, copy it and move one of the copies to a shared inbox.
It works if there is one mail to move, but when there are more I get an error
"-2147221241 - Failed Client Action"
or something similar. My Windows is not in English.
When I press ok on the failure window the mails are still copied and moved to the correct folder, so I don't know what the error means. Some mails are copying twice, so might be what the error stands for.
MoveAndCopy: incoming mail is copied and sent to the shared inbox and is marked as read in the original folder (this works).
UnreadMove: should be used when Outlook has not been open for a while and the original inboxes got new mails. Then I want the unread e-mails to be copied, marked as read and then a copy sent to the shared inbox, which should not be marked as read.
ThisOutlookSession
Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_UnreadMove(ByVal Item As Object)
Dim msg As Outlook.MailItem
If Item.Exists = True Then
Set msg = Item
Call UnreadMove(Item)
End If
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
On Error GoTo ErrorHandler
Dim msg As Outlook.MailItem
If TypeName(Item) = "MailItem" Then
Set msg = Item
Call MoveAndCopy(Item)
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
And for the two modules:
Sub UnreadMove(Item As Outlook.MailItem)
Dim Inbox As Outlook.Folder
Dim ns As Outlook.NameSpace
Dim MailDest As Outlook.Folder
Dim CopiedItem As Outlook.MailItem
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
For Each Item In Inbox
If Item.UnRead = True Then
Set CopiedItem = Item.Copy
Item.UnRead = False
Item.Save
Set ns = Outlook.Application.GetNamespace("MAPI")
Set MailDest = ns.Folders("myemail#test.com").Folders("MyInbox")
CopiedItem.Move MailDest
End If
Next Item
End Sub
Sub MoveAndCopy(Item As Outlook.MailItem)
Dim ns As Outlook.NameSpace
Dim MailDest As Outlook.Folder
Dim CopiedItem As Outlook.MailItem
If Item.Class = olMail Then
Set CopiedItem = Item.Copy
Item.UnRead = False
Item.Save
Set ns = Outlook.Application.GetNamespace("MAPI")
Set MailDest = ns.Folders("myemail#test.com").Folders("MyInbox")
CopiedItem.Move MailDest
End If
End Sub
UnreadMove makes a copy in the monitored folder. It would invoke Items_ItemAdd. The same for MoveAndCopy.
Whether this is the cause of the error you see now, this should do what you want.
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
' If desperate declare as Variant
Private WithEvents monitoredItems As Items
Private Sub Application_Startup()
UnreadMove
Set monitoredItems = Session.GetDefaultFolder(olFolderInbox).Items
End Sub
Sub UnreadMove()
Dim Inbox As folder
Dim MailDest As folder
Dim CopiedItem As MailItem
Dim objItem As Object
Set Inbox = Session.GetDefaultFolder(olFolderInbox)
Set MailDest = Session.folders("myemail#test.com").folders("MyInbox")
' Copying invokes itemAdd
' If you run this manually,
' after setting up monitoredItems in startup
' - a trick to turn itemAdd off
Set monitoredItems = Nothing
'
'For Each objItem In Inbox.Items
' If objItem.Class = olMail Then
' If objItem.UnRead = True Then
' Debug.Print objItem.subject
'
' Set CopiedItem = objItem.copy
' objItem.UnRead = False
' objItem.Save
' CopiedItem.Move MailDest
' End If
' End If
'Next objItem
' If the For Each index is confused by copying and moving
' Then a reverse For Next is needed.
' A reverse loop works in all situations.
Dim i As Long
For i = Inbox.Items.count To 1 Step -1
Set objItem = Inbox.Items(i)
If objItem.Class = olMail Then
If objItem.UnRead = True Then
Debug.Print objItem.subject
Set CopiedItem = objItem.copy
objItem.UnRead = False
objItem.Save
CopiedItem.Move MailDest
End If
End If
Next
' reset items to be monitored with itemAdd
Set monitoredItems = Session.GetDefaultFolder(olFolderInbox).Items
End Sub
To temporarily stop monitoring, when you make a copy in the monitored folder.
Private Sub monitoredItems_ItemAdd(ByVal Item As Object)
Dim msg As MailItem
If TypeName(Item) = "MailItem" Then
Set msg = Item
Set monitoredItems = Nothing
'Call MoveAndCopy(Item)
Call MoveAndCopy(msg)
' or
' MoveAndCopy msg
Set monitoredItems = Session.GetDefaultFolder(olFolderInbox).Items
End If
End Sub
You could stop monitoring in MoveAndCopy instead, if you wish to be more specific.

How to access emails in shared mailbox?

I have two accounts in Outlook one is my personal and another is shared.
I want to read or unread emails of my shared mail box.
I have code that is working with my personal Inbox.
With my shared email group it is showing
Sub OutlookTesting()
Dim folders As Outlook.folders
Dim Folder As Outlook.MAPIFolder
Dim iRow As Integer
Dim Pst_Folder_Name
Dim MailboxName
Dim UnRow As Integer
Dim RESS As Outlook.Recipient
Dim Flag As Integer
'Mailbox or PST Main Folder Name (As how it is displayed in your Outlook Session)
MailboxName = "Dummi#abc.com" 'Mailbox Folder or PST Folder Name (As how it is displayed in your Outlook Session)
Pst_Folder_Name = "Inbox"
' subfolder name
Dim subFolderName As String
subFolderName = "XYZ"
Set Folder = Outlook.Session.folders(MailboxName).folders(Pst_Folder_Name)
If Folder = "" Then
MsgBox "Invalid Data in Input"
GoTo end_lbl1:
End If
'Read Through each Mail and export the details to Excel for Email Archival
For iRow = 1 To Folder.Items.Count
If (Folder.Items(iRow).UnRead) Then
Flag = 0
Set Res = Folder.Items(iRow).Recipients
For Each RESS In Res
If RESS.Name = "ABCD" Or RESS.Name = "PQRS" Then
Flag = 1
End If
Next
If Flag = 1 Then
Folder.Items(iRow).UnRead = True
Else: Folder.Items(iRow).UnRead = False
End If
End If
Next iRow
MsgBox "Outlook Mails Extracted to Excel"
end_lbl1:
End Sub
Hi you can try with the below code(I have edit your above posted code) and also remove unusual code according to your need.
Sub OutlookTesting()
Dim folders As Outlook.folders
Dim folder As Outlook.MAPIFolder
Dim iRow As Integer
Dim Pst_Folder_Name
Dim MailboxName
Dim UnRow As Integer
Dim RESS As Outlook.Recipient
Dim Flag As Integer
Dim olApp As Outlook.Application
Dim olNS As Outlook.Namespace
Dim olfldr As Outlook.MAPIFolder
Dim foldername As Outlook.MAPIFolder
Dim sharedemail As Outlook.Recipient
Set olApp = New Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")
Set sharedemail = olNS.CreateRecipient("youremail#abc.com")
Set olfldr = olNS.GetSharedDefaultFolder(sharedemail, olFolderInbox)
Set folder = olfldr
If folder = "" Then
MsgBox "Invalid Data in Input"
GoTo end_lbl1:
End If
'Rad Through each Mail and export the details to Excel for Email Archival
For iRow = 1 To folder.Items.Count
If (folder.Items(iRow).UnRead) Then
Flag = 0
Set Res = folder.Items(iRow).Recipients
For Each RESS In Res
If RESS.Name = "XYZ" Or RESS.Name = "ABC" Then
Flag = 1
End If
Next
If Flag = 1 Then
folder.Items(iRow).UnRead = True
Else: folder.Items(iRow).UnRead = False
End If
End If
Next iRow
MsgBox "Outlook Mails Extracted to Excel"
end_lbl1:
End Sub

Move a specific number of emails from shared Outlook folder

Every few days I manually move a specified number of emails from a shared network mailbox to subfolders of team managers. They want them moved from oldest to newest. Both the managers and the number can change each time.
I wrote a script for moving a small number of emails with a specific subject line in the folder to a subfolder to be worked by a certain group.
I have tried to adapt this to my current task.
Sub Moverdaily()
On Error GoTo errHandler
Dim olApp As Outlook.Application
Dim objNS As Outlook.Namespace
Dim olFolder As Outlook.MAPIFolder
Dim msg As Outlook.MailItem
Dim manager= As Outlook.MAPIFolder
Dim cell,start,finish,rng As Range
Dim countE,countM As Integer
Dim emcount, casecount, movedcount
Set rng = Range(Range("A2"), Range("A2").End(xlDown))
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
Set olFolder = objNS.Folders("Documents").Folders("Inbox")
Set manager = objNS.Folders("Document").Folders("Inbox").Folders("Manager")
Set finish = ThisWorkbook.Sheets("Mover").Range("I11")
Set start = ThisWorkbook.Sheets("Mover").Range("I10")
start.Value = Format(Now, "hh:mm:ss")
Set emcount = Range("I12")
Set casecount = Range("I13")
Set movedcount = Range("I14")
countM = 0
countE = 0
For i = olFolder.Items.count To 1 Step -1
For Each cell In rng
If (cell.Text = (onlyDigits(msg.Subject))) Then
msg.move manager
countM = 1 + countM
cell.Offset(0, 1).Value = "Moved"
End If
Next
countE = 1 + countE
Next
finish.Value = Format(Now, "hh:mm:ss")
emcount.Value = countE
casecount.Value = rng.count
movedcount.Value = countM
errHandler:
MsgBox ("Error " & Err.Number & ": " & Err.Description)
Exit Sub
End Sub
Firstly, do not use "for each" with a collection that you change - MailItem.Mpve removes an itemn from that collection. Use a for i = Items.Count to 1 step -1 instead.
Secondly, do not loop through all item - if you already know the entry ids (rngarry), simply call Namespace.GetItemfromID.

Resources