vba在打开时显示userform,隐藏工作表,但保留任务栏图标

时间:2017-03-06 11:49:22

标签: excel vba excel-vba

我有一个在打开工作簿时打开的用户窗体。 Excel也是隐藏的,因此用户表单就是向用户显示的全部内容。

Private Sub Workbook_Open()
Application.Visible = False
UserForm1.Show vbModeless
End Sub

但是,这也隐藏了任务栏上的Excel图标,因此当用户点击远离用户窗体时,除非使用alt + tab或关闭/最小化用户窗体前面的其他窗口,否则他们无法返回到用户窗体。我不希望用户这样做,有些甚至可能尝试再次打开表单(假设它已关闭),导致重新打开提示和错误,我不想要。

基本上,我需要在任务栏上为用户表单添加一个图标。

关闭用户窗体后,我就让它关闭

Unload UserForm1
Application.Quit

我在互联网上发现的这个问题的例子并没有完全达到我想做的目的。 将窗体更改为最小化并打开为模式可以将图标保留在任务栏中,而不是让用户编辑工作表

Application.WindowState = xlMinimized
UserForm1.Show (1)

但是这有两个问题.....第一 - 用户形态没有成为焦点,第二 - 用户可以点击任务栏图标,工作表现在可以在用户形态后面看到,这不是什么我能做什么。

3 个答案:

答案 0 :(得分:0)

而不是隐藏应用程序最小化工作簿:

ThisWorkbook.Windows(1).WindowState = xlMinimized

答案 1 :(得分:0)

我在开发Excel-Visio应用程序时花了相当多的时间来完成这项任务并面临同样的问题(隐藏了Visio / Excel和VBA编辑器上方的Excel表单 - 但是用户可以轻松地丢失焦点而且只能返回 - Alt-Tabbing)。同样的问题!

我解决这个问题的算法是这样的(Userform类中的所有代码):

Private Sub UserForm_Initialize()

    'some init's above
    ToggleExcel         'Toggle excel, all windows are hidden now!
    ActivateVisio       'Visio fired and on top
    SetStandAloneForm   'Let's customize form
End Sub

因此,在启动时,我们拥有所需的Visio和Form。在Terminate事件中再次ToggleExcel并最小化Visio。

<强> ToggleExcel

Private Function ToggleExcel()
    Static IsVBEWasVisible As Boolean

    With Application
        If .Visible = True Then
            IsVBEWasVisible = .VBE.MainWindow.Visible
            If IsVBEWasVisible Then _
                    .VBE.MainWindow.Visible = False
            .WindowState = xlMinimized
            .Visible = False
        Else
            If IsVBEWasVisible Then _
                    .VBE.MainWindow.Visible = True
            .WindowState = xlMaximized
            .Visible = True
        End If
    End With
End Function

<强> SetStandAloneForm

对于SetStandAloneForm我声明了这个API函数块:

#If VBA7 Then
    Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
    Private Declare PtrSafe Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare PtrSafe Function SetFocus Lib "user32" (ByVal hWnd As Long) As Long
#Else
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
    Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function SetFocus Lib "user32" (ByVal hWnd As Long) As Long
#End If

实际SetStandAloneForm:

Private Function SetStandAloneForm()
    Const GWL_STYLE As Long = -16
    Const GWL_EXSTYLE As Long = -20
    Const WS_CAPTION As Long = &HC00000
    Const WS_MINIMIZEBOX As Long = &H20000
    Const WS_MAXIMIZEBOX As Long = &H10000
    Const WS_POPUP As Long = &H80000000
    Const WS_VISIBLE As Long = &H10000000
    Const WS_EX_DLGMODALFRAME As Long = &H1
    Const WS_EX_APPWINDOW As Long = &H40000
    Const SW_SHOW As Long = 5

    Dim Hwnd As Long
    Dim CurrentStyle As Long
    Dim NewStyle As Long

    If Val(Application.Version) < 9 Then
        Hwnd = FindWindow("ThunderXFrame", Me.Caption)  'XL97
    Else
        Hwnd = FindWindow("ThunderDFrame", Me.Caption)  '>XL97
    End If

    'Let's give to userform minimise and maximise buttons
    CurrentStyle = GetWindowLong(Hwnd, GWL_STYLE)
    NewStyle = CurrentStyle Or WS_MINIMIZEBOX Or WS_MAXIMIZEBOX
    NewStyle = NewStyle And Not WS_VISIBLE And Not WS_POPUP
    Call SetWindowLong(Hwnd, GWL_STYLE, NewStyle)

    'Let's give to userform a taskbar icon
    CurrentStyle = GetWindowLong(Hwnd, GWL_EXSTYLE)
    NewStyle = CurrentStyle Or WS_EX_APPWINDOW
    Call SetWindowLong(Hwnd, GWL_EXSTYLE, NewStyle)
    Call ShowWindow(Hwnd, SW_SHOW)

End Function

答案 2 :(得分:0)

Gareth在这个问题上发表的答案:

Excel Useform: How to hide application but have icon in the taskbar

努力给我一个任务栏图标,并且是一个简单的复制和粘贴。

感谢大家的帮助。