How to run code on second inbox (shared account)? - vba

I move an email to a specific subfolder of the inbox as soon as it has been tagged with the tag "Invoice".
Private WithEvents objInboxFolder As Outlook.Folder
Private WithEvents objInboxItems As Outlook.Items
'Process inbox mails
Private Sub Application_Startup()
Set objInboxFolder = Outlook.Application.Session.GetDefaultFolder(olFolderInbox)
Set objInboxItems = objInboxFolder.Items
End Sub
'Occurs when changing item
Private Sub objInboxItems_ItemChange(ByVal Item As Object)
Dim objMail As Outlook.MailItem
Dim objTargetFolder As Outlook.Folder
If TypeOf Item Is MailItem Then
Set objMail = Item
'Move mails based on color category
If InStr(objMail.Categories, "Invoice") > 0 Then
Set objTargetFolder = Application.Session.GetDefaultFolder(olFolderInbox).Folders("Invoices").Folders("Uploaded")
objMail.Move objTargetFolder
End If
End If
End Sub
I have two mailboxes/accounts in Outlook. My personal email address as well as Accounting#company.com (used by multiple people).
How do I address the Accounting inbox?

You can use the Store.GetDefaultFolder method which 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.
So, you can enumerate stores in the Outlook profile and find the required one. For example, the following code shows how to iterate over all stores and folders in Outlook recursively:
Sub EnumerateFoldersInStores()
Dim colStores As Outlook.Stores
Dim oStore As Outlook.Store
Dim oRoot As Outlook.Folder
On Error Resume Next
Set colStores = Application.Session.Stores
For Each oStore In colStores
Set oRoot = oStore.GetRootFolder
Debug.Print (oRoot.FolderPath)
EnumerateFolders oRoot
Next
End Sub
Private Sub EnumerateFolders(ByVal oFolder As Outlook.Folder)
Dim folders As Outlook.folders
Dim Folder As Outlook.Folder
Dim foldercount As Integer
On Error Resume Next
Set folders = oFolder.folders
foldercount = folders.Count
'Check if there are any folders below oFolder
If foldercount Then
For Each Folder In folders
Debug.Print (Folder.FolderPath)
EnumerateFolders Folder
Next
End If
End Sub
You can check out the Store.DisplayName property to find the required store in the profile and then get the required inbox folder of the specific store in Outlook.

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

Auto download attachment PDF file with particular subject from a shared Outlook mailbox

is there any way to auto download attached pdf file from shared outlook mailbox to local folder using vba coding?.
You can use the SaveAsFile method of the Attachment class which saves the attachment to the specified path.
Sub SaveAttachment()
Dim myInspector As Outlook.Inspector
Dim myItem As Outlook.MailItem
Dim myAttachments As Outlook.Attachments
Set myInspector = Application.ActiveInspector
If Not TypeName(myInspector) = "Nothing" Then
If TypeName(myInspector.CurrentItem) = "MailItem" Then
Set myItem = myInspector.CurrentItem
Set myAttachments = myItem.Attachments
'Prompt the user for confirmation
Dim strPrompt As String
strPrompt = "Are you sure you want to save the first attachment in the current item to the Documents folder? If a file with the same name already exists in the destination folder, it will be overwritten with this copy of the file."
If MsgBox(strPrompt, vbYesNo + vbQuestion) = vbYes Then
myAttachments.Item(1).SaveAsFile Environ("HOMEPATH") & "\My Documents\" & _
myAttachments.Item(1).DisplayName
End If
Else
MsgBox "The item is of the wrong type."
End If
End If
End Sub
To find all items with a specific string in the subject line you need to use the Find/FindNext or Restrict methods of the Items class. Read more about them in the following articles:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder
Use the NameSpace.GetSharedDefaultFolder method to get a shared folder. It returns a Folder object that represents the specified default folder for the specified user. For example, the following VBA example uses the GetSharedDefaultFolder method to resolve the Recipient object representing Eugene, and then returns Eugene's shared default Calendar folder:
Sub ResolveName()
Dim myNamespace As Outlook.NameSpace
Dim myRecipient As Outlook.Recipient
Dim CalendarFolder As Outlook.Folder
Set myNamespace = Application.GetNamespace("MAPI")
Set myRecipient = myNamespace.CreateRecipient("Eugene Astafiev")
myRecipient.Resolve
If myRecipient.Resolved Then
Call ShowCalendar(myNamespace, myRecipient)
End If
End Sub
Sub ShowCalendar(myNamespace, myRecipient)
Dim CalendarFolder As Outlook.Folder
Set CalendarFolder = myNamespace.GetSharedDefaultFolder(myRecipient, olFolderCalendar)
CalendarFolder.Display
End Sub

