-
Notifications
You must be signed in to change notification settings - Fork 7
/
ListThreadFolders.frm
262 lines (207 loc) · 10.1 KB
/
ListThreadFolders.frm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
VERSION 5.00
Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} ListThreadFolders
Caption = "Select folder to move emails to"
ClientHeight = 3015
ClientLeft = 120
ClientTop = 465
ClientWidth = 11190
OleObjectBlob = "ListThreadFolders.frx":0000
StartUpPosition = 1 'CenterOwner
End
Attribute VB_Name = "ListThreadFolders"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Public Sub UserForm_Initialize()
GetConverstationInformation
End Sub
Public Sub GetConverstationInformation()
' Original code obtained from the following site (credit user TimO):
' https://stackoverflow.com/questions/29304844/outlook-2010-vba-to-save-selected-email-to-a-folder-other-emails-in-that-convers?rq=1
' Get root items in conversation
Dim host As Outlook.Application
Set host = ThisOutlookSession.Application
' Get the user's currently selected item
Set selectedItem = host.ActiveExplorer.Selection.item(1)
Debug.Print ("Selected item: " & selectedItem.ConversationTopic)
' Check to see that the item's current folder has conversations enabled
Dim parentFolder As Outlook.folder
Dim parentStore As Outlook.store
Set parentFolder = selectedItem.Parent
Set parentStore = parentFolder.store
If parentStore.IsConversationEnabled Then
' Try and get the conversation.
Dim theConversation As Outlook.conversation
Set theConversation = selectedItem.GetConversation
If Not IsNull(theConversation) Then
' Outlook provides a table object the contains all of the items in the conversation
Dim itemsTable As Outlook.table
Set itemsTable = theConversation.GetTable
' Get the Root Items
' Enumerate the list of items
' Then use a helper method and recursion to walk all the items in the conversation
Dim group As Outlook.SimpleItems
Set group = theConversation.GetRootItems
Dim obj As Object ' an email
Dim fld As Outlook.folder ' full path to the folder the email is in (\\AcountName\Folder)
Dim sfld As String ' path to the folder the email is in excluding the account name (\Folder)
Dim IsInListBox As Boolean
For Each obj In group
If TypeOf obj Is Outlook.MailItem Or TypeOf obj Is Outlook.AppointmentItem Or TypeOf obj Is Outlook.MeetingItem Then
' If ROOT item is an email, add it to ListBox1
Set fld = obj.Parent
FolderPathEncoded = Replace(fld.FolderPath, "%2F", "/")
Debug.Print ("FolderPathEncoded: " & FolderPathEncoded & " (" & TypeName(obj) & ")")
' Don't include generic folders
sfld = Mid(FolderPathEncoded, InStr(3, FolderPathEncoded, "\") + 1)
If (sfld <> "Inbox") And _
(sfld <> "Drafts") And _
(sfld <> "Sent Items") And _
(sfld <> "Calendar") And _
(sfld <> "Auto Replies") And _
(InStr(sfld, "Shared Data") = 0) Then
' Make IsInListBox true if folder has already been added
IsInListBox = False
For i = 0 To Me.ListBox1.ListCount - 1
If Me.ListBox1.Column(0, i) = FolderPathEncoded Then
IsInListBox = True
End If
Next
If (IsInListBox = False) Then
Me.ListBox1.AddItem FolderPathEncoded
Debug.Print ("Added " & FolderPathEncoded & " to ListBox")
End If
End If
Else
Debug.Print ("Skipping obj of type " & TypeName(obj))
End If
' Repeat the process if this email is also a root item
GetConversationDetails obj, theConversation
Next obj
Else
MsgBox "The currently selected item is not a part of a conversation."
End If
Else
MsgBox "The currently selected item is not in a folder with conversations enabled."
End If
' Display message box and/or move emails
If Me.ListBox1.ListCount = 0 Then
' Don't open the window
MsgBox ("No folders found")
End
End If
If Me.ListBox1.ListCount = 1 Then
' Move emails and don't open window
Call MoveMail(Me.ListBox1.Column(0, 0))
MsgBox ("Moved email(s) to " & Me.ListBox1.Column(0, 0))
End
End If
End Sub
Private Sub GetConversationDetails(anItem As Object, theConversation As Outlook.conversation)
' Original code obtained from the following site (credit user TimO):
' https://stackoverflow.com/questions/29304844/outlook-2010-vba-to-save-selected-email-to-a-folder-other-emails-in-that-convers?rq=1
' From the root items, find all the messages and add to ListBox1
Dim group As Outlook.SimpleItems
Set group = theConversation.GetChildren(anItem)
If group.Count > 0 Then
Debug.Print ("Getting conversation details...")
Dim obj As Object ' an email
Dim fld As Outlook.folder ' full path to the folder the email is in (\\AcountName\Folder)
Dim sfld As String ' path to the folder the email is in excluding the account name (\Folder) Dim i As Integer
Dim IsInListBox As Boolean
For Each obj In group
If TypeOf obj Is Outlook.MailItem Or TypeOf obj Is Outlook.AppointmentItem Or TypeOf obj Is Outlook.MeetingItem Then
' If CHILD item is an email, add it to ListBox1
Set fld = obj.Parent
FolderPathEncoded = Replace(fld.FolderPath, "%2F", "/")
Debug.Print (" FolderPathEncoded: " & FolderPathEncoded & " (" & TypeName(obj) & ")")
' Don't include generic folders
sfld = Mid(FolderPathEncoded, InStr(3, FolderPathEncoded, "\") + 1)
If (sfld <> "Inbox") And _
(sfld <> "Drafts") And _
(sfld <> "Sent Items") And _
(sfld <> "Calendar") And _
(sfld <> "Auto Replies") And _
(InStr(sfld, "Shared Data") = 0) Then
' Make IsInListBox true if folder has already been added
IsInListBox = False
For i = 0 To Me.ListBox1.ListCount - 1
If Me.ListBox1.Column(0, i) = FolderPathEncoded Then
IsInListBox = True
End If
Next
' Add folder to ListBox if IsInListBox is false
If IsInListBox = False Then
Me.ListBox1.AddItem FolderPathEncoded
Debug.Print (" Added " & FolderPathEncoded & " to ListBox")
End If
End If
Else
Debug.Print (" Skipping obj of type " & TypeName(obj))
End If
' Repeat the process if this email is also a root item
GetConversationDetails obj, theConversation
Next obj
End If
End Sub
Private Sub ListBox1_Click()
' Move mail to selected folder
Call MoveMail(Me.ListBox1.Value)
' Close UserForm
Unload Me
End Sub
Sub MoveMail(inputfolder As String)
' Original code obtained from the following site (credit Diane Poremsky):
' https://www.slipstick.com/outlook/macro-move-folder/
Dim objOutlook As Outlook.Application
Dim objNamespace As Outlook.NameSpace
Dim objSourceFolder As Outlook.MAPIFolder
Dim objDestFolder As Outlook.MAPIFolder
Dim objItems As MailItem
Set objOutlook = Application
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderDrafts)
Set objDestFolder = GetFolder(inputfolder)
For Each objItem In objOutlook.ActiveExplorer.Selection
' Move folder if destination is different than current
If objItem.Parent <> objDestFolder Then
objItem.Move objDestFolder
Debug.Print ("Moved '" & objItem.ConversationTopic & "' to '" & objDestFolder.name & "'")
Else
Debug.Print ("Skipped moving '" & objItem.ConversationTopic & "' to '" & objDestFolder.name & "' (same folder)")
End If
Next
Set objDestFolder = Nothing
End Sub
Function GetFolder(ByVal FolderPath As String) As Outlook.folder
' Original code obtained from the following site (credit users "office 365 dev account", "Office GSX", Kim Brandl - MSFT, JiayueHu):
' https://docs.microsoft.com/en-us/office/vba/outlook/how-to/items-folders-and-stores/obtain-a-folder-object-from-a-folder-path
' Convert folder path in form of "\\folder1\folder2\folder3" to a folder object
Dim TestFolder As Outlook.folder
Dim FoldersArray As Variant
Dim i As Integer
On Error GoTo GetFolder_Error
If Left(FolderPath, 2) = "\\" Then
FolderPath = Right(FolderPath, Len(FolderPath) - 2)
End If
' Convert folderpath to array
FoldersArray = Split(FolderPath, "\")
Set TestFolder = Application.Session.Folders.item(FoldersArray(0))
If Not TestFolder Is Nothing Then
For i = 1 To UBound(FoldersArray, 1)
Dim SubFolders As Outlook.Folders
Set SubFolders = TestFolder.Folders
Set TestFolder = SubFolders.item(FoldersArray(i))
If TestFolder Is Nothing Then
Set GetFolder = Nothing
End If
Next
End If
' Return the TestFolder
Set GetFolder = TestFolder
Exit Function
GetFolder_Error:
Set GetFolder = Nothing
Exit Function
End Function