Iniciar sesión con Microsoft
Iniciar sesión o crear una cuenta
Hola:
Seleccione una cuenta diferente.
Tiene varias cuentas
Elija la cuenta con la que desea iniciar sesión.

Síntomas

Cuando intenta usar GetObject (Microsoft Visual Basic) o GetActiveObject (Microsoft Visual C++) para automatizar una aplicación de Microsoft Office, recibe uno de los siguientes mensajes de error, aunque la aplicación de Office se esté ejecutando:

Mensaje de error 1

Error en tiempo de ejecución '429':
El componente ActiveX no puede crear un objeto

Mensaje de error 2

Error: 0x800401e3 "Operación no disponible"

Causa

Aunque la aplicación de Office se está ejecutando, es posible que no esté registrada en la tabla de objetos en ejecución (ROT). Una instancia en ejecución de una aplicación de Office debe registrarse en el ROT antes de que se pueda adjuntar con GetObject (Visual Basic) o GetActiveObject (Visual C++).

Cuando se inicia una aplicación de Office, no registra inmediatamente sus objetos en ejecución. Esto optimiza el proceso de inicio de la aplicación. En lugar de registrarse en el inicio, una aplicación de Office registra sus objetos en ejecución en el ROT una vez que pierde el foco. Por lo tanto, si intenta usar GetObject o GetActiveObject para adjuntar a una instancia en ejecución de una aplicación de Office antes de que la aplicación haya perdido el foco, es posible que reciba uno de los errores anteriores.

Solución

Con el código, puede cambiar el enfoque de la aplicación de Office a su propia aplicación (o a alguna otra aplicación) para permitirle registrarse en el ROT. Además, si el código está iniciando el archivo exe de la aplicación de Office, es posible que tenga que esperar a que la aplicación de Office termine de cargarse antes de intentar adjuntar a la instancia en ejecución. Se proporciona un ejemplo de código como solución alternativa en la sección "Más información".

Estado

Este comportamiento es una característica del diseño de la aplicación.

Más información

En la mayoría de las situaciones, los desarrolladores que quieren automatizar una aplicación de Office necesitan usar CreateObject (Visual Basic) o CoCreateInstance (Visual C++) para iniciar una nueva instancia de la aplicación de Office.

Sin embargo, hay casos en los que es posible que prefiera automatizar una aplicación de Office que ya se está ejecutando: por ejemplo, si el usuario inició anteriormente la aplicación de Office. O bien, si inició el ejecutable de la aplicación de Office con código para que pueda especificar modificadores de línea de comandos para la aplicación. Para automatizar la aplicación de Office en ejecución, debe usar GetObject o GetActiveObject.

Pasos para reproducir este comportamiento

  1. Inicie Microsoft Visual Basic y cree un nuevo proyecto EXE estándar. El formulario1 se crea de forma predeterminada.

  2. Agregue un control CommandButton a Form1.

  3. Agregue el código siguiente al módulo de código del formulario.

    Private Sub Command1_Click()
        Dim oExcel As Object
        ' Launch a new instance of Microsoft Excel:
        Shell "C:\Program Files\Microsoft Office\Office\Excel.EXE", _
           vbMinimizedNoFocus
        ' An error 429 occurs on the following line:
        Set oExcel = GetObject(, "Excel.Application")
        MsgBox oExcel.Name
        Set oExcel = Nothing
    End Sub
    
  4. Asegúrese de que la ubicación de la Excel.exe sea correcta en el ejemplo de código.

  5. Salga de Microsoft Excel si ya se está ejecutando.

  6. Presione F5 para ejecutar el proyecto y haga clic en Comando1.

Solución alternativa 

Para solucionar el problema, puedes:

  • Para centrarse en la aplicación de Office, cambie el segundo argumento de la función Shell a vbMinimizedFocus, vbMaximizedFocus o vbNormalFocus.

  • Céntrese en el formulario de Visual Basic.

  • Intente ObtenerObjeto mientras realiza la contabilidad del tiempo de carga de la aplicación de Office.

El siguiente código revisado ilustra esta solución alternativa.

Private Declare Sub Sleep Lib "kernel32" _
    (ByVal dwMilliseconds As Long)

