Logg på med Microsoft
Logg på, eller opprett en konto.
Hei,
Velg en annen konto.
Du har flere kontoer
Velg kontoen du vil logge på med.

Symptomer

Når du prøver å bruke GetObject (Microsoft Visual Basic) eller GetActiveObject (Microsoft Visual C++) til å automatisere et Microsoft Office-program, får du en av følgende feilmeldinger, selv om Office-programmet kjører:

Feilmelding 1

Kjøretidsfeil 429:
ActiveX-komponenten kan ikke opprette objekt

Feilmelding 2

Feil: 0x800401e3 «Operasjonen er ikke tilgjengelig»

Årsak

Selv om Office-programmet kjører, kan det hende det ikke er registrert i rot-tabellen (Running Object Table). En kjørende forekomst av et Office-program må være registrert i ROT før det kan knyttes til ved hjelp av GetObject (Visual Basic) eller GetActiveObject (Visual C++).

Når et Office-program starter, registreres ikke objektene som kjører umiddelbart. Dette optimaliserer programmets oppstartsprosess. I stedet for å registrere seg ved oppstart, registrerer et Office-program sine kjørende objekter i ROT når det mister fokus. Hvis du prøver å bruke GetObject eller GetActiveObject til å knytte til en kjørende forekomst av et Office-program før programmet har mistet fokus, kan det hende du får en av feilene ovenfor.

Løsning

Ved hjelp av kode kan du endre fokus fra Office-programmet til ditt eget program (eller til et annet program) slik at det kan registrere seg i roten. I tillegg, hvis koden starter Office-programmets exe-fil, må du kanskje vente til Office-programmet er ferdig med innlastingen før du prøver å knytte til den kjørende forekomsten. Et kodeeksempel er angitt som en midlertidig løsning i delen Mer informasjon.

Status

Denne virkemåten er etter utforming.

Mer informasjon

I de fleste tilfeller må utviklere som vil automatisere et Office-program, bruke CreateObject (Visual Basic) eller CoCreateInstance (Visual C++) til å starte en ny forekomst av Office-programmet.

Det finnes imidlertid tilfeller der du kanskje foretrekker å automatisere et Office-program som allerede kjører, for eksempel hvis brukeren tidligere startet Office-programmet. Eller, hvis du startet Office-programmets kjørbare kode, slik at du kan angi kommandolinjebrytere for programmet. Hvis du vil automatisere office-programmet som kjører, må du bruke GetObject eller GetActiveObject.

Trinn for å gjenskape virkemåten

  1. Start Microsoft Visual Basic, og opprett et nytt Standard EXE-prosjekt. Skjema1 er opprettet som standard.

  2. Legg til en CommandButton-kontroll i Skjema1.

  3. Legg til følgende kode i skjemaets kodemodul.

    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. Kontroller at plasseringen av Excel.exe er riktig i kodeeksempelet.

  5. Avslutt Microsoft Excel hvis det allerede kjører.

  6. Trykk F5 for å kjøre prosjektet, og klikk Kommando1.

Omgå problemet

Hvis du vil omgå problemet, kan du:

  • Gi fokus til Office-programmet ved å endre det andre argumentet i Shell-funksjonen til vbMinimizedFocus, vbMaximizedFocus eller vbNormalFocus.

  • Gi Visual Basic-skjemaet fokus.

  • Prøv GetObject mens du tar høyde for innlastingstiden for Office-programmet.

Følgende reviderte kode illustrerer denne midlertidige løsningen.

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

Midlertidig løsning for C++

Hvis du programmerer i C++, viser følgende kodeeksempel en lignende løsning som vist i visual basic-eksemplet ovenfor. Legg merke til at SetForegroundWindow brukes til å flytte fokus bort fra Excel, slik at den kan registrere objekter som kjører.

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

Referanser

Hvis du vil ha mer informasjon, klikker du følgende artikkelnumre for å vise artikkelen:

Slik finner du installasjonsbanen til et Office-program

Trenger du mer hjelp?

Vil du ha flere alternativer?

Utforsk abonnementsfordeler, bla gjennom opplæringskurs, finn ut hvordan du sikrer enheten og mer.

Fellesskap hjelper deg med å stille og svare på spørsmål, gi tilbakemelding og høre fra eksperter med stor kunnskap.

Var denne informasjonen nyttig?

Hvor fornøyd er du med språkkvaliteten?
Hva påvirket opplevelsen din?
Når du trykker på Send inn, blir tilbakemeldingen brukt til å forbedre Microsoft-produkter og -tjenester. IT-administratoren kan samle inn disse dataene. Personvernerklæring.

Takk for tilbakemeldingen!

×