如何根据Excel(VBA)中的值从Outlook通讯簿中提取

时间:2014-05-14 22:35:22

标签: excel vba outlook

我有以下代码可以使用(我在论坛上找到了它):

Public Sub GetUsers()
Dim myolApp As Outlook.Application
Dim myNameSpace As Namespace
Dim myAddrList As AddressList
Dim myAddrEntries As addressEntry
Dim AliasName As String
Dim i As Integer, r As Integer
Dim EndRow As Integer, n As Integer
Dim myStr As String, c As Range
Dim myPhone As String
'Dim propertyAccessor As Outlook.propertyAccessor  'This only works with 2007 and may help you out

Set myolApp = CreateObject("Outlook.Application")
Set myNameSpace = myolApp.GetNamespace("MAPI")
Set myAddrList = myNameSpace.addressLists("Global Address List")

Dim FullName As String, LastName As String, FirstName As String
Dim StartRow As Integer

EndRow = Cells(Rows.Count, 3).End(xlUp).Row

StartRow = InputBox("At which row should this start?", "Start Row", 4)

For Each c In Range("A" & StartRow & ":A" & CStr(EndRow))
    AliasName = LCase(Trim(c))
    c = AliasName
    Set myAddrEntries = myAddrList.addressEntries(AliasName)

    FullName = myAddrEntries.Name
    FirstName = Trim(Mid(FullName, InStr(FullName, "(") + 1, _
                    InStrRev(FullName, " ") - InStr(FullName, "(")))
    LastName = Right(FullName, Len(FullName) - InStrRev(FullName, " "))
    LastName = Left(LastName, Len(LastName) - 1)

    c.Offset(0, 1) = FirstName
    c.Offset(0, 2) = LastName
    c.Offset(0, 3) = FirstName & " " & LastName
Next c
End Sub

当我提供单个名称(第一个或最后一个)时,它会在地址簿中查找它,并返回找到的人的名字和姓氏。

我想提供此人的企业ID,让它查找然后返回其他信息(位置,电话号码等)。

我无法弄清楚如何做到这一点。首先,我不知道outlook如何只搜索Alias,据我所知,它只在局部变量中声明。此外,当我尝试提取其他信息时,例如:

HomeState = myAddrEntries.HomeState

我收到错误:对象不支持此属性或方法。我不知道该属性会被调用 - 我找不到任何在线文档,显示属性的命名方式(即使我搜索了MAPI docuemntation)。

所以,我的问题是 - 如何使用此代码按ID搜索并返回其他属性,如位置,数字等。另外 - 我如何概括该过程 - 是否有一个列表,这些字段名称被称为,有没有办法生成一个列表?

谢谢!

4 个答案:

答案 0 :(得分:9)

让我们看看这是否可以帮到你。我不是Outlook VBA的专家,但它大致相同,只是找到文档。

将此页加为书签:

http://msdn.microsoft.com/en-us/library/office/ff870566(v=office.14).aspx

具体来说,您可以查看AddressEntry对象的条目:

http://msdn.microsoft.com/en-us/library/office/ff870588(v=office.14).aspx

从那里你可以看到可用属性/方法的列表。我相信应该回答你的第二个问题,我收到一个错误:对象不支持这个属性或方法。我不知道该财产会被称为

Homestate不是AddressEntry对象的属性。

  

当我提供单个名称(第一个或最后一个)时,它会在地址簿中查找它,并返回找到的人的名字和姓氏。

不要指望这是100%可靠

我用6个名字对它进行了测试,其中4个正确。 3是罕见的姓氏。一个是一个全名,令人惊讶地返回了错误的结果。您的里程可能会有所不同。

这对任何大型组织都不起作用。如果您有一个小的地址列表,那么可能很容易根据简单的名/姓名字符串进行唯一解析。但除此之外,这是不可靠的。

您有几个问题:

  

我想提供此人的企业ID,让它查找,然后返回其他信息(位置,电话号码等)。

我认为这不是Outlook如何从别名中解析电子邮件地址。您需要引用一些外部数据库来执行类似的查询。

  

我不知道outlook如何知道只搜索Alias,据我所知,它只在局部变量中声明。

AliasName是示例代码中的局部变量,但是它从用户输入(例如,Excel电子表格中的单元格)中分配了一个值。因此,宏正在读取某些值并尝试根据地址簿解析它们。

正如我上面提到的,这只是一个简单字符串唯一解析为正确的个体的可能性。

  

此外,当我尝试提取其他信息时,例如:

HomeState = myAddrEntries.HomeState
     

我收到错误:对象不支持此属性或方法。我不知道该属性会被调用 - 我找不到任何在线文档,显示属性的命名方式(即使我搜索了MAPI docuemntation)。

