Bei Microsoft anmelden
Melden Sie sich an, oder erstellen Sie ein Konto.
Hallo,
Wählen Sie ein anderes Konto aus.
Sie haben mehrere Konten.
Wählen Sie das Konto aus, mit dem Sie sich anmelden möchten.

Problembeschreibung

Wenn Sie versuchen, GetObject (Microsoft Visual Basic) oder GetActiveObject (Microsoft Visual C++) zum Automatisieren einer Microsoft Office-Anwendung zu verwenden, erhalten Sie eine der folgenden Fehlermeldungen, obwohl die Office-Anwendung ausgeführt wird:

Fehlermeldung 1

Laufzeitfehler "429":
ActiveX-Komponente kann kein Objekt erstellen

Fehlermeldung 2

Fehler: 0x800401e3 "Vorgang nicht verfügbar"

Ursache

Obwohl die Office-Anwendung ausgeführt wird, ist sie möglicherweise nicht in der Running Object Table (ROT) registriert. Eine ausgeführte instance einer Office-Anwendung muss im ROT registriert werden, bevor sie mithilfe von GetObject (Visual Basic) oder GetActiveObject (Visual C++) angefügt werden kann.

Wenn eine Office-Anwendung gestartet wird, registriert sie ihre ausgeführten Objekte nicht sofort. Dadurch wird der Startprozess der Anwendung optimiert. Anstatt sich beim Start zu registrieren, registriert eine Office-Anwendung ihre ausgeführten Objekte im ROT, sobald sie den Fokus verliert. Wenn Sie daher versuchen, GetObject oder GetActiveObject zum Anfügen an eine ausgeführte instance einer Office-Anwendung zu verwenden, bevor die Anwendung den Fokus verloren hat, erhalten Sie möglicherweise einen der obigen Fehler.

Lösung

Mithilfe von Code können Sie den Fokus von der Office-Anwendung auf Ihre eigene Anwendung (oder auf eine andere Anwendung) ändern, damit sie sich selbst im ROT registrieren kann. Wenn Ihr Code die EXE-Datei der Office-Anwendung startet, müssen Sie außerdem möglicherweise warten, bis der Ladevorgang der Office-Anwendung abgeschlossen ist, bevor Sie versuchen, an die ausgeführte instance anzufügen. Ein Codebeispiel wird als Problemumgehung im Abschnitt "Weitere Informationen" bereitgestellt.

Status

Es handelt sich hierbei um ein beabsichtigtes Verhalten.

Weitere Informationen

In den meisten Fällen müssen Entwickler, die eine Office-Anwendung automatisieren möchten, CreateObject (Visual Basic) oder CoCreateInstance (Visual C++) verwenden, um eine neue instance der Office-Anwendung zu starten.

Es gibt jedoch Fälle, in denen Sie es vorziehen, eine bereits ausgeführte Office-Anwendung zu automatisieren, z. B. wenn der Benutzer die Office-Anwendung zuvor gestartet hat. Oder wenn Sie die ausführbare Datei der Office-Anwendung mithilfe von Code gestartet haben, damit Sie Befehlszeilenoptionen für die Anwendung angeben können. Um die ausgeführte Office-Anwendung zu automatisieren, müssen Sie GetObject oder GetActiveObject verwenden.

Schritte zum Reproduzieren des Verhaltens

  1. Starten Sie Microsoft Visual Basic, und erstellen Sie ein neues Standard EXE-Projekt. Form1 wird standardmäßig erstellt.

  2. Fügen Sie ein CommandButton-Steuerelement zu Form1 hinzu.

  3. Fügen Sie dem Codemodul des Formulars den folgenden Code hinzu.

    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. Stellen Sie sicher, dass der Speicherort der Excel.exe im Codebeispiel korrekt ist.

  5. Beenden Sie Microsoft Excel, wenn es bereits ausgeführt wird.

  6. Drücken Sie F5, um das Projekt auszuführen, und klicken Sie auf Befehl1.

Problemumgehung 

Um das Problem zu umgehen, haben Sie folgende Möglichkeiten:

  • Geben Sie der Office-Anwendung den Fokus, indem Sie das zweite Argument der Shell-Funktion in vbMinimizedFocus, vbMaximizedFocus oder vbNormalFocus ändern.

  • Geben Sie Ihrem Visual Basic-Formular den Fokus.

  • Versuchen Sie getObject, während die Ladezeit der Office-Anwendung berücksichtigt wird.

Der folgende überarbeitete Code veranschaulicht diese Problemumgehung.

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

Problemumgehung für C++

Wenn Sie in C++ programmieren, veranschaulicht das folgende Codebeispiel eine ähnliche Problemumgehung wie im obigen Visual Basic-Beispiel. Beachten Sie, dass SetForegroundWindow verwendet wird, um den Fokus von Excel weg zu verschieben, sodass die ausgeführten Objekte registriert werden können.

//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();

Informationsquellen

Weitere Informationen finden Sie, indem Sie auf die folgenden Artikelnummern klicken, um den Artikel anzuzeigen:

Ermitteln des Installationspfads einer Office-Anwendung

Benötigen Sie weitere Hilfe?

Möchten Sie weitere Optionen?

Erkunden Sie die Abonnementvorteile, durchsuchen Sie Trainingskurse, erfahren Sie, wie Sie Ihr Gerät schützen und vieles mehr.

In den Communities können Sie Fragen stellen und beantworten, Feedback geben und von Experten mit umfassendem Wissen hören.

War diese Information hilfreich?

Wie zufrieden sind Sie mit der Sprachqualität?
Was hat Ihre Erfahrung beeinflusst?
Wenn Sie auf "Absenden" klicken, wird Ihr Feedback zur Verbesserung von Produkten und Diensten von Microsoft verwendet. Ihr IT-Administrator kann diese Daten sammeln. Datenschutzbestimmungen.

Vielen Dank für Ihr Feedback!

×