Cómo descartar un cuadro de diálogo mostrado por una aplicación de Office con Visual Basic

Seleccione idioma Seleccione idioma
Id. de artículo: 259971 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

Resumen

Cuando automatice una aplicación de Office en Visual Basic (VB), puede mostrar un cuadro de diálogo. El cuadro de diálogo hace que parezca que la aplicación de Visual Basic deja de responder porque Visual Basic espera a que se descarte el cuadro de diálogo. El cuadro de diálogo se debe descartar para que la aplicación pueda continuar.

En este artículo se explica cómo utilizar los modelos de objetos para las aplicaciones de Office con el fin de evitar los cuadros de diálogo durante la automatización. También se proporciona un ejemplo paso a paso que simula la entrada proporcionada por el usuario y permite descartar mediante programación un cuadro de diálogo que no se puede evitar mediante las propiedades y métodos usuales que exponen los modelos de objetos.

Más información

A veces, puede que desee automatizar una aplicación de Office pero que no requiera ninguna interacción del usuario con ella. En este caso, si la aplicación de Office muestra un cuadro de diálogo, parece que la aplicación deja de responder hasta que un usuario pueda descartar el cuadro de diálogo. Sin embargo, puede que no haya ningún usuario sentado delante del equipo que descarte el cuadro de diálogo.

Las aplicaciones de Office no se diseñaron para ejecutarse de forma desatendida. Por consiguiente, una aplicación que automatiza Office a veces puede encontrarse un cuadro de diálogo que haya mostrado la aplicación de Office. Gracias a las pruebas habituales de la aplicación, normalmente puede determinar qué cuadros de diálogo aparecen y escribir código para evitarlos.

A continuación se enumeran algunas estrategias recomendadas para evitar que aparezcan cuadros de diálogo al automatizar una aplicación de Office:
  • Determine si la propiedad o método que está utilizando (el que está produciendo el cuadro de diálogo) tiene argumentos opcionales que pueda pasarle. A veces, puede evitar un cuadro de diálogo pasando todos los argumentos a la propiedad o método. Por ejemplo, si se usa el método Open para abrir un libro de Excel y ese libro está protegido mediante una contraseña, Excel muestra un cuadro de diálogo que pide al usuario que escriba la contraseña, si no se proporciona el argumento de contraseña al llamar al método Open. Para evitar el cuadro de diálogo, proporcione un valor para el argumento Password al llamar al método Open. De igual forma, al utilizar el método Close para cerrar un documento, suele servir de ayuda especificar el argumento SaveChanges para evitar que aparezca un cuadro de diálogo que pida al usuario que guarde los cambios. Para obtener información adicional sobre cómo determinar qué argumentos están disponibles para la propiedad o el método al que está llamando, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
    222101 Cómo encontrar y usar la documentación del modelo de objetos de Office
  • Estudie el modelo de objetos de la aplicación de Office para ver si puede haber alguna propiedad que evite ciertos cuadros de diálogo. Por ejemplo, el objeto de Excel Aplicación tiene las propiedades AskToUpdateLinks y AlertBeforeOverwriting.
  • Establezca la propiedad Application.DisplayAlerts (Excel, Proyecto, Word) o use Application.DoCmd.SetWarnings False (sólo en Access) para desactivar la presentación de mensajes de alerta. La mayor parte de los cuadros de diálogo se pueden evitar con esta configuración, aunque no todos.
  • Establezca la propiedad Application.FeatureInstall (en Office 2000 y versiones posteriores) para tratar los posibles cuadros de diálogo "Esta característica no está instalada..." cuando se obtenga acceso a un componente que puede no estar instalado en el sistema del usuario.
  • Utilice la instrucción On Error para evitar los mensajes de error en tiempo de ejecución que podrían producirse, por ejemplo al intentar establecer Application.ActivePrinter cuando no hay instalado ningún controlador de impresora en el sistema del usuario.
  • Pruebe completamente la aplicación como ayuda para anticipar cuándo pueden aparecer cuadros de diálogo. Por ejemplo, suponga que llama al método SaveAs de una aplicación de Office para guardar un archivo. Si ese archivo ya existe, puede aparecer un cuadro de diálogo que pida confirmación para reemplazar el archivo existente. Si modifica el código para comprobar el archivo antes de llamar al método SaveAs, puede evitar la posibilidad de que aparezca el cuadro de diálogo. Por ejemplo, si el archivo ya existe, elimínelo utilizando la instrucción Kill antes de llamar al método SaveAs.
