I have created a pst store where the folder structure will be managed by my addin.
Is it possible to remove or hide the "Deleted Items" and "Search Folders" folders ?
No, Outlook always recreates these folders even if you delete them.
To hide, see example on vba
Option Explicit
Private Sub Hide_Folders()
Dim Outlook_Folder As Outlook.folder
Dim oPA As Outlook.PropertyAccessor
Dim Prop_Name, Value, Folder_Type As String
Prop_Name = "http://schemas.microsoft.com/mapi/proptag/0x10F4000B"
Value = True ' hide
Set Outlook_Folder = Application.ActiveExplorer.CurrentFolder
Debug.Print Outlook_Folder.Name
Set oPA = Outlook_Folder.PropertyAccessor
oPA.SetProperty Prop_Name, Value
Set Outlook_Folder = Nothing
Set oPA = Nothing
End Sub
Related
I ran the following script to hide folders in outlook and I mistakenly hide my calendar
Option Explicit
Public Sub HideFolders()
Dim oFolder As Outlook.Folder
Dim oPA As Outlook.PropertyAccessor
Dim PropName, Value, FolderType As String
PropName = "http://schemas.microsoft.com/mapi/proptag/0x10F4000B"
Value = True
Set oFolder = Application.ActiveExplorer.CurrentFolder
Set oPA = oFolder.PropertyAccessor
oPA.SetProperty PropName, Value
Set oFolder = Nothing
Set oPA = Nothing
End Sub
I then tried the following script to recover my outlook calendar but it did not work
Option Explicit
Public Sub FindFolders()
Dim oFolder As Outlook.Folder
Dim oPA As Outlook.PropertyAccessor
Dim PropName, Value, FolderType As String
PropName = "http://schemas.microsoft.com/mapi/proptag/0x10F4000B"
Value = False
Set oFolder = Session.GetDefaultFolder(olFolderCalendar)
Set oPA = oFolder.PropertyAccessor
oPA.SetProperty PropName, Value
Set oFolder = Nothing
Set oPA = Nothing
End Sub
any assistance will be greatly appreciated
You can fix a problem like that without a script using OutlookSpy (I am its author) - click IMsgStore button, click "Open Folder", select the folder to open, double click the PR_ATTR_HIDDEN property to edit.
I use Outlook 365 on windows 10.
There are three calendars in the "My Calendars" group.
I would like to show all calendars at startup with the default calendar, Calendar 1, active using VBA.
To do this, I use the following VBA code, but there are two problems.
One problem is that a part of the code is redundant, which makes it time-consuming.
By default, only Calendar1 in My Calendars group is visible after startup.
To show all calendars, the code makes Calendar2 and Calendar3 visible.
After running these commands, Calendar3 is active.
To activate Calendar1 after startup, the code makes Calendar1 invisible and then visible.
I think, instead of this, it's an efficient way to use the command corresponding to check the checkbox of "My Calendars" in the navigation pane.
But I don't know how to do this.
The other problem is that, after startup using this macro, I can't switch day view and month view by shortcut keys, Cntl+Alt+1 and Cntl+Alt+2.
I think the way to check the check of "My Calendars" solves this problem
because I can switch these views by the shortcut keys when I manually check the checkbox.
So could you tell me the way to solve these problems?
Thank you in advance.
Private WithEvents g_Items As Outlook.Items
Private Sub Application_Startup()
Dim Ns As Outlook.NameSpace
Set Ns = Application.GetNamespace("MAPI")
Set g_Items = Ns.GetDefaultFolder(olFolderCalendar).Items
setupInitialDisplayCalendars
End Sub
Public Sub setupInitialDisplayCalendars()
Dim navModCal As CalendarModule
Dim navGroup As NavigationGroup
Set navModCal = ActiveExplorer.NavigationPane.Modules.GetNavigationModule(olModuleCalendar)
Set navGroup = navModCal.NavigationGroups.Item("My Calendars")
If Not (navGroup Is Nothing) Then
navGroup.NavigationFolders.Item("Calendar2").IsSelected = True
navGroup.NavigationFolders.Item("Calendar3").IsSelected = True
navGroup.NavigationFolders.Item("Calendar1").IsSelected = False
navGroup.NavigationFolders.Item("Calendar1").IsSelected = True
End If
End Sub
You can use the NavigationFolders object can be used to display calendars listed on the navigation page in Outlook.
Sub SelectCalendars()
Dim objPane As Outlook.NavigationPane
Dim objModule As Outlook.CalendarModule
Dim objGroup As Outlook.NavigationGroup
Dim objNavFolder As Outlook.NavigationFolder
Dim objCalendar As Folder
Dim objFolder As Folder
Dim i As Integer
Set Application.ActiveExplorer.CurrentFolder = Session.GetDefaultFolder(olFolderCalendar)
DoEvents
Set objCalendar = Session.GetDefaultFolder(olFolderCalendar)
Set objPane = Application.ActiveExplorer.NavigationPane
Set objModule = objPane.Modules.GetNavigationModule(olModuleCalendar)
With objModule.NavigationGroups
Set objGroup = .GetDefaultNavigationGroup(olMyFoldersGroup)
End With
For i = 1 To objGroup.NavigationFolders.Count
Set objNavFolder = objGroup.NavigationFolders.Item(i)
Select Case i
' Enter the calendar index numbers you want to open
Case 1, 3, 4
objNavFolder.IsSelected = True
' Set to True to open side by side
objNavFolder.IsSideBySide = False
Case Else
objNavFolder.IsSelected = False
End Select
Next
' set the view here
Set objPane = Nothing
Set objModule = Nothing
Set objGroup = Nothing
Set objNavFolder = Nothing
Set objCalendar = Nothing
Set objFolder = Nothing
End Sub
To change calendar folder view (day/week/month) you can use the view object:
Dim objViews As Views
Dim objView As View
Set objViews = Application.ActiveExplorer.CurrentFolder.Views
Set objView = objViews.Item("Calendar")
With objView
' Set the calendar view to show a
' single day.
.CalendarViewMode = olCalendarViewDay
End With
objView.Apply
The CalendarView.CalendarViewMode property returns or sets an OlCalendarViewMode that determines the current view mode of the CalendarView object.
Is there a method in VBA to achieve the same effect of right-clicking on a folder in the folder pane and selecting 'Sort Subfolders A to Z'?
As a comparison, the code below from Microsoft.com sorts Items in a folder; however, it does not appear that the .Sort method used in this code is available for the Folders object like it is for the Items object.
Sub SortByDueDate()
Dim myNameSpace As Outlook.NameSpace
Dim myFolder As Outlook.Folder
Dim myItem As Outlook.TaskItem
Dim myItems As Outlook.Items
Set myNameSpace = Application.GetNamespace("MAPI")
Set myFolder = myNameSpace.GetDefaultFolder(olFolderTasks)
Set myItems = myFolder.Items
myItems.Sort "[DueDate]", False
For Each myItem In myItems
MsgBox myItem.Subject & "-- " & myItem.DueDate
Next myItem
End Sub
Additionally, it does not appear that there are any methods available for moving folders in the tree.
Is more extensive code required to replicate the native 'Sort Subfolders A to Z' action with VBA?
Can this be achieved with PropertyAssessor and, if so, what is the proper syntax for setting the PR_SORT_POSITION property? For example, the code below results in an error, as commented in the code.
Sub Example()
Dim myProp As String
Dim myValue As Variant
Dim oFolder As Folder
Set oFolder = Application.Session.GetDefaultFolder(olFolderInbox)
myProp = "http://schemas.microsoft.com/mapi/proptag/0x30200102"
myValue = "FD7F"
oFolder.PropertyAssessor.SetProperty myProp, myValue 'Run-time error '438': Object doesn't support this property or method
End Sub
The Outlook object model doesn't provide any property or method to sort folders. You may find the NavigationPane object helpful. See Customizing the Navigation Pane for more information.
You can sort the folders in the Outlook UI by explicitly setting the PR_SORT_POSITION property on each subfolder - see Get folder list ordered as displayed
I posted my code here because this was high in Google results and all other threads were closed
https://answers.microsoft.com/en-us/outlook_com/forum/all/sorting-outlook-subfolders-z-a/9aef727c-510c-49e0-869d-4234373b71d7
https://answers.microsoft.com/en-us/outlook_com/forum/all/sort-order-of-subfolders/a3b55181-4f5a-43c1-82b3-94eb68a8407b
I've made custom VBA code to sort subfolders Z-A - it will load the folder order [unfortunately you still need to order it A-Z within outlook] and then reverse it so it is Z-A
I needed to quickly adjust a tonne of folders and couldn't find any code anywhere, so I quickly made the below to help patch the issue.
I didn't have the time to write lots of detail about how it works.
Known issues with the code:
It doesn't always sort the first folder. No idea why.
It doesn't seem to like it when you're looking at the list of subfolders - minimise it then run the code
This code is used to reverse the sorting of subfolders under Inbox, you'll need to adjust as required.
Sub sortZA()
Dim email_name: email_name = "email#emails.com" 'write the name of the mailbox as it appears in outlook
Dim objMainFolder As Outlook.Folder
Dim Folders As Outlook.Folders
Dim Folderx As Outlook.Folder
Dim sort_order, sort_order_b, arr
Set arr = CreateObject("System.Collections.ArrayList")
Set arr_sorted = CreateObject("System.Collections.ArrayList")
dim found_folder: found_folder=0
Set Folders = Application.ActiveExplorer.Session.Folders
For Each Folderx In Folders
If LCase(Folderx.Name) = LCase(email_name) Then
Set objMainFolder = Folderx.Folders("Inbox") 'adjust as required. Add more folders via .folders("name")
found_folder=1
End If
Next
if found_folder =0 then
msgbox "the email folder with the name '" & email_name & "' was not found"
exit sub
end if
Dim reloadFolder As Outlook.Folder
Dim propertyAccessor As Outlook.propertyAccessor
For Each Folderx In objMainFolder.Folders
' if there is an error, then there might not be any order data. Try reordering them manually. Also make sure loading the email as the main profile instead of as an additional mailbox.
'On Error Resume Next
Set propertyAccessor = Folderx.propertyAccessor
sort_order = propertyAccessor.BinaryToString(propertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x30200102"))
arr.Add Folderx.Name & "##~~##" & sort_order
arr_sorted.Add Folderx.Name & "##~~##" & sort_order
Next
arr.Sort 'keep A-Z (the original list from outlook isn't in A-Z order)
arr_sorted.Sort 'make A-Z
arr_sorted.Reverse 'make Z-A
Dim t, a, b, i, t2, a2, b2
i = 0
For Each arr_folder In arr
t = Split(arr_folder, "##~~##")
a = t(0) 'which folder name?
b = t(1) 'what is the original order? [should already be A-Z]
Set Folders = Application.ActiveExplorer.Session.Folders
For Each Folderx In Folders
'On Error Resume Next
If LCase(Folderx.Name) = LCase(email_name) Then
Set reloadFolder = Folderx.Folders("Inbox").Folders(a)
End If
Next
t2 = Split(arr_sorted(i), "##~~##")
a2 = t2(0) 'which folder name?
b2 = t2(1) 'what is the reversed order?
Set propertyAccessor = reloadFolder.propertyAccessor
propertyAccessor.SetProperty "http://schemas.microsoft.com/mapi/proptag/0x30200102", propertyAccessor.StringToBinary(b2)
i = i + 1
Next
End Sub
Additional Notes: I did try experimenting with applying ordering data manually. I couldn't get it to work properly. All the binary converting code wasn't producing the correct values, and I ended up using HEX(). Here is an example of what I was doing:
Dim custom_order As Long
custom_order = 15
For Each arr_folder In arr
'the array only contains a list of folder names.. we need to load the folder in outlook to process it again. The below line of code loads the main email inbox, then the subfolder from the array [different from the above code]
Set reloadFolder = Application.Session.GetDefaultFolder(olFolderInbox).Folders(arr_folder)
Set propertyAccessor = reloadFolder.propertyAccessor
hexval = Hex(custom_order)
propertyAccessor.SetProperty "http://schemas.microsoft.com/mapi/proptag/0x30200102", propertyAccessor.StringToBinary(hexval)
custom_order = custom_order + 1
Next
End Sub
I am attempting to add convenience when adding notes to emails in Outlook.
My plan is to take my current procedure, which adds the notes to the selected email (as an attachment), and have it call a procedure which will set a UserProperty on the MailItem object so that I can easily see which emails have notes attached by adding a custom column to my email list view.
From scouring the internet I have pieced together the following.
Option Explicit
Public Sub MarkHasNote()
Dim Selection As Outlook.Selection
Dim UserDefinedFieldName As String
Dim objProperty As Outlook.UserProperty
Dim objItem As MailItem
UserDefinedFieldName = "Note"
Set objItem = GetCurrentItem()
Set objProperty = objItem.UserProperties.Add(UserDefinedFieldName, Outlook.OlUserPropertyType.olYesNo, olFormatYesNoIcon)
objProperty.Value = True
End Sub
Function GetCurrentItem() As Object
Dim objApp As Outlook.Application
Set objApp = Application
On Error Resume Next
Select Case TypeName(objApp.ActiveWindow)
Case "Explorer"
Set GetCurrentItem = objApp.ActiveExplorer.Selection.Item(1)
Case "Inspector"
Set GetCurrentItem = objApp.ActiveInspector.CurrentItem
End Select
Set objApp = Nothing
End Function
I have set a breakpoint and checked the UserProperties of the MailItem. I see that the details are there and the value is set to "True". However, the email does not show the Yes/No icon in the "Note" column of the email pane of Outlook.
How do I get Outlook to show my user defined property value in the email pane when I add the column to the view?
A save is required for a selection. An Inspector item prompts for a save.
Private Sub MarkHasNote_DisplayTest()
' Add the UserProperty column with Field Chooser
' You can view the value toggling when you run through the code
Dim Selection As Selection
Dim UserDefinedFieldName As String
Dim objProperty As UserProperty
Dim objItem As mailItem
UserDefinedFieldName = "NoteTest"
Set objItem = GetCurrentItem()
Set objProperty = objItem.UserProperties.Add(UserDefinedFieldName, Outlook.OlUserPropertyType.olYesNo, olFormatYesNoIcon)
objProperty.Value = Not objProperty.Value
' Required for an explorer selection
objItem.Save
' For an inspector item there would be a prompt to save
' if not already done in the code
End Sub
I use the Application_ItemSend event to trigger actions on mails I send.
Under certain conditions the mail shall be moved to a new subfolder.
Since one can't move the mail before it is sent without jeopardizing the send, I copy the mail before sending and delete the original after.
Set myCopiedItem = objItem.Copy
myCopiedItem.Move olTempFolder
myCopiedItem.UnRead = False
myCopiedItem.SentOnBehalfOfName = olSession.CurrentUser
myCopiedItem.SendUsingAccount = olSession.Accounts(1)
'myCopiedItem.SenderName = olSession.CurrentUser
'myCopiedItem.SenderEmailAddress = olSession.CurrentUser.Address
objItem.DeleteAfterSubmit = True
I would like to have me as a sender on the copied mail.
I tried to set several different properties:
.SendOnBehalfOfName and .SendUsingAccount do not do what I am after.
.SenderName and .SenderEmailAddress showed to be "read only"
How can I avoid that the mail shows up in the folder without a sender?
Would this work for you:
Save the email in the Application_ItemSend event first:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Item.Save
MoveEmail Item, "\\Mailbox - Darren Bartrup-Cook\Inbox\Some Folder\Some Sub Folder"
End Sub
In a separate module (excuse MoveEmail being a function - originally it returned the EmailID of the moved email):
'----------------------------------------------------------------------------------
' Procedure : MoveEmail
' Author : Darren Bartrup-Cook
' Date : 03/07/2015
'-----------------------------------------------------------------------------------
Public Function MoveEmail(oItem As Object, sTo As String) As String
Dim oNameSpace As Outlook.NameSpace
Dim oDestinationFolder As Outlook.MAPIFolder
Set oNameSpace = Application.GetNamespace("MAPI")
Set oDestinationFolder = GetFolderPath(sTo)
oItem.Move oDestinationFolder
End Function
'----------------------------------------------------------------------------------
' Procedure : GetFolderPath
' Author : Diane Poremsky
' Original : http://www.slipstick.com/developer/working-vba-nondefault-outlook-folders/
'-----------------------------------------------------------------------------------
Function GetFolderPath(ByVal FolderPath As String) As Outlook.MAPIFolder
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
Firstly, Move is a function, not a sub - it returns the newly created item. The original must be immediately discarded.
set myCopiedItem = myCopiedItem.Move(olTempFolder)
Secondly, sender related properties are set only after the message is sent and moved to the Sent Items folder. One solution is to wait until the Items.ItemAdd event fires on the Sent Items folder and make a copy then - the sender properties will be set by that time.
In theory, you can set a dozen or so PR_SENDER_* and PR_SENT_REPRESENTING_* MAPI properties, but if I remember my experiments correctly, MailItem.PropertyAccessor.SetProperty will not let you set sender related properties. If using Redemption is an option (I am its author), it allows to set the RDOMail.Sender and RDOMail.SentOnBehalfOf properties to an instance of an RDOAddressEntry object (such as that returned by RDOSession.CurrentUser).