excel 激活未保存工作簿的最佳方法

epggiuax  于 2022-12-14  发布在  其他
关注(0)|答案(2)|浏览(189)

我有各种代码来创建报表。报表被添加到一个新的工作簿中,该工作簿不会被保存,其原理是用户可以选择是保存工作簿还是在查看结果后关闭它。下面的代码将激活未保存的工作簿。

Sub ActivateWorkbook(wbResults As Workbook)
    Dim objWindow As Window
    
    With Application

        .VBE.MainWindow.WindowState = vbext_ws_Minimize
                
        For Each objWindow In .Windows
            
            With objWindow
                
                If .Caption <> wbResults.Name Then .WindowState = xlMinimized
                
            End With
            
        Next objWindow
        
        With .Windows(wbResults.Name)
            
            .WindowState = xlMaximized
            
            .Activate
            
        End With
                
    End With
    
End Sub

这在单个监视器上可以正常工作。但是如果已经有多个工作簿,并且它们是不同的监视器,它会最小化两个(所有)监视器中的窗口,看起来不太理想。我在想,如果我能够识别哪个监视器有活动工作簿,我只能最小化该监视器的窗口(如果需要,包括VBE)。
作为对chris neilsen的回复,我将包含一些基本的代码来说明我用什么来调用上面的过程。请记住,每个过程的目的是不同的,每个过程中的大多数代码实际上并不适合这个特定的问题。

Sub ExampleCode()
    Dim wbXXX As Workbook
    
    Set wbXXX = Workbooks.Add
    
    With wbXXX
    
        'Main code here
    
    End With
    
    Call ActivateWorkbook(wbXXX)
    
    Set wbXXX = Nothing
    
End Sub

感谢任何想帮忙的人。很感激。

y1aodyip

y1aodyip1#

好吧,这似乎对我有用。它不太好。注意,需要“Microsoft Visual Basic for Applications Extensibility 5.3”来最小化VBE,VBE是运行代码的地方,而不是主Excel应用程序。无论如何,Activate在过去对我来说并不可靠。如果它对你有用,我想就不需要这些了。如果有人愿意测试它,请让我知道你怎么去。我只测试了一个双显示器设置到目前为止。
目的:当“激活”不起作用时,在与活动工作簿相同的监视器中显示新工作簿。

Private Declare PtrSafe Function FindWindow _
    Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, _
    ByVal lpWindowName As String) _
    As LongPtr
    
Private Declare PtrSafe Function MonitorFromWindow _
    Lib "user32" _
    (ByVal hwnd As LongPtr, _
    ByVal dwFlags As Long) _
    As LongPtr
    
Private Declare PtrSafe Function EnumDisplayMonitors _
    Lib "user32.dll" _
    (ByVal hdc As Long, _
    ByRef lprcClip As Any, _
    ByVal lpfnEnum As Long, _
    ByVal dwData As Long) _
    As Long
    
Private Declare PtrSafe Function GetSystemMetrics _
    Lib "user32" _
    (ByVal Index As Long) _
    As Long
    
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Const MONITOR_DEFAULTTONEAREST = &H2
Private Const SM_CMONITORS As Long = 80

Private hWndMonitor As LongPtr
Private hActiveWorkbook As LongPtr
Private hVBE As LongPtr
Private lngMode As Long

Function MonitorCount() As Long
    
    MonitorCount = GetSystemMetrics(SM_CMONITORS)
    
End Function

Function MonitorsAreTheSame() As Boolean
    
    MonitorsAreTheSame = True
    
    'Count of monitors
    If MonitorCount > 1 Then
        
        'Check the ActiveWorkbook
        lngMode = 0
        
        hWndMonitor = FindWindow("XLMAIN", Application.Caption)
        
        EnumDisplayMonitors ByVal 0&, ByVal 0&, AddressOf MonitorEnumProc, ByVal 0&
        
        'Check the VBE
        lngMode = 1
        
        hWndMonitor = FindWindow("wndclass_desked_gsk", Application.VBE.MainWindow.Caption)
        
        EnumDisplayMonitors ByVal 0&, ByVal 0&, AddressOf MonitorEnumProc, ByVal 0&
        
        MonitorsAreTheSame = CBool(hActiveWorkbook = hVBE)
        
    End If
    
End Function

Private Function MonitorEnumProc(ByVal hMonitor As Long, ByVal hdcMonitor As Long, lprcMonitor As RECT, ByVal dwData As Long) As Long
    
    If MonitorFromWindow(hWndMonitor, MONITOR_DEFAULTTONEAREST) = hMonitor Then
        
        Select Case lngMode
            
            Case 0
                
                hActiveWorkbook = CStr(hMonitor)
                
            Case 1
                
                hVBE = CStr(hMonitor)
                
        End Select
        
    End If
    
    MonitorEnumProc = MonitorCount
    
End Function

Sub Test()
    Dim wbkTest As Workbook
    
    Set wbkTest = Workbooks.Add
    
    Call ActivateWorkbook(wbkTest)
    
    Set wbkTest = Nothing
    
End Sub

Sub ActivateWorkbook(wbkResults As Workbook)
    Dim objWindow As Window
    
    With Application
    
         If MonitorsAreTheSame = True Then
        
            .VBE.MainWindow.WindowState = vbext_ws_Minimize
            
            For Each objWindow In .Windows
                
                With objWindow
                
                    If .Left = Application.VBE.MainWindow.Left Then
                    
                        If .Caption <> wbkResults.Name Then .WindowState = xlMinimized
                        
                    End If
                    
                End With
                
            Next objWindow
            
        Else
            
            For Each objWindow In .Windows
                
                With objWindow
                
                    If .Left <> Application.VBE.MainWindow.Left Then
                    
                        If .Caption <> wbkResults.Name Then .WindowState = xlMinimized
                        
                    End If
                    
                End With
                
            Next objWindow
            
        End If
                        
        .Windows(wbkResults.Name).WindowState = xlMaximized
        
        AppActivate (.Caption)
                
    End With
    
End Sub
uinbv5nw

uinbv5nw2#

这应该足够了-不需要第二个子激活。2这些应该在前台显示新的工作簿,没有其他窗口改变。

Sub ExampleCode()
    Dim wbXXX As Workbook
    
    Set wbXXX = Workbooks.Add
    
    With wbXXX
    
        'Main code here
    
    End With
    
    wbXXX.Activate
    
    Set wbXXX = Nothing
    
End Sub

相关问题