Private Sub Command1_Click()
    Dim intSection As Integer
    Dim intTries As Integer
    Dim oExcel As Object

    ' Enable error handler for this procedure:
    On Error GoTo ErrorHandler

    ' Launch Microsoft Excel, giving it focus:
    Shell "C:\Program Files\Microsoft Office\Office\Excel.EXE", _
        vbMinimizedFocus 'other options for starting with
        'focus: vbMaximizedFocus and vbNormalFocus

    ' Move focus back to this form. (This ensures the Office
    '  application registers itself in the ROT, allowing
    '  GetObject to find it.)
    Me.SetFocus

    ' Attempt to use GetObject to reference the running
    '  Office application:
    intSection = 1 'attempting GetObject...
    Set oExcel = GetObject(, "Excel.Application")
    intSection = 0 'resume normal error handling

    ' Now you can automate Microsoft Excel:
    MsgBox oExcel.Name & ": able to GetObject after " & _
        intTries + 1 & " tries.", vbMsgBoxSetForeground

    ' Finished with automation so release your reference:
    Set oExcel = Nothing

    ' Exit procedure:
    Exit Sub

ErrorHandler:
    If intSection = 1 Then 'GetObject may have failed because the
    'Shell function is asynchronous; enough time has not elapsed
    'for GetObject to find the running Office application. Wait
    'wait 1/2 seconds and retry the GetObject. If you try 20 times
    'and GetObject still fails, assume some other reason
    'for GetObject failing and exit the procedure.
        intTries = intTries + 1
        If intTries < 20 Then
            Sleep 500 ' wait 1/2 seconds
            Resume 'resume code at the GetObject line
        Else
            MsgBox "GetObject still failing. Process ended.", _
                vbMsgBoxSetForeground
        End If
    Else 'intSection = 0 so use normal error handling:
        MsgBox Error$
    End If
End Sub

Solución alternativa para C++

Si está programando en C++, en el ejemplo de código siguiente se muestra una solución alternativa similar a la que se muestra en el ejemplo anterior de Visual Basic. Observe que SetForegroundWindow se usa para alejar el foco de Excel, lo que le permite registrar sus objetos en ejecución.

//Store the handle of the currently active window...
HWND hwndCurrent = ::GetForegroundWindow();

//Launch Excel and wait until it is waiting for
//user input...
STARTUPINFO Start;
PROCESS_INFORMATION ProcInfo;
ZeroMemory(&Start,sizeof(STARTUPINFO));
Start.cb=sizeof(Start);
Start.dwFlags = STARTF_USESHOWWINDOW;
Start.wShowWindow = SW_SHOWMINIMIZED;

//Change the path to Excel as needed...
LPSTR pszExcelPath = 
      "c:\\program files\\microsoft office\\office\\excel.exe";

::CreateProcess(NULL, pszExcelPath, 0, 0, 1,
       NORMAL_PRIORITY_CLASS, 0, NULL, &Start, &ProcInfo);


if((::WaitForInputIdle(ProcInfo.hProcess, 10000))==WAIT_TIMEOUT)
{
    ::MessageBox(NULL, "Timed out waiting for Excel.", NULL,  
                 MB_OK);
}

//Restore the active window to the foreground...
//  NOTE: If you comment out this line, the code will fail!
::SetForegroundWindow(hwndCurrent);

//Initialize COM library...
::CoInitialize(NULL);

//Attach to the running instance...
CLSID clsid;
CLSIDFromProgID(L"Excel.Application", &clsid);  
IUnknown *pUnk = NULL;
IDispatch *pDisp = NULL;

for(int i=1;i<=5;i++) //try attaching for up to 5 attempts
{
   HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
   if(SUCCEEDED(hr)) 
   {
       hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pDisp);
       break;
   }
   ::Sleep(1000);
}

if (!pDisp) {
    ::MessageBox(NULL, "Failed to find instance!!", "Error", 
                 MB_ICONHAND);
}
else {
    ::MessageBox(NULL, "Got instance of Excel!", "Success", MB_OK);
}

//Release the no-longer-needed IUnknown...
if (pUnk) 
    pUnk->Release();

//... Add your automation code for Excel here ...

//Release pDisp when no longer needed...
if (pDisp)
    pDisp->Release();

//Cleanup COM...
CoUninitialize();

Referencias

Para obtener más información, haga clic en los números de artículo siguientes para verlos:

Cómo encontrar la ruta de instalación de una aplicación de Office

¿Necesita más ayuda?

¿Quiere más opciones?

Explore las ventajas de las suscripciones, examine los cursos de aprendizaje, aprenda a proteger su dispositivo y mucho más.

Las comunidades le ayudan a formular y responder preguntas, enviar comentarios y leer a expertos con conocimientos extensos.

¿Le ha sido útil esta información?

¿Cuál es tu grado de satisfacción con la calidad del lenguaje?
¿Qué ha afectado a su experiencia?
Si presiona Enviar, sus comentarios se usarán para mejorar los productos y servicios de Microsoft. El administrador de TI podrá recopilar estos datos. Declaración de privacidad.

¡Gracias por sus comentarios!

×