excel - una - Use VBA para borrar la ventana Inmediato?
print vba (11)
¿Alguien sabe cómo borrar la ventana inmediata usando VBA?
Si bien siempre puedo borrarlo manualmente, tengo curiosidad de saber si hay una forma de hacerlo programáticamente.
A continuación hay una solución de here
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
Aquí hay una combinación de ideas (probado con excel vba 2007):
''* (esto puede reemplazar su llamada diaria a la depuración)
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
No me gusta eliminar el contenido Inmediato (miedo a eliminar el código por accidente, por lo que lo anterior es un truco en algunos de los códigos que todos escribieron).
Esto maneja el problema sobre el que Akos Groller escribe: "Desafortunadamente, esto solo funciona si la posición de intercalación está al final de la ventana Inmediato"
El código abre la ventana Inmediato (o pone el foco en él), envía un CTRL + END, seguido por una inundación de líneas nuevas, por lo que el contenido de depuración anterior no está a la vista.
Tenga en cuenta que DoEvents es crucial ; de lo contrario, la lógica fallaría (la posición de intercalación no se movería a tiempo hasta el final de la ventana Inmediato).
Después de experimentar un poco, hice algunas modificaciones al código de Mehow de la siguiente manera:
- Errores de trampa (el código original está cayendo debido a que no se establece una referencia a "VBE", que también cambié a myVBE para mayor claridad)
- Establezca la ventana Inmediato en visible (¡por las dudas!)
- Comentó la línea para devolver el enfoque a la ventana original, ya que es esta línea la que hace que el contenido de la ventana de código se elimine en máquinas donde ocurren problemas de tiempo (lo verifiqué con PowerPoint 2013 x32 en Win 7 x64). ¡Parece que el foco está cambiando antes de que SendKeys se haya completado, incluso con Wait establecido en True!
- Cambie el estado de espera en SendKeys ya que no parece estar adherido a mi entorno de prueba.
También noté que el proyecto debe tener confianza para el modelo de objetos del proyecto VBA habilitado.
'' 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
Estoy a favor de no depender nunca de las teclas de método abreviado, ya que puede funcionar en algunos idiomas pero no en todos ... Aquí está mi humilde contribución:
Public Sub CLEAR_IMMEDIATE_WINDOW()
''by Fernando Fernandes
''YouTube: Expresso Excel
''Language: Portuguese/Brazil
Debug.Print VBA.String(200, vbNewLine)
End Sub
La respuesta marcada no funciona si se activa mediante el botón en la hoja de trabajo. Abre el cuadro de diálogo Ir a excel, como CTRL + G es el acceso directo para. Tienes que SetFocus en la ventana Inmediato antes. Es posible que también necesite DoEvent
si desea Debug.Print
. Debug.Print
justo después de borrar.
Application.VBE.Windows("Immediate").SetFocus
Application.SendKeys "^g ^a {DEL}"
DoEvents
Para completar, como @Austin D notó:
Para aquellos que se preguntan, las teclas de método abreviado son Ctrl + G (para activar la ventana Inmediato), luego Ctrl + A (para seleccionar todo), luego Del (para borrarlo).
Mucho más difícil de hacer que había imaginado. Encontré una versión here por keepitcool que evita los temidos Sendkeys
Ejecuta esto desde un módulo regular.
Se actualizó como la publicación inicial omitió las declaraciones de funciones privadas: el trabajo de copiar y pegar deficiente por parte del usuario realmente
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
Para la limpieza de la ventana Inmediato utilizo (VBA Excel 2016) la siguiente función:
Private Sub ClrImmediate()
With Application.VBE.Windows("Immediate")
.SetFocus
Application.SendKeys "^g", True
Application.SendKeys "^a", True
Application.SendKeys "{DEL}", True
End With
End Sub
Pero la llamada directa de ClrImmediate()
esta manera:
Sub ShowCommandBarNames()
ClrImmediate
''-- DoEvents
Debug.Print "next..."
End Sub
funciona solo si pongo el punto de interrupción en Debug.Print
, de lo contrario, la eliminación se realizará después de la ejecución de ShowCommandBarNames()
- NO antes de Debug.Print . Desafortunadamente, la llamada de DoEvents()
no me ayudó ... Y no importa: TRUE o FALSE está configurado para SendKeys .
Para resolver esto, uso las próximas dos llamadas:
Sub ShowCommandBarNames()
''-- ClrImmediate
Debug.Print "next..."
End Sub
Sub start_ShowCommandBarNames()
ClrImmediate
Application.OnTime Now + TimeSerial(0, 0, 1), "ShowCommandBarNames"
End Sub
Me parece que usar Application.OnTime podría ser muy útil en la programación de VBA IDE. En este caso, se puede usar incluso TimeSerial (0, 0, 0 ) .
SendKeys es directo, pero puede no gustarle (por ejemplo, abre la ventana Inmediato si se cerró y mueve el foco).
La forma de WinAPI + VBE es muy elaborada, pero es posible que no desee otorgarle acceso a VBA a VBA (incluso puede ser que su política de grupo de empresa no lo haga).
En lugar de borrar, puedes eliminar su contenido (o parte de él ...) con espacios en blanco:
Debug.Print String(65535, vbCr)
Desafortunadamente, esto solo funciona si la posición de intercalación se encuentra al final de la ventana Inmediato (la cadena se inserta, no se agrega). Si solo publica contenido a través de Debug.Print y no utiliza la ventana interactivamente, esto hará el trabajo. Si usa activamente la ventana y navega ocasionalmente dentro del contenido, esto no ayuda mucho.
Yo tuve el mismo problema. Aquí es cómo resolví el problema con la ayuda del enlace de Microsoft: https://msdn.microsoft.com/en-us/library/office/gg278655.aspx
Sub clearOutputWindow()
Application.SendKeys "^g ^a"
Application.SendKeys "^g ^x"
End Sub
o incluso más simple
Sub clearDebugConsole()
For i = 0 To 100
Debug.Print ""
Next i
End Sub
Sub ClearImmediateWindow()
SendKeys "^{g}", False
DoEvents
SendKeys "^{Home}", False
SendKeys "^+{End}", False
SendKeys "{Del}", False
SendKeys "{F7}", False
End Sub