当显示用户表单(运行其Show
方法)时,它不仅显示在屏幕上,而且还占据焦点(例如击键的目标)。
比如说,用户表单是一个定制的工具栏。它的Show
在Workbook_Open()
中触发,但表单本身的使用相对较少,因此我们希望焦点在其出现后立即返回到主应用程序窗口。
不幸的是,似乎SetFocus
方法对应用程序对象无效。
那么这是怎么做到的呢?
我想我的例子的解决方案是在之后
Private Sub Workbook_Open()
[...]
UserForm1.Show
我使用这个:
AppActivate Application.caption
这会将焦点从用户窗体重置为 Excel 工作表。
对我来说
AppActivate ThisWorkbook.Application
在Show
声明之后似乎工作正常。
在其他情况下
AppActivate "Microsoft Excel"
也可能没问题。
其他答案中提到的AppActivate Application.Caption
和(更好的)AppActivate ActiveWindow.Caption
都专注于应用程序窗口本身......但他们不关注人们通常希望焦点的实际单元格/范围。为此,请使用:
ActiveCell.Activate
这样做的好处是不需要额外单击要返回焦点的工作表单元格区域 - 额外的单击可能会更改以前的选择。
这有点棘手,但这是可以做的。
在子例程"私有子UserForm_Initialize()"中,将其添加为最后一行:
Private Sub UserForm_Initialize()
. . . . . . . . . .
Application.OnTime Now(), "MoveFocusToWorksheet"
End Sub
在任何通用代码模块中(如果没有,请添加一个),声明一个 API 函数:
Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
在任何通用代码模块(当然,可以是带有 API 声明的代码模块)中,添加以下子例程:
Public Sub MoveFocusToWorksheet()
Dim Dummy As Long
ThisWorkbook.Worksheets("Sheet1").Activate
' "Sheet1" here is the tab name of the sheet you want to move focus to. _
Or simply use then: With shtABC.Activate _
where "shtABC" being the worksheet's CodeName, _
same as ThisWorkbook.Worksheets("Sheet1").CodeName, _
same as the sheets module name showing in the Project Explorer panel.
Dummy = SetForegroundWindow(Application.hwnd)
End Sub
我为应用程序创建一个对象,例如 Outlook,然后将 WindowSate 更改为最大化(OlMaximized),然后当我想删除焦点时,我最小化(ol最小化)
Set OutlookObj = GetObject(, "Outlook.Application")
OutlookObj.ActiveExplorer.WindowState = olMinimized
OutlookObj.ActiveExplorer.WindowState = olMaximized
或者,您可以从应用程序内部更改状态,也可以更改其位置和大小等,有关更多信息,请参阅:https://msdn.microsoft.com/en-us/library/office/ff838577.aspx
Application.WindowState = xlMaximized
另一种形式是:
AppActivate ThisWorkbook.Name
我使用 AppActivate ActiveWindow.Caption因为 AppActivate Application.Caption如果为同一工作簿打开多个窗口,则可以聚焦错误的窗口。
作为这个优秀讨论的脚注,在某些情况下,您可以通过跳过对.Show
的调用来避免焦点问题,因此焦点永远不会首先移动。 例如,对于 Word,如果要更新无模式窗体或对话框,只需更新所需区域并省略对 .Show
的调用,例如:
Sub ShowProblems(ByVal ProbLoc)
EditBox2.TextBox.Text = "Here is the problem location: " & ProbLoc
' not needed: EditBox2.Show vbModeless
End Sub
Private Sub UserForm_Activate()
RefRangeIn.SetFocus
End Sub
它对我有用, 在 excel 2013 VBA 中
添加一个虚拟表单并添加代码,如下所示:
Private Sub SomeButton_Click()
frm_Dummy.Show vbModeless
Unload frm_Dummy
End Sub
或
Sub SomeSub()
frm_Some.Show vbModeless
frm_Dummy.Show vbModeless
Unload frm_Dummy
End Sub
我创建了一个带有用户窗体的浮动菜单,并使用此代码使光标离开用户窗体并跳转/聚焦回工作表。它在每个命令按钮代码的末尾工作,也适用于用户窗体的启动代码。
应用程序激活此工作簿.应用程序
只需将上面的代码行放在任何命令按钮代码的"结束子"行和初始显示用户表单代码之前即可。