使用VBA清除即时窗口?

Alp*_*pha 51 excel vba immediate-window excel-vba

有谁知道如何使用VBA清除即时窗口?

虽然我总是可以手动清除它,但我很好奇是否有办法以编程方式执行此操作.

小智 30

以下是此处的解决方案

Sub stance()
Dim x As Long

For x = 1 To 10    
    Debug.Print x
Next

Debug.Print Now
Application.SendKeys "^g ^a {DEL}"    
End Sub
Run Code Online (Sandbox Code Playgroud)

  • 对于那些想知道的人,快捷键是"Ctrl + G"(激活立即窗口),然后是"Ctrl + A"(选择所有内容),然后是"Del"(清除它). (9认同)
  • 这个解决方案的唯一问题是`Application.SendKeys`似乎非常不可预测.例如,在_different subprocedure_中使用它时,我的Userform的初始化将受到影响(听起来很奇怪).虽然这个更短,但听起来有点危险. (6认同)
  • 代码的唯一问题是您可以在执行后重新打印到即时窗口.什么都不会显示出来 (4认同)
  • 奇.看起来很简单.但是,当我从Access 2007运行它时,它正在关闭我的NumLock.谁知道为什么? (3认同)
  • 对我不起作用(Excel 2013). (2认同)
  • 尝试使用类似“ If Application.VBE.ActiveWindow.Caption =“ Immediate”和Application.VBE.ActiveWindow.Visible的应用程序,然后使用Application.SendKeys“ ^ a {DEL} {HOME}”`以减少不可预测性。 (2认同)

bre*_*tdj 23

我设想的更难做到这一点.我 keepitcool 找到了一个避免可怕的版本Sendkeys

从常规模块运行此命令.

更新为初始帖子错过了私人功能声明 - 真正糟糕的复制和粘贴工作

Private Declare Function GetWindow _
Lib "user32" ( _
ByVal hWnd As Long, _
ByVal wCmd 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 FindWindowEx _
Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long
Private Declare Function GetKeyboardState _
Lib "user32" (pbKeyState As Byte) As Long
Private Declare Function SetKeyboardState _
Lib "user32" (lppbKeyState As Byte) As Long
Private Declare Function PostMessage _
Lib "user32" Alias "PostMessageA" ( _
ByVal hWnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long _
) As Long


Private Const WM_KEYDOWN As Long = &H100
Private Const KEYSTATE_KEYDOWN As Long = &H80


Private savState(0 To 255) As Byte


Sub ClearImmediateWindow()
'Adapted  by   keepITcool
'Original from Jamie Collins fka "OneDayWhen"
'http://www.dicks-blog.com/excel/2004/06/clear_the_immed.html


Dim hPane As Long
Dim tmpState(0 To 255) As Byte


hPane = GetImmHandle
If hPane = 0 Then MsgBox "Immediate Window not found."
If hPane < 1 Then Exit Sub


'Save the keyboardstate
GetKeyboardState savState(0)


'Sink the CTRL (note we work with the empty tmpState)
tmpState(vbKeyControl) = KEYSTATE_KEYDOWN
SetKeyboardState tmpState(0)
'Send CTRL+End
PostMessage hPane, WM_KEYDOWN, vbKeyEnd, 0&
'Sink the SHIFT
tmpState(vbKeyShift) = KEYSTATE_KEYDOWN
SetKeyboardState tmpState(0)
'Send CTRLSHIFT+Home and CTRLSHIFT+BackSpace
PostMessage hPane, WM_KEYDOWN, vbKeyHome, 0&
PostMessage hPane, WM_KEYDOWN, vbKeyBack, 0&


'Schedule cleanup code to run
Application.OnTime Now + TimeSerial(0, 0, 0), "DoCleanUp"


End Sub


Sub DoCleanUp()
' Restore keyboard state
SetKeyboardState savState(0)
End Sub


Function GetImmHandle() As Long
'This function finds the Immediate Pane and returns a handle.
'Docked or MDI, Desked or Floating, Visible or Hidden


Dim oWnd As Object, bDock As Boolean, bShow As Boolean
Dim sMain$, sDock$, sPane$
Dim lMain&, lDock&, lPane&


On Error Resume Next
sMain = Application.VBE.MainWindow.Caption
If Err <> 0 Then
MsgBox "No Access to Visual Basic Project"
GetImmHandle = -1
Exit Function
' Excel2003: Registry Editor (Regedit.exe)
'    HKLM\SOFTWARE\Microsoft\Office\11.0\Excel\Security
'    Change or add a DWORD called 'AccessVBOM', set to 1
' Excel2002: Tools/Macro/Security
'    Tab 'Trusted Sources', Check 'Trust access..'
End If


For Each oWnd In Application.VBE.Windows
If oWnd.Type = 5 Then
bShow = oWnd.Visible
sPane = oWnd.Caption
If Not oWnd.LinkedWindowFrame Is Nothing Then
bDock = True
sDock = oWnd.LinkedWindowFrame.Caption
End If
Exit For
End If
Next
lMain = FindWindow("wndclass_desked_gsk", sMain)
If bDock Then
'Docked within the VBE
lPane = FindWindowEx(lMain, 0&, "VbaWindow", sPane)
If lPane = 0 Then
'Floating Pane.. which MAY have it's own frame
lDock = FindWindow("VbFloatingPalette", vbNullString)
lPane = FindWindowEx(lDock, 0&, "VbaWindow", sPane)
While lDock > 0 And lPane = 0
lDock = GetWindow(lDock, 2) 'GW_HWNDNEXT = 2
lPane = FindWindowEx(lDock, 0&, "VbaWindow", sPane)
Wend
End If
ElseIf bShow Then
lDock = FindWindowEx(lMain, 0&, "MDIClient", _
vbNullString)
lDock = FindWindowEx(lDock, 0&, "DockingView", _
vbNullString)
lPane = FindWindowEx(lDock, 0&, "VbaWindow", sPane)
Else
lPane = FindWindowEx(lMain, 0&, "VbaWindow", sPane)
End If


GetImmHandle = lPane


End Function
Run Code Online (Sandbox Code Playgroud)

  • 从过去爆炸:这是我十年或更久以前写的代码! (7认同)
  • 谢谢~~这比我预期的要难得多:D (3认同)

Ako*_*ler 18

SendKeys是直的,但您可能不喜欢它(例如,如果它关闭,它会打开立即窗口,并移动焦点).

WinAPI + VBE方式非常复杂,但您可能希望不授予VBA访问VBE(甚至可能是您的公司组策略).

而不是清除你可以用空格清除其内容(或其中的一部分......):

Debug.Print String(65535, vbCr)
Run Code Online (Sandbox Code Playgroud)

不幸的是,这仅在插入位置位于立即窗口的末尾时才起作用(插入字符串,不附加).如果您只通过Debug.Print发布内容并且不以交互方式使用该窗口,则可以完成此任务.如果您主动使用该窗口并偶尔导航到内容中,这并没有多大帮助.

  • 理论上,在选择窗口和向其发布密钥之间的用户界面上会发生事情.所以消息_may_传递到其他地方.更现实的是,如果您针对不同的应用程序或版本并且密钥可以执行完全不同的操作,则不会出现错误.当然,作为速记,它是可以的(而不是你按Ctrl-g Ctrl-a Del,为什么VBA不能这样做?),但如果我可以避免它,我不会向使用SendKeys的用户部署内容. (8认同)
  • 这发生在我身上 - ctrl +一个删除以某种方式进入代码模块窗口并消灭了我的代码,我没有意识到,直到它为时已晚才能恢复它.我根本不推荐SendKeys方法. (7认同)
  • 仅作记录:SENDKeys 更改键盘设置,例如 NUMLOCK……至少可以说很烦人 (3认同)
  • 为什么你不喜欢sendkeys? (2认同)

Seb*_*eck 16

甚至更简单

Sub clearDebugConsole()
    For i = 0 To 100
        Debug.Print ""
    Next i
End Sub
Run Code Online (Sandbox Code Playgroud)

  • 我理解其他解决方案更彻底,但我不确定你为什么被投票.这是对我有用的解决方案 - 我只是需要清除它,并使一些空白工作得很好.谢谢! (2认同)
  • 至少肮脏但有趣的方式:-) (2认同)

Art*_*yka 7

如果通过工作表中的按钮触发,标记的答案不起作用。它会打开“转到 Excel”对话框,因为 CTRL+G 是其快捷方式。您必须先将焦点设置在立即窗口上。DoEvent如果您想Debug.Print在清算后立即进行,您可能也需要。

Application.VBE.Windows("Immediate").SetFocus
Application.SendKeys "^g ^a {DEL}"
DoEvents
Run Code Online (Sandbox Code Playgroud)

为了完整起见,@Austin D 注意到:

对于那些想知道的人,快捷键是 Ctrl+G(激活立即窗口),然后 Ctrl+A(选择所有内容),然后 Del(清除它)。


小智 6

以下是各种想法的组合(使用excel vba 2007测试):

'*(这可以取代你日常的调用调试)

Public Sub MyDebug(sPrintStr As String, Optional bClear As Boolean = False)
   If bClear = True Then
      Application.SendKeys "^g^{END}", True

      DoEvents '  !!! DoEvents is VERY IMPORTANT here !!!

      Debug.Print String(30, vbCrLf)
   End If

   Debug.Print sPrintStr
End Sub
Run Code Online (Sandbox Code Playgroud)

我不喜欢删除Immediate内容(害怕意外删除代码,因此以上是对你所写的一些代码的攻击.

这解决了Akos Groller上面写到的问题: "不幸的是,这只有在插入位置位于立即窗口的末尾时才有效 "

代码打开立即窗口(或将焦点放在它上面),发送一个CTRL + END,然后是大量的换行符,因此以前的调试内容不可见.

请注意, DoEvents是至关重要的,否则逻辑将失败(插入位置不会及时移动到立即窗口的末尾).