Get Inbox associated with mailbox that is not the main mailbox

I'm trying to get the inbox of a specific email address where there is more than one address connected to the same Outlook.
I can only succeed if I check the main mailbox (the first listed in Outlook).
dim outlApp as Object
dim outlNsp as Object
dim outlMapp as Object
dim outlsubMapp as Object
dim Mappar as Object
outlApp = CreateObject("Outlook.Application")
outlNsp = outlApp.GetNamespace("MAPI")
outlMapp = outlNsp.Folders.item(Mail_username)
Mappar = outlMapp.Folders
outlsubMapp = Mappar.item(6)
'6 is olFolderInbox enum value
outlsubMapp = outlNsp.GetDefaultFolder(6)
'6 is olFolderInbox enum value
Inbox = outlsubMapp.Name
If I change Mail_username I still get the first email inbox folder.
This macro lists every store to which you have access and the top level folders which will include their Inboxes. It shows how to access stores and folders that are not defaults.
I am not sure if this is a complete answer but it will get you started. Try the macro then come back with any questions.
Sub ListStoresAndTopLevelFolders()
Dim FldrCrnt As Folder
Dim InxFldrChild As Long
Dim InxStoreCrnt As Long
Dim StoreCrnt As Folder
With Application.Session
For InxStoreCrnt = 1 To .Folders.Count
Set StoreCrnt = .Folders(InxStoreCrnt)
With StoreCrnt
Debug.Print .Name
For InxFldrChild = .Folders.Count To 1 Step -1
Set FldrCrnt = .Folders(InxFldrChild)
With FldrCrnt
Debug.Print " " & .Name
End With
Next
End With
Next
End With
End Sub
You can use the Store.GetDefaultFolder method which 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.
To get all stores in the profile you need to use the Stores property of the Namespace class:
Sub EnumerateFoldersInStores()
Dim colStores As Outlook.Stores
Dim oStore As Outlook.Store
Dim oRoot As Outlook.Folder
On Error Resume Next
Set colStores = Application.Session.Stores
For Each oStore In colStores
Set oRoot = oStore.GetRootFolder
Debug.Print (oRoot.FolderPath)
EnumerateFolders oRoot
Next
End Sub
Private Sub EnumerateFolders(ByVal oFolder As Outlook.Folder)
Dim folders As Outlook.folders
Dim Folder As Outlook.Folder
Dim foldercount As Integer
On Error Resume Next
Set folders = oFolder.folders
foldercount = folders.Count
'Check if there are any folders below oFolder
If foldercount Then
For Each Folder In folders
Debug.Print (Folder.FolderPath)
EnumerateFolders Folder
Next
End If
End Sub

How to create a top-level folder in my Outlook using vb.net - VB.NET, Outlook 2013

