Shared Mailbox Management - vba

I need a macro that will move messages received into a shared mailbox to a subfolder of that mailbox, depending on the sender's email address, basically a normal outlook rule.
I've been looking at some articles on http://www.slipstick.com/ which has got me part way there but there isn't an exact solution for what I want to do and I'm not proficient enough with VBA in Outlook yet to work it out.
So far I've got this code on ThisOutlookSession to watch the mailbox:
Dim i As Long
Private WithEvents olInboxItems As Items
Private Sub Application_Startup()
Dim objNS As NameSpace
Set objNS = Application.Session
Set olInboxItems = GetFolderPath(">Digital Analytics\Inbox").Items
Set objNS = Nothing
End Sub
And this function in a module to obtain the path of the watched mailbox folder:
' Use the GetFolderPath function to find a folder in non-default mailboxes
Function GetFolderPath(ByVal FolderPath As String) As Outlook.Folder
Dim oFolder As Outlook.Folder
Dim FoldersArray As Variant
Dim i As Integer
On Error GoTo GetFolderPath_Error
If Left(FolderPath, 2) = "\\" Then
FolderPath = Right(FolderPath, Len(FolderPath) - 2)
End If
'Convert folderpath to array
FoldersArray = Split(FolderPath, "\")
Set oFolder = Application.Session.Folders.Item(FoldersArray(0))
If Not oFolder Is Nothing Then
For i = 1 To UBound(FoldersArray, 1)
Dim SubFolders As Outlook.Folders
Set SubFolders = oFolder.Folders
Set oFolder = SubFolders.Item(FoldersArray(i))
If oFolder Is Nothing Then
Set GetFolderPath = Nothing
End If
Next
End If
'Return the oFolder
Set GetFolderPath = oFolder
Exit Function
GetFolderPath_Error:
Set GetFolderPath = Nothing
Exit Function
End Function

This works, I used a case to move the item if it came from a specific email address:
Dim i As Long
Private WithEvents olInboxItems As Items
Private Sub Application_Startup()
Dim objNS As NameSpace
Set objNS = Application.Session
Set olInboxItems = GetFolderPath(">Digital Analytics\Inbox").Items
Set objNS = Nothing
For Each Item In olInboxItems
End Sub
Private Sub olInboxItems_ItemAdd(ByVal Item As Object)
Dim objDestFolder As Outlook.MAPIFolder
Dim destFolder As String
Dim sendersAddress As String
If Item.Class = olMail Then
sendersAddress = Item.SenderEmailAddress
Select Case sendersAddress
Case "no-reply#omniture.com"
destFolder = ">Digital Analytics\Inbox\Reports"
Case "no-reply#edigitalresearch.com"
destFolder = ">Digital Analytics\Inbox\Reports"
End Select
Set objDestFolder = GetFolderPath(destFolder)
Item.Move objDestFolder
End If
End Sub

Related

Run code when new email comes to any subfolder in a Shared Mailbox

I want to run code when any new email comes to a specific shared mailbox.
The event triggers when the email comes to INBOX folder.
The event does not trigger if a new email comes straight to its subfolders - like to shared#mailbox.com/Inbox/subfolder1.
What should I change so the code runs if a new email comes to any subfolder in the inbox?
The mailbox has a lot of subfolders. Moreover their structure may change.
Option Explicit
Private WithEvents mtFolder As Outlook.Folder
Private WithEvents mtItems As Outlook.Items
Private Sub mtItems_ItemAdd(ByVal Item As Object)
Debug.Print "XXX"
'my CODE
End Sub
Private Sub Application_Startup()
Dim Ns As Outlook.NameSpace
Set Ns = Application.GetNamespace("MAPI")
Dim objOwner
Set objOwner = Ns.CreateRecipient("shared#mailbox.com")
objOwner.Resolve
If objOwner.Resolved Then
Set mtFolder = Ns.GetSharedDefaultFolder(objOwner, olFolderInbox)
Set mtItems = mtFolder.Items
End If
Set Ns = Nothing
Exit Sub
eh:
End Sub
Thank you a lot for your help! Here the solution.
At first I have added Class Module named "clsFolder" with events:
Option Explicit
Private OlFldr As Folder
Public WithEvents Items As Outlook.Items
'called to set up the object
Public Sub Init(f As Folder) ', sPath As String)
Set OlFldr = f
Set Items = f.Items
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
If TypeOf Item Is Outlook.MailItem Then
Debug.Print "eMail '" & Item.Subject & "' was added to Folder '" & OlFldr.name & _
"'. Mailbox: '" & Item.Parent.Store & "'."
'do sth with a email added...
End If
End Sub
Then in ThisOutlookSession I setup a collecion of folder for all (sub)folders in the SharedMailbox:
Option Explicit
Public colFolders As Collection '<< holds the clsFolder objects with events
Private Sub Application_Startup()
Dim Ns As Outlook.NameSpace
Dim oFolder As Outlook.Folder
Set Ns = Application.GetNamespace("MAPI")
Dim objOwner
Set objOwner = Ns.CreateRecipient("my_Shared_Mailibox")
objOwner.Resolve
If objOwner.Resolved Then
Set oFolder = Ns.GetSharedDefaultFolder(objOwner, olFolderInbox)
Set colFolders = New Collection
processFolder oFolder
End If
Set Ns = Nothing
Set oFolder = Nothing
Exit Sub
eh:
End Sub
'function to create folder objects
Function GetFolderObject(foldr As Folder)
Dim rv As New clsFolder
rv.Init foldr
Set GetFolderObject = rv
End Function
'process all subfolders
Private Sub processFolder(ByVal oParent As Outlook.MAPIFolder)
Dim oFolder As Outlook.MAPIFolder
colFolders.Add GetFolderObject(oParent)
Dim oMail As Outlook.MailItem
For Each oMail In oParent.Items
'do sth with every email if necessary
Next
If (oParent.Folders.Count > 0) Then
For Each oFolder In oParent.Folders
processFolder oFolder
Next
End If
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

How to reference a subfolder of a shared mailbox?

I want to save Outlook attachments to a shared drive.
The below script saves attachments from my own inbox. I want to save attachments from a subfolder of a shared mailbox.
Private WithEvents InboxItems As Outlook.Items
Const attPath As String = "T:\London File3 Group\Client Reporting\Test\ABI Daily\"
Private Sub Application_Startup()
Dim outlookApp As Outlook.Application: Set outlookApp = Outlook.Application
Dim objectNS As Outlook.NameSpace: Set objectNS = outlookApp.GetNamespace("MAPI")
Set InboxItems = objectNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub InboxItems_ItemAdd(ByVal Item As Object)
Dim Msg As Outlook.MailItem: Set Msg = Item
Dim olDestFldr As Outlook.MAPIFolder
Dim myAttachments As Outlook.Attachments
Dim Filename As String
If Not TypeName(Msg) = "MailItem" Then Exit Sub
If (Msg.Subject Like "*Trade*") Or (Msg.Subject Like "*Trades*") Or _
(Msg.Subject Like "*Article 59*") Or (Msg.Subject Like "*Val*") Or _
(Msg.Subject Like "*Valuation*") Or (Msg.Subject Like "*Trading*") Or _
(Msg.Subject Like "*St James*") Then
Set myAttachments = Item.Attachments
Filename = myAttachments.Item(1).DisplayName
myAttachments.Item(1).SaveAsFile attPath & Filename
Msg.UnRead = False
End If
End Sub
Work with GetSharedDefaultFolder Method which Returns a MAPIFolder object that represents the specified default folder for the specified user. This method is used in a delegation scenario, where one user has delegated access to another user for one or more of their default folders
Example
Private WithEvents InboxItems As Outlook.Items
Const attPath As String = "T:\London File3 Group\Client Reporting\Test\ABI Daily\"
Private Sub Application_Startup()
Dim outlookApp As Outlook.Application: Set outlookApp = Outlook.Application
Dim objectNS As Outlook.NameSpace: Set objectNS = outlookApp.GetNamespace("MAPI")
Dim ShrdRecip As Outlook.Recipient: Set ShrdRecip = objectNS.CreateRecipient("0m3r#email.com")
Set InboxItems = GetSharedDefaultFolder(ShrdRecip, olFolderInbox).Items
End Sub
Edit
Example for subfolder
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Dim olNs As Outlook.NameSpace
Dim ShrdRecip As Outlook.Recipient
Dim Inbox As Outlook.MAPIFolder
Set olNs = Application.GetNamespace("MAPI")
Set ShrdRecip = olNs.CreateRecipient("0m3r#email.com")
Set Inbox = olNs.GetSharedDefaultFolder(ShrdRecip, olFolderInbox) _
.Folders("FolderName")
Set Items = Inbox.Items
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
If TypeOf Item Is Outlook.MailItem Then
Debug.Print Item.Subject ' print on Immediate window
End If
End Sub

Move Outlook incoming message to folder that starts with the same codes

I am trying to automate moving incoming messages to a designated subfolder in Outlook.
Messages that contain a projectnumber in the format P000.0000 should be moved to the Inbox's subfolder that starts with the same projectnumber.
The subfolders will be pre-created by hand, so the user can decide which projects to round up in a dedicated subfolder.
The folderstructure is Inbox>Actueel>P000.0000
The first bit, where incoming messages are checked works fine, but after that I get lost... Where it starts with For Each Folder In olFolderPrjcts
The error is on this line Set olFolder = objNS.GetDefaultFolder(olFolderInbox)
This is what I came up with so far:
Private WithEvents myOlItems As Outlook.Items
Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Dim olFolder As Outlook.MAPIFolder
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
Set olFolder = objNS.GetDefaultFolder(olFolderInbox)
Set myOlItems = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub myOlItems_ItemAdd(ByVal item As Object)
Dim Atts As Outlook.Attachments
Dim Props As Outlook.UserProperties
Dim Prop As Outlook.UserProperty
Dim PropName As String
PropName = "NumberAttachments"
Set Atts = item.Attachments
Set Props = item.UserProperties
Set Prop = Props.Find(PropName, True)
If Prop Is Nothing Then
Set Prop = Props.Add(PropName, olText, True)
End If
Dim olFolder As Outlook.MAPIFolder
Set olFolder = objNS.GetDefaultFolder(olFolderInbox)
Dim olFolderPrjcts
Set olFolderPrjcts = olFolder.Folders("actueel")
Prop.Value = Atts.Count
item.Save
Dim Msg As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Set Msg = item
For Each Folder In olFolderPrjcts
If Left(Msg.Subject, 9) = Left(Folder.Name, 9) Then
Msg.Move (Folder)
End If
Next
' DO SOMETHING TO NEWLY ARRIVED MESSAGE
' If Msg.Subject contains like P000.0000 AND
' folder exists that starts with P000.0000
' then move to that folder
End If
End Sub
Without Option Explicit the error is likely Run-time error '424': Object required.
With Option Explicit the error is likely Compile error: Variable not defined.
Option Explicit
' Tools | Options | Editor tab
' Checkbox "Require Variable Declaration"
Private Sub myOlItems_ItemAdd(ByVal Item As Object)
Dim objNS As Namespace ' <--
Dim olFolder As folder
Dim folder As folder
Dim olFolderPrjcts As folder
Dim Msg As MailItem
Set objNS = GetNamespace("MAPI") ' <--
Set olFolder = objNS.GetDefaultFolder(olFolderInbox)
Set olFolderPrjcts = olFolder.Folders("actueel")
If TypeName(Item) = "MailItem" Then
Set Msg = Item
For Each folder In olFolderPrjcts.Folders
If Left(Msg.subject, 9) = Left(folder.name, 9) Then
'Debug.Print Msg.subject
'Debug.Print folder.name
Msg.move folder ' <-- no brackets
Exit For
End If
Next
End If
End Sub

Iterate all email items in a specific Outlook folder

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