Aanmelden met Microsoft
Meld u aan of maak een account.
Hallo,
Selecteer een ander account.
U hebt meerdere accounts
Kies het account waarmee u zich wilt aanmelden.

Symptomen

Wanneer u GetObject (Microsoft Visual Basic) of GetActiveObject (Microsoft Visual C++) probeert te gebruiken om een Microsoft Office-toepassing te automatiseren, krijgt u een van de volgende foutberichten, ook al wordt de Office-toepassing uitgevoerd:

Foutbericht 1

Runtimefout '429':
ActiveX-onderdeel kan geen object maken

Foutbericht 2

Fout: 0x800401e3 'Bewerking niet beschikbaar'

Oorzaak

Hoewel de Office-toepassing wordt uitgevoerd, is deze mogelijk niet geregistreerd in de Running Object Table (ROT). Een actief exemplaar van een Office-toepassing moet zijn geregistreerd in de ROT voordat deze kan worden gekoppeld met behulp van GetObject (Visual Basic) of GetActiveObject (Visual C++).

Wanneer een Office-toepassing wordt gestart, worden de actieve objecten niet onmiddellijk geregistreerd. Dit optimaliseert het opstartproces van de toepassing. In plaats van zich bij het opstarten te registreren, registreert een Office-toepassing de actieve objecten in de ROT zodra deze de focus verliest. Als u GetObject of GetActiveObject probeert te gebruiken om te koppelen aan een actief exemplaar van een Office-toepassing voordat de focus van de toepassing is verloren, kan een van de bovenstaande fouten worden weergegeven.

Oplossing

Met behulp van code kunt u de focus van de Office-toepassing wijzigen in uw eigen toepassing (of naar een andere toepassing) zodat deze zichzelf kan registreren in de ROT. Als uw code het exe-bestand van de Office-toepassing start, moet u mogelijk wachten totdat de Office-toepassing is geladen voordat u een verbinding probeert te maken met het actieve exemplaar. In de sectie 'Meer informatie' vindt u een codevoorbeeld als tijdelijke oplossing.

Status

Dit gedrag is inherent aan het ontwerp van het product.

Meer informatie

In de meeste gevallen moeten ontwikkelaars die een Office-toepassing willen automatiseren CreateObject (Visual Basic) of CoCreateInstance (Visual C++) gebruiken om een nieuw exemplaar van de Office-toepassing te starten.

Er zijn echter gevallen waarin u liever een Office-toepassing wilt automatiseren die al wordt uitgevoerd, bijvoorbeeld als de gebruiker de Office-toepassing eerder heeft gestart. Of als u het uitvoerbare bestand van de Office-toepassing hebt gestart met behulp van code, zodat u opdrachtregelopties voor de toepassing kunt opgeven. Als u de actieve Office-toepassing wilt automatiseren, moet u GetObject of GetActiveObject gebruiken.

Stappen om het gedrag te reproduceren

  1. Start Microsoft Visual Basic en maak een nieuw Standard EXE-project. Form1 wordt standaard gemaakt.

  2. Voeg een besturingselement CommandButton toe aan Form1.

  3. Voeg de volgende code toe aan de codemodule van het formulier.

    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. Zorg ervoor dat de locatie van de Excel.exe juist is in het codevoorbeeld.

  5. Sluit Microsoft Excel af als deze al wordt uitgevoerd.

  6. Druk op F5 om het project uit te voeren en klik op Command1.

Tijdelijke oplossing

Als u het probleem wilt omzeilen, kunt u het volgende doen:

  • Geef de focus op de Office-toepassing door het tweede argument van de shell-functie te wijzigen in vbMinimizedFocus, vbMaximizedFocus of vbNormalFocus.

  • Geef uw Visual Basic-formulier de focus.

  • Probeer GetObject uit te voeren terwijl u de laadtijd van de Office-toepassing controleert.

De volgende herziene code illustreert deze tijdelijke oplossing.

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

Tijdelijke oplossing voor C++

Als u in C++ programmeert, laat het volgende codevoorbeeld een vergelijkbare tijdelijke oplossing zien als in het bovenstaande Visual Basic-voorbeeld. U ziet dat SetForegroundWindow wordt gebruikt om de focus van Excel te verplaatsen, zodat de actieve objecten kunnen worden geregistreerd.

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

Verwijzingen

Klik voor meer informatie op de volgende artikelnummers om het artikel weer te geven:

Het installatiepad van een Office-toepassing vinden

Meer hulp nodig?

Meer opties?

Verken abonnementsvoordelen, blader door trainingscursussen, leer hoe u uw apparaat kunt beveiligen en meer.

Community's helpen u vragen te stellen en te beantwoorden, feedback te geven en te leren van experts met uitgebreide kennis.

Was deze informatie nuttig?

Hoe tevreden bent u met de taalkwaliteit?
Wat heeft uw ervaring beïnvloed?
Als u op Verzenden klikt, wordt uw feedback gebruikt om producten en services van Microsoft te verbeteren. Uw IT-beheerder kan deze gegevens verzamelen. Privacyverklaring.

Hartelijk dank voor uw feedback.

×