So as the title says, I am trying to create a top-level folder in my Outlook but I haven't got any success with it. I've read several tutorials and code snippets but non of them seem to be a success.
So now i Have this piece of code which creates a folder under the Inbox folder:
Dim objFolder As Outlook.MAPIFolder
Dim objOutlook As Outlook._Application
objOutlook = New Outlook.Application()
objFolder.Folders.Add("Some folder", Outlook.OlDefaultFolders.olFolderInbox)
The question is, how can I create the same folder but then as a top-level folder instead as a sub-folder of the inbox folder.
I already tried to do it like this:
objFolder.Folders.Add("Some folder") but this didn't work.
Top folders (root nodes in the navigation pane) are store. If you need to add a new store in the profile you can use the AddStoreEx method of the Namesapace class which adds a Personal Folders file (.pst) in the specified format to the current profile. See How to: Add or Remove a Store for more information.
In case if you need to create a top-level folder (at the same level with standard folders like Inbox and etc.) you can get the Parent folder object of the Inbox or any other default folder and add a new folder there. For example:
Dim objFolder As Outlook.MAPIFolder
Dim parentFolder as Outlook.MAPIFolder
Dim objOutlook As Outlook._Application
objOutlook = New Outlook.Application()
myNamespace = objOutlook.GetNamespace("MAPI")
objFolder = myNamespace.GetDefaultFolder(olFolderInbox)
parentFolder = objFolder.Parent
parentFolder.Folders.Add("Some folder", Outlook.OlDefaultFolders.olFolderInbox)
Also you may find the GetRootFolder method of the Store class helpful. It returns a Folder object representing the root-level folder of the Store. You can use the GetRootFolder method to enumerate the subfolders of the root folder of the Store. Unlike NameSpace.Folders which contains all folders for all stores in the current profile, Store.GetRootFolder.Folders allows you to enumerate all folders for a given Store object in the current profile.
Sub EnumerateFoldersInStores()
Dim colStores As Outlook.Stores
Dim oStore As Outlook.Store
Dim oRoot As Outlook.Folder
On Error Resume Next
Set colStores = Application.Session.Stores
For Each oStore In colStores
Set oRoot = oStore.GetRootFolder
Debug.Print (oRoot.FolderPath)
EnumerateFolders oRoot
Next
End Sub
Private Sub EnumerateFolders(ByVal oFolder As Outlook.Folder)
Dim folders As Outlook.folders
Dim Folder As Outlook.Folder
Dim foldercount As Integer
On Error Resume Next
Set folders = oFolder.folders
foldercount = folders.Count
'Check if there are any folders below oFolder
If foldercount Then
For Each Folder In folders
Debug.Print (Folder.FolderPath)
EnumerateFolders Folder
Next
End If
Private Sub CreateNewFolder()
Dim oApp As Outlook.Application = New Outlook.Application
Dim oNS As Outlook.NameSpace = oApp.GetNamespace("MAPI")
Dim InboxFolder As Outlook.MAPIFolder = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox)
Dim customFolder As Outlook.MAPIFolder
Try
customFolder = InboxFolder.Folders.Add("Vellaichamy", Outlook _
.OlDefaultFolders.olFolderInbox)
InboxFolder.Folders("Authorcode").Display()
Catch ex As Exception
MessageBox.Show("The following error occurred: " & ex.Message)
End Try
End Sub

Why can't I access subfolders of a shared mailbox?

My goal is to create a VBA script that fires when a new e-mail arrives to a shared mailbox and does the following things if the title contains specific text:
1. Moves the message to a specified subfolder
2. Saves all Excel attachments to a Desktop folder.
After doing considerable research I came up with the following code and pasted into ThisOutlookSession:
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Dim myOlApp As Outlook.Application
Dim myNms As Outlook.NameSpace
Dim myFolder As Outlook.MAPIFolder
Dim myitem As Object
Dim myRecipient As Outlook.Recipient
Dim myExplorer As Outlook.Explorer
Dim SharedFolder As Outlook.MAPIFolder
Dim oMoveTarget As Outlook.MAPIFolder
Set myOlApp = CreateObject("Outlook.Application")
Set myNms = myOlApp.GetNamespace("MAPI")
Set myFolder = myNms.GetDefaultFolder(olFolderInbox)
Set myExplorer = myOlApp.ActiveExplorer
Set myExplorer.CurrentFolder = myFolder
Set myRecipient = myNms.CreateRecipient("shared mailbox")
Set SharedFolder = myNms.GetSharedDefaultFolder(myRecipient, olFolderInbox)
Set oMoveTarget = SharedFolder.Folders("specific subfolder where messages should be moved")
Set Items = SharedFolder.Items
End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
Dim Msg As Outlook.MailItem
Dim att As Attachment
Dim FileName As String
Dim intFiles As Integer
Dim myOlApp As Outlook.Application
Dim myNms As Outlook.NameSpace
Dim myFolder As Outlook.MAPIFolder
Dim myitem As Object
Dim myRecipient As Outlook.Recipient
Dim myExplorer As Outlook.Explorer
Dim SharedFolder As Outlook.MAPIFolder
Dim oMoveTarget As Outlook.MAPIFolder
If TypeName(item) = "MailItem" Then
Set Msg = item
If InStr(1, item.Subject, "specific text in subject") > 0 Then
For Each att In item.Attachments
If InStr(att.DisplayName, ".xlsx") Then
FileName = "folderpath to desktop location\" & Trim(att.FileName)
att.SaveAsFile FileName
intFiles = intFiles + 1
End If
Next
item.Move oMoveTarget
End If
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
I get the following error message when I try to run the code manually (F5) or when Outlook is restarted:
Run-time error '-2147221233 (8004010f)':
The attempted operation failed.
An object could not be found.
The line where the running is stopped is when the specific subfolder (oMoveTarget) is set in Private Sub Application_Startup().
If I omit (or comment out) the reference to a subfolder, the script works: Excel attachments from incoming e-mails to the shared mailbox with a specific subject are saved.
I am allowed to access and run a script on a shared mailbox, but I am denied access to its subfolders.
Is "Download shared folders" check box checked on the Advanced tab of your Exchange account properties dialog?
Try to uncheck it.