Установите фокус обратно в окно приложения после показа userform

при отображении userform (запуск его Show метод) он не только отображается на экране, но и принимает фокус (назначение, например, нажатия клавиш).

скажем, userform-это настраиваемая панель инструментов. Его Show пожары Workbook_Open() но сама форма используется относительно редко, поэтому мы хотим, чтобы фокус вернулся к главному окну приложения сразу после его появления.

к сожалению, кажется SetFocus метод недопустим для применения объекты.

так как же это делается?

Я полагаю, что решение для моего примера приходит после

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

8 ответов


Я использую этот :

AppActivate Application.caption

это сбрасывает фокус с пользовательской формы на лист Excel.


Это немного сложно, но это то, что можно сделать.

в подпрограмме "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 ThisWorkbook.Application

сразу после Show заявление, кажется, работает нормально.

в других случаях

AppActivate "Microsoft Excel"

также может быть ОК.


в качестве сноски к этому отличному обсуждению, в некоторых случаях вы можете избежать проблемы с фокусом, пропустив вызов .Show, поэтому фокус никогда не перемещается в первую очередь. Например, с слово, если вы обновляете форма диалоговое окно немодальное или просто обновить необходимую площадь и пропустить вызов .Show, например:

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

Я создаю объект для приложения, например Outlook, затем изменяю WindowSate на Maximized (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

Private Sub UserForm_Activate()
    RefRangeIn.SetFocus
End Sub

это работает для меня, в excel 2013 VBA


другая форма является:

AppActivate ThisWorkbook.Name

добавить фиктивную форму и добавить коды, как показано ниже:

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