How do I move an email in Outlook to a subfolder? - vba

I am trying to create a macro that will move items in my Outlook inbox to a subfolder of another folder that is on the same level as the Inbox (i.e., the parent folder is not a sub-folder of the inbox). This is the code I am using:
Sub EventRequests()
On Error Resume Next
Dim ns As Outlook.NameSpace
Dim moveToFolder As Outlook.MAPIFolder
Dim objItem As Outlook.MailItem
Set ns = Application.GetNamespace("MAPI")
'Define path to the target folder
Set moveToFolder = ns.Folders("Events").Folders("Event Requests")
If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox ("Select an E-mail first")
Exit Sub
End If
If moveToFolder Is Nothing Then
MsgBox "Target folder not found!", vbOKOnly + vbExclamation, "Move Macro Error"
End If
For Each objItem In Application.ActiveExplorer.Selection
If moveToFolder.DefaultItemType = olMailItem Then
If objItem.Class = olMail Then
objItem.Move moveToFolder
End If
End If
Next
Set objItem = Nothing
Set moveToFolder = Nothing
Set ns = Nothing
End Sub
When I run the code I get an error that says "Target folder not found!" I tried
Set moveToFolder = ns.GetDefaultFolder(olFolderInbox).Folders("Events").Folders("Event Requests")and Set MoveToFolder = ns.Folders("Mailbox - my name").Folders(targetFolder) but neither of those worked. I have a different macro set up that moves messages in my inbox to a folder that is a subfolder of my inbox and it works fine:
Set moveToFolder = ns.GetDefaultFolder(olFolderInbox).Folders("Completed")
How do I fix the target path so that it points to the correct subfolder?

I'm going to go ahead and post an answer to my own question so that if other people in the future have this issue they can see the code I arrived at that works:
Sub EventRequests()
Dim ns As Outlook.NameSpace
Dim moveToFolder As Outlook.MAPIFolder
Dim objItem As Outlook.MailItem
Set ns = Application.GetNamespace("MAPI")
On Error GoTo 0
Set moveToFolder = ns.GetDefaultFolder(olFolderInbox).Parent.Folders("Events").Folders("Event Requests")
If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox ("Select an E-mail first")
Exit Sub
End If
If moveToFolder Is Nothing Then
MsgBox "Target folder not found!", vbOKOnly + vbExclamation, "Move Macro Error"
End If
For Each objItem In Application.ActiveExplorer.Selection
If moveToFolder.DefaultItemType = olMailItem Then
If objItem.Class = olMail Then
objItem.Move moveToFolder
End If
End If
Next
Set objItem = Nothing
Set moveToFolder = Nothing
Set ns = Nothing
End Sub

Related

Outlook VBA Stumbling Over "Undeliverable" Report

