Add a public Folder to my Favorite Folder - vba

I am looking for a VBA Script to automatically add a public folder to the "Favorites" folder in Outlook 365 (to add it as a GPO later). I have found multiple scripts such as this one:
' path to public folder; should be similar to
' "Public Folders\All Public Folders\Company\Sales"
strFolder = "\\Public Folders - gabriel.buehler#wingd.com\All Public Folders\Local Winterthur Holidays"
Call AddFolderToFavorites(strFolder, True)
Sub AddFolderToFavorites(strPath, AddToAddressBook)
Const olContactItem = 2
Set myFolder = GetFolder(strPath)
If Not myFolder Is Nothing Then
myFolder.AddToPFFavorites
' if contacts folder,
' optionally add new Favorite to OAB
If myFolder.DefaultItemType = olContactItem Then
If AddToAddressBook = True Then
strFavFolder = _
"Public Folders\Favorites\" & _
myFolder.Name
Set myFavFolder = GetFolder(strFavFolder)
If Not myFavFolder Is Nothing Then
myFavFolder.ShowAsOutlookAB = True
End If
End If
End If
End If
Set myFolder = Nothing
End Sub
Public Function GetFolder(strFolderPath)
On Error Resume Next
strFolderPath = Replace(strFolderPath, "/", "\")
arrFolders = Split(strFolderPath, "\")
Set objApp = CreateObject("Outlook.Application")
Set objNS = objApp.GetNamespace("MAPI")
Set objFolder = objNS.Folders.Item(arrFolders(0))
If Not objFolder Is Nothing Then
For I = 1 To UBound(arrFolders)
Set colFolders = objFolder.Folders
Set objFolder = Nothing
Set objFolder = colFolders.Item(arrFolders(I))
If objFolder Is Nothing Then
Exit For
End If
Next
End If
Set GetFolder = objFolder
Set colFolders = Nothing
Set objNS = Nothing
Set objApp = Nothing
End Function
To be honest: I have not used VBA before, so I don't know if the code itself is correct...but When I start to run the script, it always pops up a window where I should ad a "Macro Name":
When I enter In a macro name and press "run" it says "Compile Error Invalid Outside Procedure".
Can you tell me what I am doing wrong here?

You can manage the Outlook favorites group by accessing the NavigationPane module.
Dim mailModule as Outlook.MailModule
Set mailModule = Application.ActiveExplorer().NavigationPane.Modules.GetNavigationModule(Outlook.OlNavigationModuleType.olModuleMail)
Dim favGroup as Outlook.NavigationGroup
Set favGroup = ailModule.NavigationGroups.GetDefaultNavigationGroup(Outlook.OlGroupType.olFavoriteFoldersGroup)
favGroup.NavigationFolders.Add(objFolder)
Read more about that in the Add a Folder to the Favorite Folders Group article.
Also, you may find the Folder.AddToPFFavorites method which adds a Microsoft Exchange public folder to the public folder's Favorites folder helpful.

Related

On Error Resume Next to ignore Error 440 when attempting to create an existing folder

Step 1:
I want to make a folder, and if it fails (it may already exist), I want to ignore and move on.
Sub MakeFolder()
'declare variables
Dim outlookApp As Outlook.Application
Dim NS As Outlook.NameSpace
'set up folder objects
Set outlookApp = New Outlook.Application
Set outlookApp = New Outlook.Application
Set NS = outlookApp.GetNamespace("MAPI")
Set objOwner = NS.CreateRecipient("email#host.com")
objOwner.Resolve
Set outlookInbox = NS.GetSharedDefaultFolder(objOwner, olFolderInbox)
'make a folder, maybe
Dim newFolder
On Error Resume Next
Set newFolder = outlookInbox.Folders.Add("myNewFolder")
On Error GoTo -1
On Error GoTo 0
End Sub
I get an error:
If the folder doesn't exist, it creates it.
Step2:
I have a list of folders (about 60) that may change over time. Because of this, I'd like to run a script checking for new folders and then create them.
For Each fol In folders
On Error Resume Next
Set newFolder = outlookInbox.Folders.Add(fol)
If Err.Number <> 0 Then
On Error GoTo -1
Else:
Debug.Print fol & " created "
End If
On Error GoTo 0
Next ID
Same here, the outlookInbox.Folders.Add() throws errors regardless of the return next, if it can't create that folder.
Now that you fixed your IDE, you could use the following code
Option Explicit
Public Sub Example()
Dim olNs As Outlook.NameSpace
Set olNs = Application.GetNamespace("MAPI")
Dim Inbox As Outlook.Folder
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Dim SubFolder As Outlook.Folder
'// SubFolder Name
Dim FolderName As String
FolderName = "myNewFolder"
'// Check if folder exist else create one
If FolderExists(Inbox, FolderName) = True Then
Debug.Print "Folder Exists"
Set SubFolder = Inbox.Folders(FolderName)
Else
Set SubFolder = Inbox.Folders.Add(FolderName)
End If
End Sub
'// Function - Check folder Exist
Private Function FolderExists(Inbox As Folder, FolderName As String)
Dim Sub_Folder As MAPIFolder
On Error GoTo Exit_Err
Set Sub_Folder = Inbox.Folders(FolderName)
FolderExists = True
Exit Function
Exit_Err:
FolderExists = False
End Function

How to move messages from a specific account?

I have multiple accounts attached to Outlook 2010.
I want to move messages from a specific account, older than X days, to a .pst file for local storage.
I found scripts to move messages from the default inbox, but nothing on specifying an account.
I know you can specify an account when sending email using
Set OutMail.SendUsingAccount = Outlook.Application.Session.Accounts.Item(2)
but I can't find anything for looking into another account.
I've found the stores references for the folders (\Inbox and \Sent) and I know how to specify the days old. I have a script that works, but only in my primary account.
After some more searching and testing I came up with the following solution. This was actually from a 2009 post on stackoverflow here: Original VBA
It uses a public function to build the folder locations and a Subroutine to look for received dates older than 60 days and move those files to the specified locations.
The public function is:
Public Function GetFolder(strFolderPath As String) As MAPIFolder
Dim objNS As NameSpace
Dim colFolders As folders
Dim objFolder As MAPIFolder
Dim arrFolders() As String
Dim i As Long
On Error GoTo TrapError
strFolderPath = Replace(strFolderPath, "/", "\")
arrFolders() = Split(strFolderPath, "\")
Set objNS = GetNamespace("MAPI")
On Error Resume Next
Set objFolder = objNS.folders.Item(arrFolders(0))
If Not objFolder Is Nothing Then
For i = 1 To UBound(arrFolders)
Set colFolders = objFolder.folders
Set objFolder = Nothing
Set objFolder = colFolders.Item(arrFolders(i))
If objFolder Is Nothing Then
Exit For
End If
Next
End If
On Error GoTo TrapError
Set GetFolder = objFolder
Set colFolders = Nothing
Set objNS = Nothing
Exit_Proc:
Exit Function
TrapError:
MsgBox Err.Number & " " & Err.Description
End Function
The subroutine that does the actual work is below.
I added the Pass as Integer to allow the routine to work through two different source and destination folders. If I change the Sub name to Application_Startup it will run whenever outlook is started.
PST Folder Name\Archive-Inbox - PST folder name in Outlook with sub-folder
Email Account Name\Inbox - Account name in Outlook with sub-folder
Sub MoveOldEmail()
Dim oItem As MailItem
Dim objMoveFolder As MAPIFolder
Dim objInboxFolder As MAPIFolder
Dim i As Integer
Dim Pass As Integer
For Pass = 1 To 2
If Pass = 1 Then
Set objMoveFolder = GetFolder("PST Folder Name\Archive-Inbox")
Set objInboxFolder = GetFolder("Email Account Name\Inbox")
ElseIf Pass = 2 Then
Set objMoveFolder = GetFolder("PST Folder Name\Archive-Sent Items")
Set objInboxFolder = GetFolder("Email Account Name\Sent Items")
End If
For i = objInboxFolder.Items.Count - 1 To 0 Step -1
With objInboxFolder.Items(i)
''Error 438 is returned when .receivedtime is not supported
On Error Resume Next
If .ReceivedTime < DateAdd("d", -60, Now) Then
If Err.Number = 0 Then
.Move objMoveFolder
Else
Err.Clear
End If
End If
End With
Next
Next Pass
Set objMoveFolder = Nothing
Set objInboxFolder = Nothing
End Sub
Hope this helps someone else.

Define folder location

Working on a macro for Outlook 2007 which selects messages in a folder.
In example 1 and 2 below the customers folder is selected, then a specific customer folder is selected. The method to define the location seems clumsy. Is there a cleaner way to do this?
Right clicking on the sub-folder and selecting properties, the path shown is: "\mailbox-name\customers\customer-xyz". Referencing the path this way in a macro doesn't work. Is it possible to reference the folder location in a more direct manner?
Set olNamespace = olApp.GetNamespace("MAPI")
' Example-1, Select folder by name from default PST inbox
Set FolderKeep = _
olNamespace.GetDefaultFolder(olFolderInbox).Folders("customers").Folders("customer-XYZ")
' Example-2, Select folder by mailbox name/folder/subfolder
Set FolderKeep = _
olNamespace.Folders("mailbox-name").Folders("customers").Folders("customer-XYZ")
A method of pulling the folder out of a path is described here.
http://www.outlookcode.com/d/code/getfolder.htm
Private Function GetFolder(strFolderpath As String) As Folder
' The path argument needs to be in quotation marks and
' exactly match the folder hierarchy that the user sees in the Folder List.
'
' NOTE: If any folder name in the path string contains a "\" character,
' this routine will not work,
'
' As the developer do not use this. It hides errors.
'On Error GoTo GetFolder_Error
Dim objNS As Namespace
Dim objFolder As Folder
Dim arrFolders() As String
Dim colFolders As Folders
Dim i As Long
Dim uErrorMsg As String
' Remove leading slashes, if any
Do While Left(strFolderpath, 1) = "\"
'Debug.Print strFolderpath
strFolderpath = Right(strFolderpath, Len(strFolderpath) - 1)
Loop
Debug.Print strFolderpath
arrFolders() = Split(strFolderpath, "\")
Set objNS = GetNamespace("MAPI")
Set objFolder = objNS.Folders.Item(arrFolders(0))
If Not objFolder Is Nothing Then
For i = 1 To UBound(arrFolders)
Set colFolders = objFolder.Folders
Set objFolder = Nothing
Set objFolder = colFolders.Item(arrFolders(i))
If objFolder Is Nothing Then Exit For
Next
End If
Set GetFolder = objFolder
ExitRoutine:
Set colFolders = Nothing
Set objNS = Nothing
Set objFolder = Nothing
Exit Function
GetFolder_Error:
uErrorMsg = "Err.Number: " & Err.Number & vbCr & "Err.Description: " & Err.Description
MsgBox uErrorMsg
Set GetFolder = Nothing
Resume ExitRoutine
End Function
Private Sub GetFolder_Test()
Dim testFolder As Folder
Set testFolder = GetFolder("\mailbox-name\customers\customer-xyz")
If Not (testFolder Is Nothing) Then testFolder.Display
End Sub

Get MAPI Folder in Outlook from Folder Path

I am trying to use the function from on this page: http://www.outlookcode.com/d/code/getfolder.htm to use the folder path to navigate to a folder. (I will copy that code onto the bottom of this question--I used it as-is, unmodified at all.) The reason I need to use this is that the default inbox in Outlook is not the same as the inbox I need to be active. I know the path of the relevant inbox by right clicking on it and hit properties, and looking at location.
This is the code I use:
Set objOutlook = CreateObject("Outlook.Application", "localhost")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set Inbox = GetFolder("\\itadmin#email.org\inbox")
Debug.Print Inbox '<-- This fails
Set InboxItems = Inbox.Items '<-- This also fails
InboxItems.SetColumns ("SentOn")
This returns runtime error 91, Object variable or With block variable not set.
I have no idea what this means. If you could help me solve this error, that would be awesome, and if you have a way that I could avoid this problem entirely, that would be awesome also. Thanks!
Public Function GetFolder(strFolderPath As String)As MAPIFolder
' strFolderPath needs to be something like
' "Public Folders\All Public Folders\Company\Sales" or
' "Personal Folders\Inbox\My Folder"
Dim objApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Dim colFolders As Outlook.Folders
Dim objFolder As Outlook.MAPIFolder
Dim arrFolders() As String
Dim I As Long
On Error Resume Next
strFolderPath = Replace(strFolderPath, "/", "\")
arrFolders() = Split(strFolderPath, "\")
Set objApp = Application
Set objNS = objApp.GetNamespace("MAPI")
Set objFolder = objNS.Folders.Item(arrFolders(0))
If Not objFolder Is Nothing Then
For I = 1 To UBound(arrFolders)
Set colFolders = objFolder.Folders
Set objFolder = Nothing
Set objFolder = colFolders.Item(arrFolders(I))
If objFolder Is Nothing Then
Exit For
End If
Next
End If
Set GetFolder = objFolder
Set colFolders = Nothing
Set objNS = Nothing
Set objApp = Nothing
End Function
I found the answer. Turns out it's something stupid, as per usual :)
Set Inbox = GetFolder("\\itadmin#email.org\inbox")
needs to be
Set Inbox = GetFolder("itadmin#email.org/inbox")
. This fixes the problem. I figured I would leave this here in case anyone else has this problem, the solution is simply to follow the given format...
Just add this line...
strFolderPath = Replace(strFolderPath, "\\", "")
Apparently also needs this line:
strFolderPath = Replace(strFolderPath, "\", "/")
But after the previous line.
So, in context:
strFolderPath = Replace(strFolderPath, "\\", "")
strFolderPath = Replace(strFolderPath, "\", "/")

Moving Emails to Public Folder using Dynamic Paths

In our Corporate environment we have a Mailbox (not the default inbox) with many sub folders. We also have a Public Folder which is an exact mirror of the Mailbox folder structure.
I am trying to detect the path of a selected email and move that email to its mirrored folder in the Public Folders.
I would say 95% of this code is correct but I am left with an Outlook error message "Can't move the items."
The code is supposed to do the following:
1. detects the current folder of the selected email(s)
2. converts the MAPIFolder into a path string
3. shortens the string to remove the root Mailbox directory structure
4. adds the remaining string onto the root directory structure of the public folder
5. converts the resulting path back into a MAPIFolder
6. move the selected email(s) to the mirrored folder in the Public Folders
Sub PublicFolderAutoArchive()
Dim olApp As Object
Dim currentNameSpace As NameSpace
Dim wipFolder As MAPIFolder
Dim objFolder As MAPIFolder
Dim pubFolder As String
Dim wipFolderString As String
Dim Messages As Selection
Dim itm As Object
Dim Msg As MailItem
Dim Proceed As VbMsgBoxResult
Set olApp = Application
Set currentNameSpace = olApp.GetNamespace("MAPI")
Set wipFolder = Application.ActiveExplorer.CurrentFolder
Set Messages = ActiveExplorer.Selection
' Destination root directory'
' Tried with both "\\Public Folders" and "Public Folders" .. neither worked
pubFolder = "\\Public Folders\All Public Folders\InboxMirror"
' wipFolder.FolderPath Could be any folder in our mailbox such as:
' "\\Mailbox - Corporate Account\Inbox\SubFolder1\SubFolder2"
' however, the \\Mailbox - Corporate Account\Inbox\" part is
' static and never changes so the variable below removes the static
' section, then the remainder of the path is added onto the root
' of the public folder path which is an exact mirror of the inbox.
' This is to allow a dynamic Archive system where the destination
'path matches the source path except for the root directory.
wipFolderString = Right(wipFolder.FolderPath, Len(wipFolder.FolderPath) - 35)
' tried with and without the & "\" ... neither worked
Set objFolder = GetFolder(pubFolder & wipFolderString & "\")
If Messages.Count = 0 Then
Exit Sub
End If
For Each itm In Messages
If itm.Class = olMail Then
Proceed = MsgBox("Are you sure you want archive the message to the Public Folder?", _
vbYesNo + vbQuestion, "Confirm Archive")
If Proceed = vbYes Then
Set Msg = itm
Msg.Move objFolder
End If
End If
Next
End Sub
Public Function GetFolder(strFolderPath As String) As MAPIFolder
' strFolderPath needs to be something like
' "Public Folders\All Public Folders\Company\Sales" or
' "Personal Folders\Inbox\My Folder"
Dim objApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Dim colFolders As Outlook.Folders
Dim objFolder As Outlook.MAPIFolder
Dim arrFolders() As String
Dim I As Long
On Error Resume Next
strFolderPath = Replace(strFolderPath, "/", "\")
arrFolders() = Split(strFolderPath, "\")
Set objApp = Application
Set objNS = objApp.GetNamespace("MAPI")
Set objFolder = objNS.Folders.Item(arrFolders(0))
If Not objFolder Is Nothing Then
For I = 1 To UBound(arrFolders)
Set colFolders = objFolder.Folders
Set objFolder = Nothing
Set objFolder = colFolders.Item(arrFolders(I))
If objFolder Is Nothing Then
Exit For
End If
Next
End If
Set GetFolder = objFolder
Set colFolders = Nothing
Set objNS = Nothing
Set objApp = Nothing
End Function
Note: The mailbox above is just an example and is not the actual mailbox name. I used MsgBox to confirm the path string was being joined correctly with all appropriate back slashes and that the Right() function was getting what I needed from the source path.
I'm not sure, but should be something like?
set objApp = New Outlook.Application
instead of
set objApp = Application
From glancing at the code, it appears that your GetFolder() implementation doesn't like the double-backslash you're giving at the start of the path. There's even a comment indicating this at the start of the function. Try removing those two chars from the front of pubFolder.
Alternatively, you could alter GetFolder to permit them. A few lines like this should do the trick.
If Left(strFolderPath, 2) = "\\" Then
strFolderPath = Right(strFolderPath, Len(strFolderPath) - 2)
End If