Nota: aun cuando use estas técnicas y diseñe una aplicación cuidadosamente para evitar los cuadros de diálogo, puede que todavía tenga que hacer frente a una situación en la que un cuadro de diálogo no se pueda evitar con los métodos y propiedades expuestas en el modelo de objetos de la aplicación de Office. En tales situaciones, podría ser necesario descartar mediante programación un cuadro de diálogo simulando la entrada que proporciona el usuario. La demostración siguiente ilustra cómo se puede lograr esto con un cliente de automatización de Visual Basic.

Ejemplo

Los pasos de esta sección demuestran la automatización de Microsoft Word para imprimir un documento. El cliente de automatización llama al método PrintOut del objeto Word Document. Si la impresora predeterminada del usuario se configura para imprimir en el puerto FILE, una llamada a PrintOut genera un cuadro de diálogo que pide al usuario que escriba un nombre de archivo. Para determinar si el método PrintOut hace que este cuadro de diálogo aparezca, el cliente de automatización de Visual Basic utiliza un control Timer para detectar el tiempo de inactividad después de llamar al método PrintOut. Antes de llamar a PrintOut, Timer se habilita y se establece para desencadenarse en cinco segundos. Cuando PrintOut se completa, Timer se deshabilita. Por consiguiente, si el método PrintOut se completa antes de cinco segundos, el evento Timer nunca se produce y no se realiza ninguna otra acción. El documento se imprime y la ejecución del código continúa más allá del método PrintOut. Sin embargo, si el evento Timer se produce dentro del intervalo de cinco segundos, se supone que el método PrintOut no se ha completado y que el retraso se debe a un cuadro de diálogo que espera los datos que proporciona el usuario. Cuando el evento Timer se produce, el cliente de automatización da el foco a Word y utiliza SendKeys para descartar el cuadro de diálogo.

Nota: para la demostración, este ejemplo utiliza el método PrintOut de manera que muestra intencionadamente un cuadro de diálogo cuando imprime en un conjunto de impresoras a un puerto FILE. Observe que el método PrintOut tiene dos argumentos, OutputfileName y PrintToFile, que puede proporcionar para evitar este cuadro de diálogo.

Además, al utilizar este enfoque con "timer", puede personalizar el tiempo de espera para que sea mayor o menor de cinco segundos, así como las pulsaciones de teclas que envía al cuadro de diálogo.

Esta demostración consta de dos proyectos de Visual Basic:
  1. Un archivo EXE de ActiveX que proporciona una clase Timer, que se usa para detectar un retraso. La razón para utilizar un archivo EXE de ActiveX para la clase Timer es ejecutar el código de Timer en un proceso independiente y, por consiguiente, en un subproceso independiente. Esto permite a la clase Timer generar un evento durante una llamada de automatización suspendida.
  2. Un EXE estándar que utiliza la automatización para Word y llama al método PrintOut con el fin de imprimir un documento. Utiliza el archivo EXE de ActiveX para detectar un retraso al llamar al método PrintOut.