I have VBA code that marks selected messages as read, assigns a category and moves them to a subfolder.
Mail Delivery System "Undeliverable" reports are not marked-as-read, categorized or moved.
I tried to duplicate the For Each loop to look for olReportItem. (I realize that it is inefficient to have two loops, but am just doing it this way for testing purposes so I can keep all the beta code in one section.)
Sub TestMoveToSubfolder()
'With selected emails: (1) mark as read, (2) assign category, (3) move to subfolder
On Error Resume Next
Dim thisFolder As Outlook.MAPIFolder
Dim objFolder As Outlook.MAPIFolder
Dim objItem As Outlook.MailItem
Dim objStore As Store
Set thisFolder = Application.ActiveExplorer.CurrentFolder
Set objStore = thisFolder.Store
Set objFolder = thisFolder.Folders("REFERENCE_DESIRED_FOLDER")
'Be sure target folder exists
If objFolder Is Nothing Then
MsgBox "I can't find the designated subfolder.", vbOKOnly + vbExclamation, "INVALID SUBFOLDER"
Exit Sub
End If
'Confirm at least one message is selected
If Application.ActiveExplorer.Selection.Count = 0 Then
Exit Sub
End If
'Loop through emails
For Each objItem In Application.ActiveExplorer.Selection
If objFolder.DefaultItemType = olMailItem Then
If objItem.Class = olMail Then
objItem.UnRead = False
objItem.Categories = "INSERT_DESIRED_CATEGORY"
objItem.Move objFolder
End If
End If
Next
'TEST SECTION to work with undeliverable reports
Dim objItem2 As Outlook.ReportItem
'Loop through nondelivery reports
For Each objItem2 In Application.ActiveExplorer.Selection
If objFolder.DefaultItemType = olMailItem Then
If objItem2.Class = olReportItem Then
objItem2.UnRead = False
objItem2.Categories = "INSERT_DESIRED_CATEGORY"
objItem2.Move objFolder
End If
End If
Next
Set objItem2 = Nothing
Set thisFolder = Nothing
Set objFolder = Nothing
Set objItem = Nothing
Set objStore = Nothing
End Sub
The problem is related to declaring the objItem in the following way:
Dim objItem As Outlook.MailItem
or
Dim objItem2 As Outlook.ReportItem
To be able to iterate over all items selected in Outlook you need to declare the objItem as object in the code.
Typically to find out the exact line of code causing the issue you need to remove the following line:
On Error Resume Next
There also no need to have two separate loops, you may combine two conditions into the single loop:
Dim objItem As Object
'Loop through emails
For Each objItem In Application.ActiveExplorer.Selection
' check for regular mail items
If objItem.Class = olMail Then
objItem.UnRead = False
objItem.Categories = "INSERT_DESIRED_CATEGORY"
objItem.Move objFolder
End If
' check for report items
If objItem.Class = olReportItem Then
objItem.UnRead = False
objItem.Categories = "INSERT_DESIRED_CATEGORY"
objItem.Move objFolder
End If
Next
As I said in my comment, no olReportItem class exists. Declaring objItem As Variant (or As Object) will allow iteration between all selection clases (in a unique iteration. Something like that:
Dim objItem
For Each objItem In appOutlook.ActiveExplorer.Selection
If objFolder.DefaultItemType = olMailItem Then
If objItem.Class = olMail Then
objItem.UnRead = False
objItem.Categories = "INSERT_DESIRED_CATEGORY"
objItem.Move objFolder
ElseIf objItem.Class = olReport Then
Stop
'do whatever you need here...
End If
End If
Next
For the record, the final working code is below. I don't want to mark this as the answer since that seems like I am trying to take credit for the work of #niton, #FaneDuru and #Eugene Astafiev, but thanks to their input the question has been answered and the problem is solved.
Sub TestMoveToSubfolder()
'With selected emails: (1) mark as read, (2) assign category, (3) move to subfolder
Dim thisFolder As Outlook.MAPIFolder
Dim objFolder As Outlook.MAPIFolder
Dim objItem As Object 'could also define as Variant
Dim objStore As Store 'used if you want to find subfolder of current mailbox
'set folder locations
Set thisFolder = Application.ActiveExplorer.CurrentFolder 'alternative is Set thisFolder = objItem.Parent
Set objStore = thisFolder.Store 'alternative is to bypass thisFolder and use Set objStore = objItem.Parent.MAPIFolder.Store
On Error Resume Next
Set objFolder = thisFolder.Folders("REFERENCE_DESIRED_FOLDER")
On Error GoTo 0
'Be sure target folder exists
If objFolder Is Nothing Then
MsgBox "I can't find the designated subfolder.", vbOKOnly + vbExclamation, "INVALID FOLDER"
Exit Sub
End If
'Require that this procedure be called only when a message is selected
If Application.ActiveExplorer.Selection.Count = 0 Then
Exit Sub
End If
'Loop through selected items
For Each objItem In Application.ActiveExplorer.Selection
If objFolder.DefaultItemType = olMailItem Then
If objItem.Class = olMail Then
objItem.UnRead = False
objItem.Categories = "INSERT_DESIRED_CATEGORY"
objItem.Save
If thisFolder <> objFolder Then objItem.Move objFolder
ElseIf objItem.Class = olReport Then
objItem.UnRead = False
objItem.Categories = "INSERT_DESIRED_CATEGORY"
objItem.Save
If thisFolder <> objFolder Then objItem.Move objFolder
End If
End If
Next
'Clean up
Set thisFolder = Nothing
Set objFolder = Nothing
Set objItem = Nothing
Set objStore = Nothing
End Sub

How to setup VBscript to run in a specific folder in Outlook [duplicate]

How can I in an Outlook VBA macro iterate all email items in a specific Outlook folder (in this case the folder belongs not to my personal inbux but is a sub-folder to the inbox of a shared mailbox.
Something like this but I've never done an Outlook macro...
For each email item in mailboxX.inbox.mySubfolder.items
// do this
next item
I tried this but the inbox subfolder is not found...
Private Sub Application_Startup()
Dim objNS As Outlook.NameSpace
Dim objFolder As Outlook.MAPIFolder
Set objNS = GetNamespace("MAPI")
Set objFolder = objNS.Folders("myGroupMailbox")
Set objFolder = objFolder.Folders("Inbox\mySubFolder1\mySubFolder2")
On Error GoTo ErrorHandler
Dim Msg As Outlook.MailItem
For Each Item In objFolder.Items
If TypeName(Item) = "MailItem" Then
Set Msg = Item
If new_msg.Subject Like "*myString*" Then
strBody = myItem.Body
Dim filePath As String
filePath = "C:\myFolder\test.txt"
Open filePath For Output As #2
Write #2, strBody
Close #2
End If
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
Next Item
End Sub
In my case the following worked:
Sub ListMailsInFolder()
Dim objNS As Outlook.NameSpace
Dim objFolder As Outlook.MAPIFolder
Set objNS = GetNamespace("MAPI")
Set objFolder = objNS.Folders.GetFirst ' folders of your current account
Set objFolder = objFolder.Folders("Foldername").Folders("Subfoldername")
For Each Item In objFolder.Items
If TypeName(Item) = "MailItem" Then
' ... do stuff here ...
Debug.Print Item.ConversationTopic
End If
Next
End Sub
Likewise, you can as well iterate through calender items:
Private Sub ListCalendarItems()
Set olApp = CreateObject("Outlook.Application")
Set olNS = olApp.GetNamespace("MAPI")
Set olRecItems = olNS.GetDefaultFolder(olFolderTasks)
strFilter = "[DueDate] > '1/15/2009'"
Set olFilterRecItems = olRecItems.Items.Restrict(strFilter)
For Each Item In olFilterRecItems
If TypeName(Item) = "TaskItem" Then
Debug.Print Item.ConversationTopic
End If
Next
End Sub
Note that this example is using filtering and also .GetDefaultFolder(olFolderTasks) to get the builtin folder for calendar items. If you want to access the inbox, for example, use olFolderInbox.
The format is:
Set objFolder = objFolder.Folders("Inbox").Folders("mySubFolder1").Folders("mySubFolder2")
As advised in a comment "move the next item line to before the ProgramExit label"
Sub TheSub()
Dim objNS As Outlook.NameSpace
Dim fldrImAfter As Outlook.Folder
Dim Message As Outlook.MailItem
'This gets a handle on your mailbox
Set objNS = GetNamespace("MAPI")
'Calls fldrGetFolder function to return desired folder object
Set fldrImAfter = fldrGetFolder("Folder Name Here", objNS.Folders)
For Each Message In fldrImAfter.Items
MsgBox Message.Subject
Next
End Sub
Recursive function to loop over all folders until the specified folder name is found....
Function fldrGetFolder( _
strFolderName As String _
, objParentFolderCollection As Outlook.Folders _
) As Outlook.Folder
Dim fldrSubFolder As Outlook.Folder
For Each fldrGetFolder In objParentFolderCollection
'MsgBox fldrGetFolder.Name
If fldrGetFolder.Name = strFolderName Then
Exit For
End If
If fldrGetFolder.Folders.Count > 0 Then
Set fldrSubFolder = fldrGetFolder(strFolderName,
fldrGetFolder.Folders)
If Not fldrSubFolder Is Nothing Then
Set fldrGetFolder = fldrSubFolder
Exit For
End If
End If
Next
End Function

Need Error Message: Move To code

I have a Move to Code. The issue I am having is a result of multiple accounts. I have 3 to be exact.
Let's say - My boss emailed me, so I jump from my work account to my personal account. I read her email, jump back to my work account and run macro. It moves her (last read/selected) to location. I don't know how many personal emails I've moved by mistake because I forgot to reselect the correct email I meant to move.
How can I produce a prompt message stating I'm in the wrong account and if I should proceed? Note: there may be times I may need to proceed.
Additional Information:
Account One: Chieri Thompson (Personal)
Account Two: Artwork Emails
Account Three: DesignProofsTAC (work email - the one utilizing move to macro)
Under Design Proofs TAC is :
Inbox (folder)
Completed (subfolder)
Outsourced (subfolder)
.....
Private Sub CommandButton7_Click() 'COMPLETED
On Error Resume Next
Dim ns As Outlook.NameSpace
Dim MoveToFolder As Outlook.MAPIFolder
Dim objItem As Outlook.MailItem
Set objItem = objApp.ActiveInspector.CurrentItem
Set ns = Application.GetNamespace("MAPI")
Set MoveToFolder = ns.Folders("designproofstac").Folders("Inbox").Folders("3_COMPLETED")
If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox ("Not in Correct Folder")
Exit Sub
End If
' this is the error code I want to produce the "you are in wrong account - proceed anyway?" DesignProofsTAC should be "default" i guess.
If MoveToFolder Is Nothing Then
MsgBox "Target folder not found!", vbOKOnly + vbExclamation, "Move Macro Error"
End If
For Each objItem In Application.ActiveExplorer.Selection
If MoveToFolder.DefaultItemType = olMailItem Then
If objItem.Class = olMail Then
objItem.Move MoveToFolder
End If
End If
Next
Set objItem = Nothing
Set MoveToFolder = Nothing
Set ns = Nothing
End Sub
You may find this simpler than checking accounts.
Untested Code:
Option Explicit
Sub MoveOpenMail 'COMPLETED
' Place a button on the Quick Access Toolbar for an item opened for reading.
Dim ns As NameSpace
Dim MoveToFolder As Folder
Dim objItem As object ' <--- May not be a mailitem
Set ns = Application.GetNamespace("MAPI")
' Do not use On Error Resume Next
' unless there is a specific purpose
' and it is quickly followed by On Error GoTo 0
On Error Resume Next
Set MoveToFolder = ns.Folders("designproofstac").Folders("Inbox").Folders("3_COMPLETED")
On Error GoTo 0
If MoveToFolder Is Nothing Then
MsgBox "Target folder not found!", vbOKOnly + vbExclamation, "MoveOpenMail VBA Error"
GoTo ExitRoutine
End If
On Error Resume Next
Set objItem = ActiveInspector.CurrentItem
On Error GoTo 0
If objItem Is Nothing Then
MsgBox "Use this code when there is an open mailitem!", vbOKOnly + vbExclamation, "MoveOpenMail VBA Error"
GoTo ExitRoutine
End If
If MoveToFolder.DefaultItemType = olMailItem Then
If objItem.Class = olMail Then
objItem.Move MoveToFolder
End If
Else
MsgBox "Target folder is wrong type!", vbOKOnly + vbExclamation, "MoveOpenMail VBA Error"
End If
ExitRoutine:
Set ns = Nothing
Set MoveToFolder = Nothing
Set objItem = Nothing
End Sub
Sub MoveSelectedMail 'COMPLETED
' Place a button on the Quick Access Toolbar for an open folder
Dim ns As NameSpace
Dim MoveToFolder As Folder
Dim objItem as Object
Dim objExplorer As Explorer
Dim objSelection As Object
Dim x as Long
Set ns = Application.GetNamespace("MAPI")
On Error Resume Next
Set MoveToFolder = ns.Folders("designproofstac").Folders("Inbox").Folders("3_COMPLETED")
On Error GoTo 0
If MoveToFolder Is Nothing Then
MsgBox "Target folder not found!", vbOKOnly + vbExclamation, "MoveSelectedMail VBA Error"
GoTo ExitRoutine
End If
Set objExplorer = ActiveExplorer
Set objSelection = objExplorer.Selection
If objSelection.Count = 0 Then
MsgBox "Select one or more mailitems"
GoTo ExitRoutine
Else
If MoveToFolder.DefaultItemType = olMailItem Then
' Do not use For Each
' Count backwards when moving or deleting
For x = objSelection.Count to 1 step -1
Set objItem = objSelection.Item(x)
If objItem.Class = olMail Then
objItem.Move MoveToFolder
End If
Next x
Else
MsgBox "Target folder is wrong type!", vbOKOnly + vbExclamation, "MoveSelectedMail VBA Error"
End If
End If
ExitRoutine:
Set ns = Nothing
Set MoveToFolder = Nothing
Set objItem = Nothing
Set objExplorer = Nothing
Set objSelection = Nothing
End Sub
The Namespace class provides the Accounts property which eturns an Accounts collection object that represents all the Account objects in the current profile. The Account class provides the DeliveryStore property which returns a Store object that represents the default delivery store for the account. So, you can compare the Store where you chose the item and the default store for the account you need to move the item.
Also you may find the GetDefaultFolder method of the Store class helpful, it returns a Folder object that represents the default folder in the store and that is of the type specified by the FolderType argument. This method is similar to the GetDefaultFolder method of the NameSpace object. The difference is that this method gets the default folder on the delivery store that is associated with the account, whereas NameSpace.GetDefaultFolder returns the default folder on the default store for the current profile.

Outlook flag an email and move it to a folder

Is there a script that would allow me to flag an email in outlook and then automatically move it to a folder?
I found the following that will copy selected email and move it, but I need it to flag it as well;
Outlook VB Macro to move selected mail item(s) to a target folder
Sub MoveToFiled()
On Error Resume Next
Dim ns As Outlook.NameSpace
Dim moveToFolder As Outlook.MAPIFolder
Dim objItem As Outlook.MailItem
Set ns = Application.GetNamespace("MAPI")
'Define path to the target folder
Set moveToFolder = ns.Folders("Mailbox - Jim Merrell").Folders("#Filed")
If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox ("No item selected")
Exit Sub
End If
If moveToFolder Is Nothing Then
MsgBox "Target folder not found!", vbOKOnly + vbExclamation, "Move Macro Error"
End If
For Each objItem In Application.ActiveExplorer.Selection
If moveToFolder.DefaultItemType = olMailItem Then
If objItem.Class = olMail Then
objItem.move moveToFolder
End If
End If
Next
Set objItem = Nothing
Set moveToFolder = Nothing
Set ns = Nothing
End Sub
Cheers,
Steven
in the end the follwoing line should do the Job:
mail.FlagRequest = "text you need"
or if you also want to set reminders etc. use this
Sub flag_the_mail(mail As mailitem, flagre as string, tm As String)
On Error GoTo ende
mail.MarkAsTask olMarkNoDate
mail.FlagRequest = flagre
If tm <> "00:00:00 09:00" Then
mail.TaskStartDate = tm
mail.TaskDueDate = tm
mail.ReminderSet = True
mail.ReminderTime = tm
Else
mail.TaskStartDate = "01.01.4501"
mail.TaskDueDate = "01.01.4501"
mail.ReminderSet = False
mail.ReminderTime = "00:00:00"
End If
mail.Save
ende:
If Err.Number <> 0 Then MsgBox ("Fehler in 'Kennzeichensetzen': " & Err.Number & " - " & Err.Description)
End Sub
tm - which is the date - comes as a text here, e.g. "03.11.2014 09:00"
I hope this helps,
Max

Type Mismatch error when items in Inbox declared as mailitems

I have the following VBA code in Outlook to move mail to a personal folder if it is old. Here is the code:
I get an exception on the line Next objItem (looking at the watch it is set to nothing).
What would cause objItem to be null and thus cause a Type Mismatch exception in the Next objItem line?
Sub MoveOldMailFromInbox()
Dim objFolder As Outlook.MAPIFolder
Dim objNS As Outlook.NameSpace, objItem As Outlook.MailItem, mail As Outlook.MailItem
Set objNS = Application.GetNamespace("MAPI")
Dim Inbox As MAPIFolder
Set Inbox = objNS.GetDefaultFolder(olFolderInbox)
Dim mailToMove As New Collection
Dim EightyFiveDaysAgo As Date
EightyFiveDaysAgo = DateAdd("d", -85, Date)
Set objFolder = objNS.Folders("PersonalFolders").Folders("InboxOlderThan85Days")
If objFolder Is Nothing Then
MsgBox "This folder doesn't exist!", vbOKOnly + vbExclamation, "INVALID FOLDER"
End If
For Each objItem In Inbox.Items
If objFolder.DefaultItemType = olMailItem Then
If objItem.Class = olMail And objItem.ReceivedTime < EightyFiveDaysAgo Then
mailToMove.Add objItem
End If
End If
Next objItem
For Each mail In mailToMove
mail.UnRead = False
mail.Move objFolder
Next mail
Set objItem = Nothing
Set objFolder = Nothing
Set objNS = Nothing
End Sub
You're iterating through Inbox.Items but your variable objItem is defined as MailItem - an item in your inbox might not always be a MailItem.
Try
Dim objItem as Object