【问题标题】:I need to swap any two telephone numbers in the Outlook ContactItem object我需要交换 Outlook ContactItem 对象中的任意两个电话号码
【发布时间】:2017-08-06 19:44:37
【问题描述】:

我编写了一些代码来整理 Outlook 中的联系人列表。

多年来,我在各个领域存储了“额外”的电话号码,现在我想移动它们。

特别是当我在手机字段中识别非手机号码和在非手机字段中识别手机号码时,我想交换它们。

但是,下面的代码不起作用;它不会出错,但一旦交换例程返回,电话号码就不会改变。

我认为是因为我对 ByRef 的使用不正确,或者类属性无法通过引用传递,或者类字符串属性以我无法理解的奇怪方式表现。

我已经尝试过 PriortySwitch Arg1 Arg2 Arg3 和 Call PrioritySwitch(Arg1,Arg2,Arg3)

即使有人可以确认它至少无法完成,我也不会浪费时间试图弄明白它。

Sub Whatever
  Dim Ns As Outlook.NameSpace
  Dim Contacts As Items
  Dim Contact As ContactItem

  Set Ns = Application.GetNamespace("MAPI")

  'use the default folder
  Set Contacts = Ns.GetDefaultFolder(olFolderContacts).Items.Restrict("[MessageClass]='IPM.Contact'")

  'do whatever
  On Error GoTo WTF

  For Each Item In Contacts
    If Item.Class = olContact Then
      Set Contact = Item
      With Contact
        ' Call SetCategories(Contact)
        '.MobileTelephoneNumber = FormatTel(.MobileTelephoneNumber)
        '.AssistantTelephoneNumber = FormatTel(.AssistantTelephoneNumber)
        '.Business2TelephoneNumber = FormatTel(.Business2TelephoneNumber)
        '.BusinessFaxNumber = FormatTel(.BusinessFaxNumber)
        '.BusinessTelephoneNumber = FormatTel(.BusinessTelephoneNumber)
        '.CallbackTelephoneNumber = Format(.CallbackTelephoneNumber)
        '.CarTelephoneNumber = FormatTel(.CarTelephoneNumber)
        '.CompanyMainTelephoneNumber = FormatTel(.CompanyMainTelephoneNumber)
        '.Home2TelephoneNumber = FormatTel(.Home2TelephoneNumber)
        '.HomeFaxNumber = FormatTel(.HomeFaxNumber)
        '.HomeTelephoneNumber = FormatTel(.HomeTelephoneNumber)
        '.OtherFaxNumber = FormatTel(.OtherFaxNumber)
        '.OtherTelephoneNumber = FormatTel(.OtherTelephoneNumber)
        '.PagerNumber = FormatTel(.PagerNumber)
        '.PrimaryTelephoneNumber = FormatTel(.PrimaryTelephoneNumber)
        '.RadioTelephoneNumber = FormatTel(.RadioTelephoneNumber)
        '.TTYTDDTelephoneNumber = FormatTel(.TTYTDDTelephoneNumber)

        ' prioritise
        PrioritySwitch .MobileTelephoneNumber, .BusinessTelephoneNumber, True
        PrioritySwitch .MobileTelephoneNumber, .Business2TelephoneNumber, True
        PrioritySwitch .MobileTelephoneNumber, .BusinessFaxNumber, True
        PrioritySwitch .MobileTelephoneNumber, .CompanyMainTelephoneNumber, True
        PrioritySwitch .MobileTelephoneNumber, .PrimaryTelephoneNumber, True
        PrioritySwitch .MobileTelephoneNumber, .AssistantTelephoneNumber, True
        PrioritySwitch .MobileTelephoneNumber, .CallbackTelephoneNumber, True
        PrioritySwitch .MobileTelephoneNumber, .CarTelephoneNumber, True
        PrioritySwitch .MobileTelephoneNumber, .CompanyMainTelephoneNumber, True
        PrioritySwitch .MobileTelephoneNumber, .Home2TelephoneNumber, True
        PrioritySwitch .MobileTelephoneNumber, .HomeTelephoneNumber, True
        PrioritySwitch .MobileTelephoneNumber, .OtherTelephoneNumber, True
        PrioritySwitch .MobileTelephoneNumber, .PagerNumber, True
        PrioritySwitch .MobileTelephoneNumber, .HomeFaxNumber, True
        PrioritySwitch .MobileTelephoneNumber, .OtherFaxNumber, True

        If Not .Saved Then .Save
      End With
    End If
  Next
  Exit Sub
  WTF:
    Debug.Print Contact
End Sub

Sub PrioritySwitch(ByRef Tel1 As String, ByRef Tel2 As String, mobileOnly As Boolean)
  Dim t1 As String
  Dim switchTel As Boolean

  switchTel = False

  'Logic code goes here
  switchTel = True

  If switchTel Then
    t1 = Tel1
    Tel1 = Tel2
    Tel2 = t1
  End If
End Sub

【问题讨论】:

    标签: vba outlook pass-by-reference


    【解决方案1】:

    当你这样做时......

    With Contact
        '...
        PrioritySwitch .MobileTelephoneNumber, .BusinessTelephoneNumber, True
    

    ...您正在调用Contact 对象的属性。这会将电话号码返回到内部堆栈变量。该内部堆栈变量是 ByRef 传递给您的 PrioritySwitch Sub 的内容。一旦它返回,堆栈变量就会被丢弃,因为您没有将它们分配给任何东西。这相当于...

    Dim stackVar1 As String
    stackVar1 = Contact.MobileTelephoneNumber
    Dim stackVar2 As String
    stackVar2 = Contact.BusinessTelephoneNumber
    PrioritySwitch stackVar1, stackVar2, True
    '...and then stackVar1 and stackVar2 disappear...
    

    ByRef 不能只是神奇地将过程连接到这样的属性 - 想象它们在 VBA 类中的样子,因为这与使用 COM 的属性时发生的情况非常接近对象。

    Public Property Let MobileTelephoneNumber(number As String)
        'Frobs whatever Outlook does to store the number.
    End Property
    
    Public Property Get MobileTelephoneNumber() As String
        'Frobs whatever Outlook does to retrieve the number.
    End Property
    

    也就是说,您可以使用CallByName 函数执行类似的操作,然后直接在您的Sub 中调用属性:

    Public Sub PrioritySwitch(target As ContactItem, propertyOne As String, _
                              propertyTwo As String, mobileOnly As Boolean)
        Tel1 = CallByName(target, propertyOne, VbGet)
        Tel2 = CallByName(target, propertyTwo, VbGet)
    
        '...code that sets switchTel
    
        If switchTel Then
          CallByName target, propertyOne, VbLet, Tel2
          CallByName target, propertyTwo, VbLet, Tel1
        End If
    End Sub 
    

    然后你的调用代码看起来更像这样(没有With 块 - 除非你有更多的工作要做Contact):

        ' prioritise
        PrioritySwitch Contact, "MobileTelephoneNumber", "BusinessTelephoneNumber", True
        PrioritySwitch Contact, "MobileTelephoneNumber", "Business2TelephoneNumber", True
        PrioritySwitch Contact, "MobileTelephoneNumber", "BusinessFaxNumber", True
        PrioritySwitch Contact, "MobileTelephoneNumber", "CompanyMainTelephoneNumber", True
        ' etc...
    

    【讨论】:

    • 感谢共产国际,
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    • 1970-01-01
    • 2021-07-17
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    相关资源
    最近更新 更多