【问题标题】:Set focus back to the application window after showing userform显示用户表单后将焦点设置回应用程序窗口
【发布时间】:2015-03-18 12:21:05
【问题描述】:

当显示一个用户表单(运行其Show 方法)时,它不仅会显示在屏幕上,还会获得焦点(例如击键的目的地)。

说,用户窗体是一个定制的工具栏。它的ShowWorkbook_Open() 中触发,但表单本身相对很少使用,因此我们希望焦点在它出现后立即返回到主应用程序窗口。

不幸的是,SetFocus 方法似乎对应用程序对象无效。

那么这是怎么做到的呢?

我想我的例子的解决方案是在

Private Sub Workbook_Open()
    [...]
    UserForm1.Show

【问题讨论】:

    标签: vba excel focus userform


    【解决方案1】:

    我用这个:

    AppActivate Application.caption

    这会将焦点从用户窗体重置到您的 Excel 工作表。

    【讨论】:

    • 这似乎是我也尝试过的更通用的版本。也许ThisWorkbook.Application.Caption 将是最可靠的解决方案..
    • 这正是我所需要的。很有帮助!
    【解决方案2】:

    对我来说

    AppActivate ThisWorkbook.Application
    

    Show 语句之后似乎工作正常。

    其他情况

    AppActivate "Microsoft Excel"
    

    也可以。

    【讨论】:

    • IDK 为什么但现在这些停止工作了......所以明确欢迎进一步的答案!
    • 这在 64 位环境的 Excel 2016 中仍然适用于我。在用户表单代码中,我有Me.Show VBA.vbModeless,紧随其后的是AppActivate Excel.ThisWorkbook.Application.Caption。如果这对您不起作用,我的第一个想法是您没有使用无模式表单,或者代码中的某些内容在此 AppActivate 行之后将焦点返回到用户表单。为了进行测试,我建议在新的空白表单上的新工作簿中尝试。
    【解决方案3】:

    这有点棘手,但这是可以做到的。

    在子程序“Private Sub 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
    

    【讨论】:

    • 在真正感谢您的努力的同时,我认为 AppActivate 的真正设计目的是满足我在 Q 中的需要。VBA 帮助说:AppActivate 语句发生了变化指定应用程序或窗口的焦点,但不影响它是最大化还是最小化。"
    • @Greenberet AppActivate 是一个非常优雅的解决方案。注意:帮助还说:“如果没有完全匹配,任何标题字符串以title开头的应用程序都会被激活。”这是潜在危险的来源。只要您确定它从不在您的情况下是一个问题,AppActivate 绝对是它。
    【解决方案4】:

    其他答案中提到的AppActivate Application.Caption 和(更好的)AppActivate ActiveWindow.Caption 都在专注于应用程序窗口本身......但他们确实专注于实际的单元格/范围通常希望焦点所在的位置。为此,请使用:

    ActiveCell.Activate
    

    它的好处是不需要额外单击要返回焦点的工作表的单元格区域 - 额外单击可能会更改先前的选择。

    【讨论】:

      【解决方案5】:

      另一种形式是:

      AppActivate ThisWorkbook.Name
      

      【讨论】:

        【解决方案6】:

        我用 AppActivate ActiveWindow.Caption 因为 AppActivate Application.Caption 如果为同一个工作簿打开多个窗口,则可能会聚焦错误的窗口。

        【讨论】:

          【解决方案7】:

          作为这个精彩讨论的脚注,在某些情况下,您可以通过跳过对.Show 的调用来避免焦点问题,因此焦点从一开始就不会移动。以 Word 为例,如果您要更新无模式表单或对话框,只需更新所需区域并省略对 .Show 的调用,例如:

          Sub ShowProblems(ByVal ProbLoc)
              EditBox2.TextBox.Text = "Here is the problem location: " & ProbLoc
              ' not needed: EditBox2.Show vbModeless
          End Sub
          

          【讨论】:

            【解决方案8】:

            我为应用程序创建一个对象,例如Outlook,然后将WindowSate更改为最大化(OlMaximized),然后当我想移除焦点时我最小化(olMinimized)

            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
            

            【讨论】:

              【解决方案9】:
              Private Sub UserForm_Activate()
                  RefRangeIn.SetFocus
              End Sub
              

              它对我有用,在 excel 2013 VBA 中

              【讨论】:

                【解决方案10】:

                添加一个虚拟表单并添加如下代码:

                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
                

                【讨论】:

                  【解决方案11】:

                  我创建了一个带有用户表单的浮动菜单,并使用此代码使我的光标离开用户表单并跳转/聚焦回到我的工作表。它适用于每个命令按钮代码的末尾以及用户表单的启动代码。

                  AppActivate ThisWorkbook.Application

                  只需将上面的代码行放在任何命令按钮代码的“End Sub”行和初始显示用户窗体代码之前。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-01-24
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-11-11
                    相关资源
                    最近更新 更多