Simptomi

Kada pokušate koristiti GetObject (Microsoft Visual Basic) ili Getactiveobject (Microsoft Visual C++) da biste automatizirati aplikaciju sustava Microsoft Office, prikazat će vam se jedna od sljedećih poruka o pogrešci, iako je pokrenuta aplikacija sustava Office:

Poruka o pogrešci 1

Pogreška u pokretanju "429": ActiveX komponenta ne može stvarati objekt

Poruka o pogrešci 2

Pogreška: 0x800401i3 "operacija nije dostupna"

Uzrok

Iako je aplikacija sustava Office pokrenuta, možda nije registrirana u tablici pokrenut objekt (trune). Pokretanje instance aplikacije sustava Office mora biti registrirano u trulež prije nego što se može priložiti pomoću programa GetObject (Visual Basic) ili Getactiveobject (Visual C++). Kada započne aplikacija sustava Office, neće odmah registrirati svoje pokrenive objekte. Time se optimizirati postupak pokretanja aplikacije. Umjesto registracije pri pokretanju, aplikacija sustava Office registrira svoje pokrenuta objekte u trulež kada izgubi fokus. Dakle, ako pokušate koristiti GetObject ili Getactiveobject da biste priložili instancu izvođenja aplikacije sustava Office prije no što je aplikacija izgubila fokus, možda će vam se prikazati jedna od gore navedenih pogrešaka.

Rješenje

Pomoću koda možete promijeniti fokus iz aplikacije sustava Office u vlastitu aplikaciju (ili u neku drugu aplikaciju) da biste ga dopustili da se registrira u trulež. Uz to, ako vaš kod pokreće exe datoteku aplikacije sustava Office, možda ćete morati pričekati da se aplikacija sustava Office dovrši pri učitavanju prije nego što pokušate priložiti instancu izvođenja. Uzorak koda naveden je kao zaobilazno rješenje u odjeljku "Dodatne informacije".

Status

To je ponašanje prema dizajnu.

Dodatne informacije

U većini slučajeva programeri koji žele automatizirati aplikaciju sustava Office moraju koristiti CreateObject (Visual Basic) ili CoCreateInstance (Visual C++) da bi pokrenuli novu instancu aplikacije sustava Office. No postoje slučajevi u kojima biste radije automatizirati aplikaciju sustava Office koja je već pokrenuta: na primjer, ako je korisnik prethodno pokrenuo aplikaciju sustava Office. Ili, ako ste pokrenuli izvršnu aplikaciju sustava Office pomoću koda da biste mogli odrediti parametre naredbenog retka za aplikaciju. Da biste automatizirati pokretanje aplikacije sustava Office, morate koristiti objekt GetObject ili Getactiveobject.

Koraci za reprodukciju ponašanja

  1. Pokrenite Microsoft Visual Basic i stvorite novi standardni EXE Project. Form1 je po zadanom stvoren.

  2. Dodavanje kontrole Cmdbutton u Form1.

  3. U modul koda obrasca dodajte sljedeći kod.

    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 = NothingEnd Sub
  4. Provjerite je li mjesto programa Excel. exe ispravno u uzorku koda.

  5. Zatvorite Microsoft Excel ako je već pokrenut.

  6. Pritisnite F5 da biste pokrenuli projekt, a zatim kliknite Command1.

Zaobilazno rješenje

Da biste zaobišli problem, možete učiniti sljedeće:

  • Usredotočite se na aplikaciju sustava Office promjenom drugog argumenta funkcije Shell na vbMinimizedFocus, vbmaximizedfokusili vbnormalfokus.

  • U fokus Dajte svoj vizualni osnovni oblik.

  • Pokušajte GetObject tijekom računovodstva za vrijeme učitavanja aplikacije sustava Office.

Sljedeći izmijenjeni kod ilustrira ovo zaobilazno rješenje.

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 IfEnd Sub

Zaobilazno rješenje za C++

Ako ste programiranje u c + +, sljedeći uzorak koda pokazuje slično zaobilazno rješenje koje je prikazano u gornjem uzorku programa Visual Basic. Primijetite da se prozor Setforegroundkoristi da bi se fokus pomaknuo od programa Excel i omogućio mu da registrira svoje pokrenite objekte.

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

Reference

Dodatne informacije potražite u člancima iz Microsoftove baze znanja pod sljedećim brojevima:

192919 Automatsko automatizacija sigurne baze podataka programa Access pomoću značajke Visual Basic

237338 Poruka o pogrešci pomoću WordMailove: "Ova metoda ili svojstvo nisu dostupni"

240794 Određivanje puta aplikacije sustava Office

Potrebna vam je dodatna pomoć?

Proširite svoje vještine
Istražite osposobljavanje
Prvi koristite nove značajke
Pridružite se Microsoft Insidere

Jesu li ove informacije bile korisne?

Koliko ste zadovoljni kvalitetom prijevoda?

Što je utjecalo na vaše iskustvo?

Imate li još povratnih informacija? (Neobavezno)

Hvala vam na povratnim informacijama!

×