我从StackOverflow open收到了大约十个回复,但没有一个能很好地回答我的问题。
我已经在Excel VBA中为这个特定的项目创建了几个UserForms。(注意:我没有接受过正式的VBA编程培训,我所做的一切都是自学或抄袭别人的代码。)在与这些表单中的多个表单交互时,我希望用户能够访问命令,以便从公司的全球地址列表中选择用户名。通过表单上的命令按钮和以下函数,我可以做到这一点:
Public Function GetUsernameFromOutlook(sCap As String) As String
'fancy code to call Outlook dialog box to select names.
'Badresult is the default, gives username of operator if they try to:
' select more than one recipient
' cancel out of the dialog box
Dim olApp As Object ' Outlook.Application
Dim olDialog As Object ' Outlook.SelectNamesDialog
Dim hwnd As Long
Set olApp = CreateObject("Outlook.Application")
Set olDialog = olApp.Session.GetSelectNamesDialog
With olDialog
.Caption = sCap
.ForceResolution = True
.AllowMultipleSelection = False
.NumberOfRecipientSelectors = olShowTo
.ToLabel = "Select User"
If .Display = False Then GoTo BadResult
SetForegroundWindow (Excel.Application.hwnd)
If .Recipients.Count <> 1 Then GoTo BadResult
'Debug.Print .Recipients(1).Name
'Debug.Print .Recipients(1).Address
'Debug.Print .Recipients(1).AddressEntry.GetExchangeUser.Alias
GetUsernameFromOutlook = .Recipients.Item(1).AddressEntry.GetExchangeUser.Alias
End With
' hwnd = FindWindow(vbNullString, sCap & ": Global Address List")
Set olApp = Nothing
Set olDialog = Nothing
Exit Function
BadResult:
SetForegroundWindow (Excel.Application.hwnd)
GetUsernameFromOutlook = Environ("UserName")
End Function正如您所看到的,我尝试按照其他答案中的建议使用SetForegroundWindow和FindWindow API调用。但是在导致问题之前,代码甚至不会到达这些行。
If .Display = False这一行显示了Outlook中的SelectNamesDialog框,但因为我的UserForm是模式的(我想),所以它仍然是可见窗口。我被迫使用Alt-Tab切换到Outlook。然后,在选择名称或从Outlook对话框中取消后,我需要再次按Alt-Tab组合键才能返回到Excel。
此外,因为代码正在等待Outlook框的响应,所以没有进一步的代码执行,所以在我完成所有的Alt切换之前,甚至不会发生SetForegroundWindow。
发布的其他解决方案提到了使用对MSWord的调用,或者从电子表格中查找信息或保存到电子表格中。我正在尝试使用此调用来修改表单控件的标题或文本,例如命令按钮、文本框或文本标签。我只需要收集Outlook别名,因为我有另一个函数可以根据别名从Outlook收集其他选定的信息,因此别名保存在表单上的标签(看不见)中,并根据需要使用此另一个函数转换为全名、缩写或电子邮件地址。
到目前为止,一切都很好,我真的很想将这个界面发布给我的beta测试者,但我不想在每个人点击“选择名称”按钮后向他们解释使用Alt-Tab。他们会认为他们的计算机已锁定,并进行硬重新启动。(或者致电IT人员,他们将开始询问他们无法回答的问题。)
很抱歉,这个问题太长了,但我想包含尽可能多的信息。我肯定会有需要澄清的事情,所以请将您的问题发送给我作为回应,我会尽我最大的努力解释得更好。谢谢您抽时间见我。
发布于 2015-02-11 00:45:37
Outlook对象模型不允许您指定通讯簿对话框的父窗口-它将始终是Outlook。
在扩展的MAPI级别(C++或Delphi),您可以在调用IAddbook::Address时指定窗口句柄,但不能从VBA执行此操作。
如果可以选择使用Redemption,则可以在使用RDOSelectNames对象之前设置RDOSession.ParentWindow属性。
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
Session.ParentWindow = Excel.Application.hwnd
set ABDialog = Session.GetSelectNamesDialog
ABDialog.Display true发布于 2016-03-01 05:00:49
我刚刚在这上面花了一个晚上,所以即使这个帖子已经有一年之久了,它也应该会有所帮助。你应该试着使用:
"olApp.ActiveWindow.Activate“
它总结为这个完整的工作函数:
enter Public Function GetUsernameFromOutlook(sCap As String) As String
'fancy code to call Outlook dialog box to select names.
'Badresult is the default, gives username of operator if they try to:
' select more than one recipient
' cancel out of the dialog box
Dim olApp As Outlook.Application ' Outlook.Application
Dim olDialog As Outlook.SelectNamesDialog
Dim hwnd As Long
Set olApp = New Outlook.Application
Set olDialog = olApp.Session.GetSelectNamesDialog
'Set olDialog = new Outlook.Application
With olDialog
.Caption = sCap
'.ForceResolution = True
.AllowMultipleSelection = False
.NumberOfRecipientSelectors = olShowTo
.ToLabel = "Select User"
olApp.ActiveWindow.Activate
.display
If .Recipients.Count <> 1 Then GoTo BadResult
'Debug.Print .Recipients(1).Name
'Debug.Print .Recipients(1).Address
'Debug.Print .Recipients(1).AddressEntry.GetExchangeUser.Alias
GetUsernameFromOutlook = .Recipients.Item(1).AddressEntry
End With
Set olApp = Nothing
Set olDialog = Nothing
Exit Function
BadResult:
GetUsernameFromOutlook = "A voir ultérieurement"
End Function herehttps://stackoverflow.com/questions/28436827
复制相似问题