我需要构建一个工具,允许用户从他的Outlook中选择一封电子邮件,这样我就可以将该电子邮件保存为.msg文件,或者将附件另外保存为文件。
我对可能是允许搜索/过滤电子邮件的最简单,最好的方法感到磕磕绊绊。我需要为用户提供一个至少与Outlook略有相似的视图(例如,文件夹应该是相同的顺序/层次结构。
Outlook对象模型是否有某种我可以调用的Explorer / Picker / Selection对话框,在用户选择电子邮件后会返回storeid和entryid?或者我需要自己动手吗?
我应该提一下,我已经知道如何保存电子邮件或附件,所以我的问题只是处理选择和过滤电子邮件。
仅供参考,我在使用Outlook 2007的MS Access 2007中对此进行编程。目标计算机具有2007或2010版本的Access和Outlook。
答案 0 :(得分:0)
链接到Outlook表很好。问题是Outlook不为每条消息提供唯一的ID,如果消息从一个文件夹移动到另一个文件夹,则其ID会更改。显然不是由了解数据库的人设计的。
更好的方法可能是创建在Outlook中运行的Outlook加载项,然后执行将信息发送到Access所需的任务。
答案 1 :(得分:0)
我很少使用Access进行编程,但是我在Outlook中移动了一些代码,将其破解了一段时间,似乎可以正常工作。这不是一个解决方案,但它应该告诉您如何访问所需的所有信息。
我有一个问题。 Set OutApp = CreateObject("Outlook.Application")
和Set OutApp = New Outlook.Application
都不会创建Outlook的新实例(如果已经打开)。所以Quit
关闭Outlook,无论它是否在宏开始之前打开。我建议你发一个关于这个问题的新问题;我相信有人知道如何判断Outlook是否已经打开,因此不会退出。
Outlook中的文件夹结构略显尴尬,因为顶级文件夹的类型为Folders
,而所有子文件夹的类型为MAPIFolder
。一旦你过去了,那就相当简单了。
以下代码包含函数GetListSortedChildren(ByRef Parent As MAPIFolder) As String
。此函数查找Parent的所有子项,并返回一个字符串,如“5,2,7,1,3,6,4”,它按名称按升序列出子项的索引。我会使用类似的东西通过按用户需要扩展节点来填充ListView。
我提供了一个子程序CtrlDsplChld()
,它按顺序控制所有文件夹的直接窗口的输出。我相信这应该为您提供足够的指导,以便开始访问文件夹层次结构。
子例程DsplChld(ByRef Parent As MAPIFolder, ByVal Level As Long)
包含用于查找带附件的第一条消息的代码。这将告诉您如何查看特定邮件的文件夹。
最后,CtrlDsplChld()
显示邮件的选定属性:Subject,To,HTMLBody和附件的显示名称。
希望这会有所帮助。
Option Compare Database
Option Explicit
Dim ItemWithMultipleAttachments As Outlook.MailItem
Sub CtrlDsplChld()
Dim ArrChld() As String
Dim ListChld As String
Dim InxAttach As Long
Dim InxChld As Long
Dim InxTopLLCrnt As Long
Dim OutApp As Outlook.Application
Dim TopLvlList As Folders
Set ItemWithMultipleAttachments = Nothing
Set OutApp = CreateObject("Outlook.Application")
'Set OutApp = New Outlook.Application
With OutApp
Set TopLvlList = .GetNamespace("MAPI").Folders
For InxTopLLCrnt = 1 To TopLvlList.Count
' Display top level children and their children
Call DsplChld(TopLvlList.Item(InxTopLLCrnt), 0)
Next
If Not ItemWithMultipleAttachments Is Nothing Then
With ItemWithMultipleAttachments
Debug.Print .Subject
Debug.Print .HTMLBody
Debug.Print .To
For InxAttach = 1 To .Attachments.Count
Debug.Print .Attachments(InxAttach).DisplayName
Next
End With
End If
.Quit
End With
Set OutApp = Nothing
End Sub
Sub DsplChld(ByRef Parent As MAPIFolder, ByVal Level As Long)
Dim ArrChld() As String
Dim InxChld As Long
Dim InxItemCrnt As Long
Dim ListChld As String
Debug.Print Space(Level * 2) & Parent.Name
If ItemWithMultipleAttachments Is Nothing Then
' Look down this folder for a mail item with an attachment
For InxItemCrnt = 1 To Parent.Items.Count
With Parent.Items(InxItemCrnt)
If .Class = olMail Then
If .Attachments.Count > 1 Then
Set ItemWithMultipleAttachments = Parent.Items(InxItemCrnt)
Exit For
End If
End If
End With
Next
End If
ListChld = GetListSortedChildren(Parent)
If ListChld <> "" Then
' Parent has children
ArrChld = Split(ListChld, ",")
For InxChld = LBound(ArrChld) To UBound(ArrChld)
Call DsplChld(Parent.Folders(ArrChld(InxChld)), Level + 1)
Next
End If
End Sub
Function GetListSortedChildren(ByRef Parent As MAPIFolder) As String
' The function returns "" if Parent has no children.
' If the folder has children, the functions returns "P,Q,R, ..." where
' P, Q, R and so on indices of the children of Parent in ascending
' order by name.
Dim ArrInxFolder() As Long
'Dim ArrFolder() As MAPIFolder
Dim InxChldCrnt As Long
Dim InxName As Long
Dim ListChld As String
If Parent.Folders.Count = 0 Then
' No children
GetListSortedChildren = ""
Else
'ReDim ArrName(1 To Parent.Folders.Count)
'For InxChldCrnt = 1 To Parent.Folders.Count
' ArrFolder(InxChldCrnt) = Parent.Folders(InxChldCrnt)
'Next
Call SimpleSortMAPIFolders(Parent, ArrInxFolder)
ListChld = CStr(ArrInxFolder(1))
For InxChldCrnt = 2 To Parent.Folders.Count
ListChld = ListChld & "," & CStr(ArrInxFolder(InxChldCrnt))
Next
GetListSortedChildren = ListChld
End If
End Function
Sub SimpleSortMAPIFolders(ArrFolder As MAPIFolder, _
ByRef InxArray() As Long)
' On exit InxArray contains the indices into ArrFolder sequenced by
' ascending name. The sort is performed by repeated passes of the list
' of indices that swap adjacent entries if the higher come first.
' Not an efficient sort but adequate for short lists.
Dim InxIACrnt As Long
Dim InxIALast As Long
Dim NoSwap As Boolean
Dim TempInt As Long
ReDim InxArray(1 To ArrFolder.Folders.Count) ' One entry per sub folder
' Fill array with indices
For InxIACrnt = 1 To UBound(InxArray)
InxArray(InxIACrnt) = InxIACrnt
Next
If ArrFolder.Folders.Count = 1 Then
' One entry list already sorted
Exit Sub
End If
' Each repeat of the loop moves the folder with the highest name
' to the end of the list. Each repeat checks one less entry.
' Each repeats partially sorts the leading entries and may result
' in the list being sorted before all loops have been performed.
For InxIALast = UBound(InxArray) To 1 Step -1
NoSwap = True
For InxIACrnt = 1 To InxIALast - 1
If ArrFolder.Folders(InxArray(InxIACrnt)).Name > _
ArrFolder.Folders(InxArray(InxIACrnt + 1)).Name Then
NoSwap = False
' Move higher entry one slot towards the end
TempInt = InxArray(InxIACrnt)
InxArray(InxIACrnt) = InxArray(InxIACrnt + 1)
InxArray(InxIACrnt + 1) = TempInt
End If
Next
If NoSwap Then
Exit For
End If
Next
End Sub