Crear el proyecto EXE de ActiveX
  1. Inicie Visual Basic y cree un proyecto EXE de ActiveX. Se creará Class1 de manera predeterminada.
  2. En el menú Proyecto, haga clic para seleccionar Propiedades y, a continuación, cambie el nombre del proyecto por MyTimer.
  3. Copie y pegue el código siguiente en el módulo de Class1:
    Option Explicit
    
    Public Event Timer()
    Private oForm1 As Form1
    
    Private Sub Class_Initialize()
        Set oForm1 = New Form1
        oForm1.Timer1.Enabled = False
    End Sub
    
    Private Sub Class_Terminate()
        Me.Enabled = False
        Unload oForm1
        Set oForm1 = Nothing
    End Sub
    
    Public Property Get Enabled() As Boolean
        Enabled = oForm1.Timer1.Enabled
    End Property
    
    Public Property Let Enabled(ByVal vNewValue As Boolean)
        oForm1.Timer1.Enabled = vNewValue
        If vNewValue = True Then
            Set oForm1.oClass1 = Me
        Else
            Set oForm1.oClass1 = Nothing
        End If
    End Property
    
    Public Property Get Interval() As Integer
        Interval = oForm1.Timer1.Interval
    End Property
    
    Public Property Let Interval(ByVal vNewValue As Integer)
        oForm1.Timer1.Interval = vNewValue
    End Property
    
    Friend Sub TimerEvent()
        RaiseEvent Timer
    End Sub
    					
  4. En el menú Proyecto, elija Agregar formulario para agregar un nuevo formulario al proyecto.
  5. Agregue un control Timer al formulario.
  6. Copie y pegue el código siguiente en el módulo de código de Form1:
    Option Explicit
    
    Public oClass1 As Class1
    
    Private Sub Timer1_Timer()
        oClass1.TimerEvent
    End Sub
    					
  7. Guarde este proyecto en otra subcarpeta denominada Server.
  8. En el menú Archivo, elija Make MyTimer.Exe para generar y registrar el componente.
Crear el cliente de automatización
  1. Cree un nuevo proyecto estándar EXE en Visual Basic. De forma predeterminada, se crea Form1.
  2. Agregue un control CommandButton al formulario.
  3. En el menú Proyecto, haga clic en Referencias. Agregue las referencias a la Biblioteca de objetos de Microsoft Word 8.0 (ó 9.0 ó 10.0) y a MyTimer.
  4. Copie y pegue el código siguiente al módulo de formulario:
    Option Explicit
    
    Private oWord As Word.Application
    Private strWordCaption As String
    Private WithEvents oMyTimer As MyTimer.Class1
    
    Private Sub Form_Load()
        'Create MyTimer object, and then disable it by default:
        Set oMyTimer = New MyTimer.Class1
        oMyTimer.Enabled = False
    End Sub
    
    Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
        'Terminate MyTimer object when the form is closed:
        oMyTimer.Enabled = False
        Set oMyTimer = Nothing
    End Sub
    
    Private Sub Command1_Click()
        On Error GoTo ErrorHandler
        
        'Create a new Word instance and put text in the new document:
        Set oWord = CreateObject("Word.Application")
        oWord.Visible = True
        oWord.Documents.Add
        oWord.Selection.TypeText "Hello World!"
        
        'Prepare Timer to "watch out" for a delay in calling PrintOut:
        strWordCaption = GetWordCaption 'for use with AppActivate
        oMyTimer.Interval = 5000 'allow 5 second wait time
        oMyTimer.Enabled = True
            
        'Call the PrintOut method, which may prompt the user to select
        'an output file name if the default printer is set to FILE:
        oWord.PrintOut Background:=False
    
    Done:
        On Error Resume Next
        'Turn off Timer:
        oMyTimer.Enabled = False
        
        'Close document and quit the Word instance:
        oWord.ActiveDocument.Close SaveChanges:=False
        oWord.Quit
        Set oWord = Nothing
        Exit Sub
    ErrorHandler:
        Resume Done
    End Sub
    
    Private Sub oMyTimer_Timer()
    'If this event occurs, there was a delay in calling PrintOut.
    'You can assume that the delay is caused by a dialog box prompting
    'for an output file name because the user has the printer
    'configured to print to FILE. SendKeys is used to provide the
    'output file name and dismiss the dialog box.
        Dim strKeys As String
        
        On Error Resume Next
        
        'Make sure that Word has the focus before using SendKeys to it:
    
        AppActivate strWordCaption 'Set focus to Word.
        
        'Send keystrokes to enter the output file name:
        If Right$(App.Path, 1) = "\" Then
            strKeys = App.Path & "MyOutput.prn"
        Else
            strKeys = App.Path & "\MyOutput.prn"
        End If
        Kill strKeys 'make sure file does not already exist
        strKeys = strKeys & "~" '~ represents the OK button to dismiss dialog
        SendKeys strKeys, True
           
        'Disable MyTimer:
        oMyTimer.Enabled = False
    End Sub
    
    Private Function GetWordCaption() As String
    'Returns the Word Caption. For use with the AppActivate statement
        Dim s As String
        On Error Resume Next
        If Left$(oWord.Version, 1) = "8" Then
            'Word 97 logic:
            s = oWord.Caption
        Else
            'Word 2000 or 2002 logic:
            Err.Clear
            s = oWord.ActiveWindow.Caption
            If Err.Number = 0 Then 'no error
                s = s & " - " & oWord.Caption
            Else
                s = oWord.Caption
            End If
        End If
        GetWordCaption = s
    End Function
    					
  5. Guarde este proyecto en otra subcarpeta denominada Client.
  6. Presione la tecla F5 para ejecutar el proyecto. Form1 aparece.
  7. Haga clic en Command1 en el formulario. De este modo automatiza Word, agrega un documento nuevo con algún texto y, a continuación, lo envía a la impresora utilizando el método PrintOut. No ve un cuadro de diálogo si la impresora está configurada para imprimir en una impresora.
  8. En el Panel de control de Windows, cambie la impresora predeterminada de modo que se configure para imprimir en el puerto FILE.
  9. Haga clic de nuevo en Command1 y observe que aparece un cuadro de diálogo en Word. No descarte el cuadro de diálogo; espere cinco segundos y el cuadro de diálogo se descarta mediante programación al producirse el evento Timer. Un archivo de resultados denominado MyOutput.prn se crea en la subcarpeta Client.
