我有大约十个来自StackOverflow的回复,但没有一个回复我的问题。
我已在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-Tab切换之前,SetForegroundWindow
甚至都不会发生。
已发布的其他解决方案提到使用MSWord调用,或从电子表格中查找信息或保存到电子表格。我正在尝试使用此调用来修改表单控件的标题或文本,例如命令按钮或文本框或文本标签。我只需要收集Outlook别名,因为我有另一个功能,可以根据别名从Outlook收集其他选定的信息,因此别名保存在表单上的标签(看不见)并转换为全名,缩写或e使用此其他功能根据需要发送邮件地址。
到目前为止,一切都很好,我真的很想将这个界面发布给我的测试人员,但我不想在他们点击“选择名称”按钮后向所有人解释使用Alt-Tab 。他们会相信他们的计算机已经锁定并重新启动。 (或者致电IT部门,他们会开始提出他们无法回答的问题。)
我很抱歉这个问题太长了,但我希望尽可能多地提供相关信息。我确信我需要澄清一些事情,所以请在回复中将您的问题发给我,我会尽力解释。谢谢你的时间。
答案 0 :(得分:0)
Outlook对象模型不允许您指定通讯录对话框的父窗口 - 它始终是Outlook。
在扩展MAPI级别(C ++或Delphi)上,您可以在调用IAddbook::Address时指定窗口句柄,但不能从VBA执行此操作。
如果使用Redemption是一个选项,则可以在使用RDOSession对象之前设置RDOSelectNames。ParentWindow属性。
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
Session.ParentWindow = Excel.Application.hwnd
set ABDialog = Session.GetSelectNamesDialog
ABDialog.Display true
答案 1 :(得分:0)
我刚刚度过了一个晚上,所以即使这个帖子已经有一年了,也应该有所帮助。 你应该尝试使用:
“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 here