Workbook_Open 之后 Focus 错误 Excel Window
Wrong Excel Window in Focus after Workbook_Open
我最近升级到 Office 365 / Excel 2016 导致了一些不需要的行为变化。 Workbook("Portfolio Appreciation") 包含一个 Workbook_open 过程,用于检查 Workbook("Index Returns") 是否打开;如果不是,它将打开该工作簿。
对于 Excel 2007,Index Returns
将在后台打开并停留在那里,这是所需的行为。它将是 "in a window" 并且可以在相同的 Excel window 中使用 View
的 Window
选项卡上的 Arrange All
选项进行查看色带.
对于 Excel 2016,如果它被 Workbook_Open 程序打开,Index Returns
将在其自己的 Excel Window 中打开,并在正面。 (不能再和Portfolio Appreciation
在同一个Excelwindow中查看)。
Index Returns
在前面就是问题所在。
我已经尝试选择和取消选择忽略其他使用 DDE 的应用程序的选项;我尝试了 AppActivate
方法(如下面的代码所示)并使用 MsgBox
验证了参数与相关标题栏相匹配。
不确定下一步要去哪里。赞赏建议。
另外:Index Returns
不包含宏或连接。 Portfolio Appreciation
除了 Workbook_Open
之外不包含任何宏,并且确实有一个在打开时会刷新的网络查询(查询会下载一些股票指数资料)。
Option Explicit
Private Sub Workbook_Open()
Dim wbs As Workbooks, wb As Workbook
Dim IndexReturns As String
Dim re As RegExp
Const sPat As String = "(^.*\DATA\).*"
Const sRepl As String = "EHC\Investment Committee\indexreturns.xlsb"
Dim sTitle As String
sTitle = Application.Caption
Set wbs = Application.Workbooks
Set re = New RegExp
With re
.Pattern = sPat
.Global = True
.IgnoreCase = True
End With
IndexReturns = re.Replace(ThisWorkbook.FullName, sRepl)
For Each wb In wbs
If wb.FullName = IndexReturns Then Exit Sub
Next wb
Application.ScreenUpdating = False
wbs.Open (IndexReturns)
Set re = Nothing
AppActivate sTitle 'sTitle contains title of thisworkbook
'The below doesn't work either
'AppActivate ThisWorkbook.Application.Caption
Application.ScreenUpdating = True
End Sub
我显然无法在您的环境中进行测试,但我会尝试绕过 Excel 正在做的任何事情并使用对 BringWindowToTop or SetForegroundWindow 的调用而不是 AppActivate
:
#If VBA7 Then
Public Declare PtrSafe Function BringWindowToTop Lib "user32" (ByVal _
hwnd As LongPtr) As Boolean
Public Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal _
hwnd As LongPtr) As Boolean
Public Declare PtrSafe Function FindWindow Lib "user32" Alias _
"FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName _
As Any) As LongPtr
#Else
Public Declare Function BringWindowToTop Lib "user32" (ByVal _
hwnd As Long) As Boolean
Public Declare Function SetForegroundWindow Lib "user32" (ByVal _
hwnd As Long) As Boolean
Public Declare Function FindWindow Lib "user32" Alias _
"FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName _
As Any) As Long
#End If
然后...
Dim hwnd As Long
hwnd = FindWindow(vbEmpty, sTitle) 'sTitle contains title of thisworkbook
BringWindowToTop hwnd
'...or...
SetForegroundWindow hwnd
当共产国际的代码没有改变行为时,我关注的是这是否是一个时间问题,IndexReturns
在代码激活另一个工作簿之前没有活动 window。对此进行调整的代码似乎已经解决了这个问题。
在执行 AppActivate
方法之前,我添加了一个循环来测试是否存在 IndexReturns
的 Window。
Set wb = wbs.Open(IndexReturns)
Do
DoEvents
Loop Until wb.Windows.Count > 0
AppActivate sTitle
为了更好的衡量,我还让 window 不可见,因为除了调试目的我不需要访问它:
wb.Windows(1).Visible = False
这似乎解决了Excel 2016打开文件与2007不同的问题
我最近升级到 Office 365 / Excel 2016 导致了一些不需要的行为变化。 Workbook("Portfolio Appreciation") 包含一个 Workbook_open 过程,用于检查 Workbook("Index Returns") 是否打开;如果不是,它将打开该工作簿。
对于 Excel 2007,Index Returns
将在后台打开并停留在那里,这是所需的行为。它将是 "in a window" 并且可以在相同的 Excel window 中使用 View
的 Window
选项卡上的 Arrange All
选项进行查看色带.
对于 Excel 2016,如果它被 Workbook_Open 程序打开,Index Returns
将在其自己的 Excel Window 中打开,并在正面。 (不能再和Portfolio Appreciation
在同一个Excelwindow中查看)。
Index Returns
在前面就是问题所在。
我已经尝试选择和取消选择忽略其他使用 DDE 的应用程序的选项;我尝试了 AppActivate
方法(如下面的代码所示)并使用 MsgBox
验证了参数与相关标题栏相匹配。
不确定下一步要去哪里。赞赏建议。
另外:Index Returns
不包含宏或连接。 Portfolio Appreciation
除了 Workbook_Open
之外不包含任何宏,并且确实有一个在打开时会刷新的网络查询(查询会下载一些股票指数资料)。
Option Explicit
Private Sub Workbook_Open()
Dim wbs As Workbooks, wb As Workbook
Dim IndexReturns As String
Dim re As RegExp
Const sPat As String = "(^.*\DATA\).*"
Const sRepl As String = "EHC\Investment Committee\indexreturns.xlsb"
Dim sTitle As String
sTitle = Application.Caption
Set wbs = Application.Workbooks
Set re = New RegExp
With re
.Pattern = sPat
.Global = True
.IgnoreCase = True
End With
IndexReturns = re.Replace(ThisWorkbook.FullName, sRepl)
For Each wb In wbs
If wb.FullName = IndexReturns Then Exit Sub
Next wb
Application.ScreenUpdating = False
wbs.Open (IndexReturns)
Set re = Nothing
AppActivate sTitle 'sTitle contains title of thisworkbook
'The below doesn't work either
'AppActivate ThisWorkbook.Application.Caption
Application.ScreenUpdating = True
End Sub
我显然无法在您的环境中进行测试,但我会尝试绕过 Excel 正在做的任何事情并使用对 BringWindowToTop or SetForegroundWindow 的调用而不是 AppActivate
:
#If VBA7 Then
Public Declare PtrSafe Function BringWindowToTop Lib "user32" (ByVal _
hwnd As LongPtr) As Boolean
Public Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal _
hwnd As LongPtr) As Boolean
Public Declare PtrSafe Function FindWindow Lib "user32" Alias _
"FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName _
As Any) As LongPtr
#Else
Public Declare Function BringWindowToTop Lib "user32" (ByVal _
hwnd As Long) As Boolean
Public Declare Function SetForegroundWindow Lib "user32" (ByVal _
hwnd As Long) As Boolean
Public Declare Function FindWindow Lib "user32" Alias _
"FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName _
As Any) As Long
#End If
然后...
Dim hwnd As Long
hwnd = FindWindow(vbEmpty, sTitle) 'sTitle contains title of thisworkbook
BringWindowToTop hwnd
'...or...
SetForegroundWindow hwnd
当共产国际的代码没有改变行为时,我关注的是这是否是一个时间问题,IndexReturns
在代码激活另一个工作簿之前没有活动 window。对此进行调整的代码似乎已经解决了这个问题。
在执行 AppActivate
方法之前,我添加了一个循环来测试是否存在 IndexReturns
的 Window。
Set wb = wbs.Open(IndexReturns)
Do
DoEvents
Loop Until wb.Windows.Count > 0
AppActivate sTitle
为了更好的衡量,我还让 window 不可见,因为除了调试目的我不需要访问它:
wb.Windows(1).Visible = False
这似乎解决了Excel 2016打开文件与2007不同的问题