Вопрос или проблема
Я организую все свои сообщения в Outlook в виде бесед. Я ищу функцию для перемещения текущего выбранного сообщения(ий) из входящих в соответствующие папки.
Например, если у меня есть письмо с темой “Еженедельный отчет о статусе”, которое было помещено в папку “Инженерия”, и я получаю ответ во входящих, я хотел бы запустить макрос и переместить ответ в папку “Инженерия”.
Я использую Outlook в Microsoft Office Professional Plus 2010.
Моя первая попытка решения проблемы работает в какой-то степени, но я хотел бы:
- Добавить функциональность для объектов, не являющихся MailItem;
- Упорядочить цикл
For Each
, сначала проверяя, указаны ли все корневые элементы для беседы в одной и той же таблице. Если нет, я хотел бы предложить пользователю выбрать нужную папку через диалоговое окно.
Вот моя текущая попытка:
Sub moveMailToConversationFolder()
Dim olNs As NameSpace
Dim Inbox As Outlook.MAPIFolder
Dim selectedItem As Object
Dim item As Outlook.mailItem ' Почтовый элемент
Dim folder As Outlook.MAPIFolder ' Папка текущего элемента
Dim conversation As Outlook.conversation ' Получить беседу
' Dim ItemsTable As Outlook.table ' Объект таблицы беседы
Dim mailItem As Object
Dim mailparent As Object
Set olNs = Application.GetNamespace("MAPI")
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
' On Error GoTo MsgErr
' // Должен быть выбран элемент.
Set selectedItem = Application.ActiveExplorer.Selection.item(1)
' // Если элемент = MailItem.
If TypeOf selectedItem Is Outlook.mailItem Then
Set item = selectedItem
Set conversation = item.GetConversation
If Not IsNull(conversation) Then
' Set ItemsTable = conversation.GetTable
' MsgBox conversation.GetRootItems.Count
For Each mailItem In conversation.GetRootItems ' Элементы в беседе.
If TypeOf mailItem Is Outlook.mailItem Then
Set folder = mailItem.Parent
item.move GetFolder(folder.FolderPath)
End If
Next
End If
End If
End Sub
Function GetFolder(ByVal FolderPath As String) As Outlook.folder
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
'Преобразовать путь к папке в массив
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
'Вернуть TestFolder
Set GetFolder = TestFolder
Exit Function
GetFolder_Error:
Set GetFolder = Nothing
Exit Function
End Function
Вот похожий скрипт, который может помочь.
Мой случай использования немного отличается – я вручную выбираю элементы в настраиваемом представлении, а затем запускаю скрипт с кнопки на панели инструментов. (Я обнаружил, что беседы плохо отслеживаются, плюс иногда беседа расходится на разные проекты.)
Option Explicit
Option Base 0
Public Sub MoveToFirstFolder()
Dim oNamespace As Outlook.NameSpace, oSelection As Outlook.Selection
Dim oFolder As Outlook.MAPIFolder
Dim oItem As Object, i As Integer
Set oNamespace = Application.GetNamespace("MAPI")
Set oSelection = oNamespace.Application.ActiveExplorer.Selection
If oSelection.Count < 2 Then Exit Sub
Set oFolder = getFirstNonDefaultFolder(oSelection)
If oFolder Is Nothing Then Exit Sub
' перемещение элементов
For i = 1 To oSelection.Count
Set oItem = oSelection.Item(i)
If Not oItem.Parent = oFolder Then
oSelection.Item(i).Move oFolder
End If
Next i
End Sub
Private Function getFirstNonDefaultFolder(oSelection As Outlook.Selection) As Outlook.Folder
Dim oItem As Object
Dim oFolder As Outlook.Folder
Dim i As Integer
' получить папку
For i = 1 To oSelection.Count
Set oFolder = oSelection.Item(i).Parent
Debug.Print ">" & oFolder.FullFolderPath
If Not isDefaultFolder(oFolder) Then
Set getFirstNonDefaultFolder = oFolder
Exit Function
End If
Next i
End Function
Private Function isDefaultFolder(oFolder As Outlook.Folder) As Boolean
Dim oNamespace As Outlook.NameSpace
Dim defaultFolders, fldrNum
isDefaultFolder = False
defaultFolders = Array( _
olFolderInbox, olFolderSentMail, _
olFolderDrafts, _
olFolderDeletedItems, olFolderJunk, _
olFolderOutbox, _
olFolderCalendar, _
olFolderContacts, olFolderSuggestedContacts, _
olFolderNotes, _
olFolderTasks, olFolderToDo, _
olFolderJournal, _
olFolderConflicts, olFolderLocalFailures, olFolderServerFailures, olFolderSyncIssues, _
olFolderManagedEmail, olPublicFoldersAllPublicFolders _
)
Set oNamespace = Application.GetNamespace("MAPI")
On Error Resume Next ' Не существующие стандартные папки вызывают ошибки
For Each fldrNum In defaultFolders
If oFolder = oNamespace.GetDefaultFolder(fldrNum) Then
If Err.Number Then
Err.Clear
Else
isDefaultFolder = True
Exit Function
End If
End If
Next fldrNum
End Function
Ответ или решение
Конечно, вот полное решение задачи перемещения выбранных сообщений в соответствующие папки обсуждений в Outlook с использованием VBA.
Полный код для функции и макроса
Option Explicit
Sub MoveMailToConversationFolder()
Dim olNs As Outlook.NameSpace
Dim Inbox As Outlook.MAPIFolder
Dim selectedItems As Outlook.Selection
Dim item As Object
Dim conversation As Outlook.Conversation
Dim rootItems As Outlook.Items
Dim itemFolder As Outlook.MAPIFolder
Dim targetFolder As Outlook.MAPIFolder
Set olNs = Application.GetNamespace("MAPI")
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Set selectedItems = Application.ActiveExplorer.Selection
If selectedItems.Count < 1 Then Exit Sub
Dim firstFolderPath As String
Dim allSameFolder As Boolean
allSameFolder = True
Dim firstFolder As Outlook.MAPIFolder
Set item = selectedItems.Item(1)
' Получаем папку первого выбранного элемента
Set firstFolder = item.Parent
firstFolderPath = firstFolder.FolderPath
' Проверка всех выбранных элементов на соответствие папке
For Each item In selectedItems
If Not item.Parent.FolderPath = firstFolderPath Then
allSameFolder = False
Exit For
End If
Next item
' Если все элементы в одной папке, перемещаем их
If allSameFolder Then
Set conversation = selectedItems.Item(1).GetConversation
If Not conversation Is Nothing Then
Set rootItems = conversation.GetRootItems
For Each item In rootItems
If TypeOf item Is Outlook.MailItem Then
Set itemFolder = item.Parent
targetFolder = GetFolder(itemFolder.FolderPath)
If Not targetFolder Is Nothing Then
For Each selectedItem In selectedItems
If TypeOf selectedItem Is Outlook.MailItem Then
selectedItem.Move targetFolder
End If
Next selectedItem
End If
End If
Next item
End If
Else
MsgBox "Выбранные сообщения находятся в разных папках. Пожалуйста, выберите сообщения из одной папки.", vbExclamation
End If
End Sub
Function GetFolder(ByVal FolderPath As String) As Outlook.Folder
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
' Преобразование пути к папке в массив
FoldersArray = Split(FolderPath, "\")
Set TestFolder = Application.Session.Folders.Item(FoldersArray(0))
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
Exit Function
End If
Next
' Возвращаем найденную папку
Set GetFolder = TestFolder
Exit Function
GetFolder_Error:
Set GetFolder = Nothing
End Function
Объяснение кода
-
Основной макрос
MoveMailToConversationFolder
:- Инициализирует необходимые объекты для работы с Outlook.
- Получает текущее выбранное сообщение или сообщения.
- Проверяет, находятся ли все выбранные сообщения в одной папке. Если нет, выводится сообщение об ошибке.
- Если все сообщения находятся в одной папке, программа извлекает корневые элементы беседы и перемещает все выбранные сообщения в соответствующую папку.
-
Функция
GetFolder
:- Принимает путь к папке и возвращает объект папки. Она обрабатывает ошибки и проверяет, существует ли запрашиваемая папка.
Замечания
- Убедитесь, что в VBA установлены соответствующие ссылки на библиотеку Outlook.
- При использовании макроса, выбирайте сообщения из одной папки, чтобы избежать ошибок.
- Если какие-либо сообщения не являются элементами почты, они будут проигнорированы.
Этот код должен решить вашу проблему, позволяя эффективно управлять сообщениями Outlook в соответствии с их разговорами. Если у вас есть дополнительные вопросы или нужно внести изменения, не стесняйтесь обращаться.