Microsoft proporciona ejemplos de programación con fines ilustrativos únicamente, sin ninguna garantía tanto expresa como implícita, incluyendo, pero sin limitarse a, las garantías implícitas de comerciabilidad e idoneidad para un fin determinado. En este artículo se da por supuesto que ya conoce el lenguaje de programación que se muestra, así como las herramientas empleadas para crear y depurar procedimientos. Los profesionales de soporte técnico de Microsoft pueden explicarle la funcionalidad de un determinado procedimiento, pero no modificarán estos ejemplos para ofrecer mayor funcionalidad ni crearán procedimientos adaptados a sus necesidades específicas. Si tiene poca experiencia en programación, quizá desee ponerse en contacto con un Microsoft Certified Solution Partner o con la línea del servicio de consultoría que se ofrece, mediante pago, llamando al Centro de Atención al Cliente de Microsoft en el número 902 197 198. Para obtener más información acerca de los Certified Partners, consulte el siguiente sitio web de Microsoft:
https://partner.microsoft.com/global/30000104
Para obtener más información acerca de las opciones de soporte técnico disponibles y cómo ponerse en contacto con Microsoft, consulte el siguiente sitio web de Microsoft:
http://support.microsoft.com/contactus/?ws=support

Referencias

Para obtener más información, haga clic en los números de artículo siguientes para verlos en Microsoft Knowledge Base:
257757 Aspectos que hay que tener en cuenta para realizar la automatización de Office en el servidor
226118 OFF2000: Recursos de programación para Visual Basic para Aplicaciones
253235 ARCHIVO: Offautmn.exe describe automatización de Office 97 y 2000 y proporciona código de ejemplo
Para obtener información adicional sobre la automatización de Office, visite el centro de soporte técnico de desarrollo de Office en el sitio web de Microsoft siguiente:
http://support.microsoft.com/ofd

Propiedades

Id. de artículo: 259971 - Última revisión: jueves, 27 de diciembre de 2007 - Versión: 6.4
La información de este artículo se refiere a:
  • Microsoft Office Access 2003
  • Microsoft Access 2002 Standard Edition
  • Microsoft Access 2000 Standard Edition
  • Microsoft Access 97 Standard Edition
  • Microsoft Office Excel 2003
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition
  • Microsoft Office PowerPoint 2003
  • Microsoft PowerPoint 2002 Standard Edition
  • Microsoft PowerPoint 2000 Standard Edition
  • Microsoft PowerPoint 97 Standard Edition
  • Microsoft Office Word 2003
  • Microsoft Word 2002 Standard Edition
  • Microsoft Word 2000 Standard Edition
  • Microsoft Word 97 Standard Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
Palabras clave: 
kbautomation kbhowto kbprogramming KB259971

Enviar comentarios

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com