可以有更好的解决方案吗?

是。是的,可以。

如果你在对象模型中挖掘,你会发现两个看起来很有前途的项目,GetContact方法返回ContactItem(遗憾的是这不是我们想要的),{{1} }返回GetExchangeUser。我认为这是你最接近你想要的,因为它包含你正在寻找的大部分信息。

http://msdn.microsoft.com/en-us/library/office/ff870767(v=office.14).aspx

我修改你的代码如下:

ExchangeUser

答案 1 :(得分:1)

要显着提高Outlook查找AliasName的可靠性,尤其是在大型组织中,我将删除姓氏和名字之后的所有内容,例如部门名称。只要没有选择共享确切名字和姓氏的联系人,这将非常有效。无需小写。更改此行:

Set myAddrEntries = myAddrList.addressEntries(AliasName)

进入:

' Let's cut off everything after "last name, firstname " 
' get position of second blank in string

Dim Pos As Long

Pos = InStr(1, AliasName, " ", vbTextCompare)
Pos = InStr(Pos + 1, AliasName, " ", vbTextCompare)

If Pos > 0 Then
    Set myAddrEntry = myAddrList.addressEntries(Mid(AliasName, 1, Pos - 1))
Else
    Set myAddrEntry = myAddrList.addressEntries(AliasName)
End If

这可能不是您问题的完整答案,但这仍然是解决方案的重要组成部分。

答案 2 :(得分:0)

直接获取微软代码并使其适应我的Excel工作表:

Sub DemoAE()

Dim colAL As outlook.AddressLists
Dim oAL As outlook.AddressList
Dim colAE As outlook.AddressEntries
Dim oAE As outlook.AddressEntry
Dim oExUser As outlook.ExchangeUser
Dim ws As Worksheet
Dim r As range
Set ws = application.ActiveWorkbook.Worksheets("Users")
Set r = ws.range("A2")
Set colAL = outlook.application.Session.AddressLists
TurnOff 'A function that turnsoff a bunch of memory hogging aspects of Excel when doing loops in sheets.

For Each oAL In colAL

'Address list is an Exchange Global Address List

If oAL.AddressListType = olExchangeGlobalAddressList Then
    Set colAE = oAL.AddressEntries
    For Each oAE In colAE
    If oAE.AddressEntryUserType = olExchangeUserAddressEntry Then
    Set oExUser = oAE.GetExchangeUser
        If oExUser.Alias <> "" And oExUser.PrimarySmtpAddress <> "" And oExUser.FirstName <> "" Then

            r = (oExUser.FirstName)
            r.Offset(0, 1) = (oExUser.LastName)
            r.Offset(0, 2) = (oExUser.Alias)
            r.Offset(0, 3) = (oExUser.PrimarySmtpAddress)
            If InStr(1, oExUser.Department, ",") <> 0 Then
                r.Offset(0, 4) = Left(oExUser.Department, InStr(1, oExUser.Department, ",") - 1)
            Else: r.Offset(0, 4) = oExUser.Department
            End If
        Set r = r.Offset(1, 0)
        End If
    End If
    Next

End If

Next
TurnOn 'A function that turns on a bunch of memory hogging aspects of Excel when not doing loops in sheets.

End Sub

答案 3 :(得分:0)

首先,要针对所有通讯录进行解析,请使用Namespace.CreateRecipient(例如Application.Session.CreateRecipient)/ Recipient.Resolve-如果返回true,Recipient.AddressEntry将(至少)包含有效的AddressEntry.NameAddress属性(请参阅MSDN上的AddressEntry对象)。如果AddressEntry.AddressEntryUserType属性为0olExchangeUserAddressEntry),则可以使用AddressEntry.GetExchangeUser方法返回ExchangeUser对象的实例。在您的情况下,您想要的属性是StateOrProvince

如果地址条目对应于“联系人”文件夹中的一项,则AddressEntry.AddressEntryUserType将是10olOutlookContactAddressEntry),并且您可以使用AddressEntry.GetContact()方法来获取相应ContactItem对象的实例。

请记住,如果存在多个匹配项,则Outlook对象模型将引发异常,除非您使用扩展MAPI(C ++或Windows XP),否则无法获得类似于Outlook中“重复名称”对话框的潜在匹配项列表。仅限Delphi)或Redemption(任何语言)。如果使用“兑现”是一个选项,它将公开RDOAddressBookResolveNameExRDOAddressListResolveNameEx方法,这些方法返回与整个通讯簿匹配的列表({{1 }})或仅是GAL容器(RDOSession.AddressBook.ResolveNameEx):

RDOSession.AddressBook.GAL.ResolveNameEx