VBA:Application.Screen更新Excel功能区上操作的等效项
我有一个宏,它使用VBA:Application.Screen更新Excel功能区上操作的等效项,excel,vba,Excel,Vba,我有一个宏,它使用UI自动化框架执行一些操作。我希望在宏执行期间抑制功能区上的快速移动,并希望在最后简单地显示结果。我尝试过使用应用程序。屏幕更新,但这似乎是一个不适用于功能区的设置。 是否有任何设置可用于操纵Excel功能区的屏幕更新 编辑:自动化框架可以在VBA项目中被引用为UIAutomationClient。dll文件是UIAutomationCore.dll 谢谢总结 LockWindowUpdate:不可靠的解决方案 WM_SETREDRAW:一个(太?)强大的解决方案 SW_:一个
UI自动化
框架执行一些操作。我希望在宏执行期间抑制功能区上的快速移动,并希望在最后简单地显示结果。我尝试过使用应用程序。屏幕更新
,但这似乎是一个不适用于功能区的设置。
是否有任何设置可用于操纵Excel功能区的屏幕更新
编辑:自动化框架可以在VBA项目中被引用为UIAutomationClient
。dll文件是UIAutomationCore.dll
谢谢总结
LockWindowUpdate
。主要问题是,根据我所做的测试和我发现的两篇帖子,它似乎不可靠:
- (不适用于所有机器)
- -您可以在第二篇文章中阅读以下内容: LockWindowUpdate不适用于窗口重画的通用抑制。LockWindowUpdate功能的目的是允许在窗口上绘制拖放反馈,而不受窗口本身的干扰。其目的是在绘制反馈时锁定窗口,在反馈完成时解锁窗口
'WindowHandle declaration
#If VBA7 Then
Private WindowHandle As LongPtr
#Else
Private WindowHandle As Long
#End If
'GetForegroundWindow declaration
#If VBA7 Then
Private Declare PtrSafe Function GetForegroundWindow Lib "USER32" () As LongPtr
#Else
Private Declare Function GetForegroundWindow Lib "user32" () As Long
#End If
Sub LockWindow()
On Error GoTo ErrHandler
WindowHandle = GetForegroundWindow
LockWindowUpdate WindowHandle
'Your code here
ErrHandler:
LockWindowUpdate WindowHandle
End Sub
2) WM_SETREDRAW:一个强大的解决方案
您还可以通过SendMessage窗口API函数发送一条消息,该函数用于防止重新绘制或刷新窗口
要为Excel工作簿实现此功能,可以使用以下函数声明SendMessage
,GetForegroundWindow
(请参见上面的代码)和适当的常量:
'SendMessage declaration
#If VBA7 Then
Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
#Else
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
#End If
'SendMessage Message(s)
Private Const WM_SETREDRAW = &HB
然后,您将围绕代码,如以下示例所示:
Sub FreezeWorkbook()
On Error GoTo ErrHandler
WindowHandle = GetForegroundWindow
Call SendMessage(WindowHandle, WM_SETREDRAW, False, 0&)
'Your code here
ErrHandler:
Call SendMessage(WindowHandle, WM_SETREDRAW, True, 0&)
End Sub
我还不能用UI自动化命令测试它,但它似乎应该可以工作
更激烈的选择
<>如果这不起作用,你可能会考虑为整个屏幕做这件事。为此,您需要一个返回桌面句柄的特殊函数:
'GetDesktopWindow declaration
#If VBA7 Then
Private Declare PtrSafe Function GetDesktopWindow Lib "user32" () As LongPtr
#Else
Private Declare Function GetDesktopWindow Lib "user32" () As Long
#End If
其余的基本相同:
Sub FreezeDesktop()
On Error GoTo ErrHandler
Call SendMessage(GetDesktopWindow, WM_SETREDRAW, False, 0&)
'Your code here
ErrHandler:
Call SendMessage(GetDesktopWindow, WM_SETREDRAW, True, 0&)
End Sub
请注意,这里使用错误处理更为重要,因为您不希望在出现未处理的错误时整个屏幕保持冻结状态
[但是,如果发生这种情况,您仍然可以]按键盘睡眠键,然后在进入睡眠状态后,
按唤醒键。。这样可以解冻电脑,避免任何危险
意外丢失数据。()
3) SW_:一个微妙的解决方案
如果前一个解决方案干扰了UI自动化过程,您可能需要考虑一个更微妙的解决方案,它可以间接解决您的问题。我说的是在代码开始时最小化窗口,在代码结束时最大化窗口
这并不完全是您想要的,但至少在交互发生时,用户不会看到窗口。根据我所做的测试,最小化窗口的事实不应该影响UI自动化命令'WindowHandle declaration
#If VBA7 Then
Private WindowHandle As LongPtr
#Else
Private WindowHandle As Long
#End If
'GetForegroundWindow declaration
#If VBA7 Then
Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As LongPtr
#Else
Private Declare Function GetForegroundWindow Lib "user32" () As Long
#End If
'ShowWindow declaration
#If VBA7 Then
Private Declare PtrSafe Function ShowWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal nCmdShow As Long) As Long
#Else
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
#End If
'ShowWindow Commands
Public Const SW_HIDE = 0
Public Const SW_SHOWNORMAL = 1
Public Const SW_NORMAL = 1
Public Const SW_SHOWMINIMIZED = 2
Public Const SW_SHOWMAXIMIZED = 3
Public Const SW_MAXIMIZE = 3
Public Const SW_SHOWNOACTIVATE = 4
Public Const SW_SHOW = 5
Public Const SW_MINIMIZE = 6
Public Const SW_SHOWMINNOACTIVE = 7
Public Const SW_SHOWNA = 8
Public Const SW_RESTORE = 9
Public Const SW_SHOWDEFAULT = 10
Public Const SW_MAX = 10
Sub MinimizeAndMaximize()
On Error GoTo ErrHandler
WindowHandle = GetForegroundWindow
ShowWindow WindowHandle, SW_SHOWMINIMIZED
'Your code here
ErrHandler:
ShowWindow WindowHandle, SW_MAXIMIZE
End Sub
您能更具体地介绍一下您正在使用的UI自动化框架吗?@DecimalTurn,谢谢您的回复!请看编辑后的帖子。谢谢你的回复,我尝试了你建议的第二个选项,但不幸的是,自动化框架操作的功能区似乎变灰了。我想这个函数会影响UI树,自动化框架无法执行它的操作。@ribarcheto94我添加了第三个不应该影响UI树的选项。让我知道这是否适用于您。感谢您花时间添加第三个选项。不幸的是,此宏将用于生产性应用程序,当用户单击按钮时,最小化窗口看起来不专业。我想可能没有什么好办法,但无论如何我都会给你荣誉,因为你为此付出了很多努力。也许其他人会觉得你的建议很有用。@ribarcheto94谢谢!如果您想让它保持专业性,您可以始终显示一个VBA无模式用户窗体,该窗体在最小化Excel窗口时对用户保持可见。你甚至可以包括一个进度条!非常感谢。这是一个新问题:
'WindowHandle declaration
#If VBA7 Then
Private WindowHandle As LongPtr
#Else
Private WindowHandle As Long
#End If
'GetForegroundWindow declaration
#If VBA7 Then
Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As LongPtr
#Else
Private Declare Function GetForegroundWindow Lib "user32" () As Long
#End If
'ShowWindow declaration
#If VBA7 Then
Private Declare PtrSafe Function ShowWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal nCmdShow As Long) As Long
#Else
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
#End If
'ShowWindow Commands
Public Const SW_HIDE = 0
Public Const SW_SHOWNORMAL = 1
Public Const SW_NORMAL = 1
Public Const SW_SHOWMINIMIZED = 2
Public Const SW_SHOWMAXIMIZED = 3
Public Const SW_MAXIMIZE = 3
Public Const SW_SHOWNOACTIVATE = 4
Public Const SW_SHOW = 5
Public Const SW_MINIMIZE = 6
Public Const SW_SHOWMINNOACTIVE = 7
Public Const SW_SHOWNA = 8
Public Const SW_RESTORE = 9
Public Const SW_SHOWDEFAULT = 10
Public Const SW_MAX = 10
Sub MinimizeAndMaximize()
On Error GoTo ErrHandler
WindowHandle = GetForegroundWindow
ShowWindow WindowHandle, SW_SHOWMINIMIZED
'Your code here
ErrHandler:
ShowWindow WindowHandle, SW_MAXIMIZE
End Sub