71

VBAを使用して即時ウィンドウをクリアする方法を知っている人はいますか?

私はいつでも自分で手動でクリアできますが、プログラムでこれを行う方法があるかどうか興味があります.

4

19 に答える 19

35

以下はここからの解決策です

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
于 2012-06-20T11:52:01.090 に答える
24

SendKeysはまっすぐですが、気に入らない場合があります(たとえば、閉じている場合はイミディエイトウィンドウが開き、フォーカスが移動します)。

WinAPI + VBEの方法は非常に複雑ですが、VBAにVBEへのアクセスを許可したくない場合があります(会社のグループポリシーで許可しない場合もあります)。

クリアする代わりに、そのコンテンツ(またはその一部...)を空白でフラッシュすることができます:

Debug.Print String(65535, vbCr)

残念ながら、これは、キャレットの位置がイミディエイトウィンドウの最後にある場合にのみ機能します(文字列は挿入され、追加されません)。Debug.Printを介してコンテンツを投稿するだけで、ウィンドウをインタラクティブに使用しない場合は、これで問題ありません。ウィンドウを積極的に使用し、コンテンツ内に移動することがある場合、これはあまり役に立ちません。

于 2012-11-23T07:50:51.003 に答える
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
于 2012-04-18T05:43:17.937 に答える
7

アイデアの組み合わせは次のとおりです(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

Immediate コンテンツを削除するのは好きではありません (誤ってコードを削除することを恐れているため、上記は皆さんが作成したコードの一部をハックしたものです。

これは、Akos Groller が上記について書いている問題を処理 ます

このコードは、イミディエイト ウィンドウを開き (またはそれにフォーカスを置き)、CTRL + END を送信し、その後に大量の改行が続くため、以前のデバッグ コンテンツは表示されません。

DoEvents は重要であることに注意してください 。そうしないと、ロジックが失敗します (キャレットの位置がイミディエイト ウィンドウの最後まで移動しません)。

于 2015-02-07T05:47:38.453 に答える
2

いくつかの実験の後、次のように mehow のコードにいくつかの変更を加えました。

  1. エラーをトラップします (「VBE」への参照を設定していないため、元のコードがフォールオーバーしています。わかりやすくするために、これも myVBE に変更しました)
  2. イミディエイト ウィンドウを表示に設定します (念のため!)。
  3. タイミングの問題が発生したマシンでコード ウィンドウの内容が削除されるのはこの行であるため、フォーカスを元のウィンドウに戻す行をコメント アウトしました (Win 7 x64 の PowerPoint 2013 x32 でこれを確認しました)。Wait が True に設定されていても、SendKeys が完了する前にフォーカスが戻っているようです。
  4. 私のテスト環境では守られていないように見えるため、SendKeys の待機状態を変更します。

また、VBA プロジェクト オブジェクト モデルに対する信頼がプロジェクトで有効になっている必要があることにも注意しました。

' DEPENDENCIES
' 1. Add reference:
' Tools > References > Microsoft Visual Basic for Applications Extensibility 5.3
' 2. Enable VBA project access:
' Backstage / Options / Trust Centre / Trust Center Settings / Trust access to the VBA project object model

Public Function ClearImmediateWindow()
  On Error GoTo ErrorHandler
  Dim myVBE As VBE
  Dim winImm As VBIDE.Window
  Dim winActive As VBIDE.Window

  Set myVBE = Application.VBE
  Set winActive = myVBE.ActiveWindow
  Set winImm = myVBE.Windows("Immediate")

  ' Make sure the Immediate window is visible
  winImm.Visible = True

  ' Switch the focus to the Immediate window
  winImm.SetFocus

  ' Send the key sequence to select the window contents and delete it:
  ' Ctrl+Home to move cursor to the top then Ctrl+Shift+End to move while
  ' selecting to the end then Delete
  SendKeys "^{Home}", False
  SendKeys "^+{End}", False
  SendKeys "{Del}", False

  ' Return the focus to the user's original window
  ' (comment out next line if your code disappears instead!)
  'winActive.SetFocus

  ' Release object variables memory
  Set myVBE = Nothing
  Set winImm = Nothing
  Set winActive = Nothing

  ' Avoid the error handler and exit this procedure
  Exit Function

ErrorHandler:
   MsgBox "Error " & Err.Number & vbCrLf & vbCrLf & Err.Description, _
      vbCritical + vbOKOnly, "There was an unexpected error."
  Resume Next
End Function
于 2014-03-03T21:11:52.783 に答える