Conectați-vă cu Microsoft
Conectați-vă sau creați un cont
Salut,
Selectați un alt cont.
Aveți mai multe conturi
Alegeți contul cu care doriți să vă conectați.

Simptome

Atunci când încercați să utilizați GetObject (Microsoft Visual Basic) sau GetActiveObject (Microsoft Visual C++) pentru a automatiza o aplicație Microsoft Office, primiți unul dintre următoarele mesaje de eroare, chiar dacă aplicația Office rulează:

Mesaj de eroare 1

Eroarea Run-Time ' 429 ': componenta ActiveX nu poate crea un obiect

Mesaj de eroare 2

Eroare: 0x800401e3 "Operațiunea nu este disponibilă"

Cauză

Deși aplicația Office rulează, este posibil să nu fie înregistrată în tabelul obiect care rulează (ROT). O instanță de rulare a unei aplicații Office trebuie să fie înregistrată în putregai înainte să poată fi atașată la utilizarea GetObject (Visual Basic) sau GetActiveObject (Visual C++). Atunci când pornește o aplicație Office, aceasta nu înregistrează imediat obiectele sale în execuție. Acest lucru optimizează procesul de pornire al aplicației. În loc să se înregistreze la pornire, o aplicație Office își înregistrează obiectele care se execută în putregai după ce pierde focalizarea. Prin urmare, dacă încercați să utilizați GetObject sau GetActiveObject pentru a atașa la o instanță curentă a unei aplicații Office înainte ca aplicația să piardă focalizarea, este posibil să primiți una dintre erorile de mai sus.

Rezolvare

Utilizând codul, puteți să modificați focalizarea de la aplicația Office la propria aplicație (sau la altă aplicație) pentru a-i permite să se înregistreze în putregai. În plus, dacă codul lansează fișierul exe al aplicației Office, poate fi necesar să așteptați ca aplicația Office să termine încărcarea înainte de a încerca să atașați la instanța care rulează. Un eșantion de cod este furnizat ca soluție de evitare în secțiunea "mai multe informații".

Stare

Acest comportament este proiectat.

Mai multe informații

În majoritatea situațiilor, dezvoltatorii care doresc să automatizați o aplicație Office trebuie să utilizeze funcția (Visual Basic) sau CoCreateInstance (Visual C++) pentru a lansa o instanță nouă a aplicației Office. Cu toate acestea, există cazuri în care este posibil să preferați să automatizați o aplicație Office care rulează deja: de exemplu, dacă utilizatorul a pornit anterior aplicația Office. Sau, dacă ați lansat executabilul aplicației Office utilizând codul, astfel încât să puteți specifica argumentele din linia de comandă pentru aplicație. Pentru a automatiza aplicația Office care funcționează, trebuie să utilizați GetObject sau GetActiveObject.

Pașii pentru reproducerea comportamentului

  1. Porniți Microsoft Visual Basic și creați un nou proiect standard EXE. Form1 este creat în mod implicit.

  2. Adăugați un control CommandButton la Form1.

  3. Adăugați următorul cod la modulul cod al formularului.

    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. Asigurați-vă că locația Excel. exe este corectă în eșantionul de cod.

  5. Închideți Microsoft Excel dacă rulează deja.

  6. Apăsați F5 pentru a executa proiectul și faceți clic pe Command1.

Soluție de evitare

Pentru a rezolva problema, puteți să:

  • Dați atenție aplicației Office modificând al doilea argument al funcției Shell la vbMinimizedFocus, vbMaximizedFocussau vbNormalFocus.

  • Dați focalizarea la forma vizuală.

  • Încercați GetObject în timp ce se calculează timpul de încărcare al aplicației Office.

Următorul cod revizuit ilustrează această soluție.

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

Soluție pentru C++

Dacă programați în C++, următorul exemplu de cod demonstrează o soluție similară cu cea afișată în eșantionul Visual Basic de mai sus. Observați că SetForegroundWindow este utilizat pentru a muta focalizarea în afara Excel, permițându-i să își înregistreze obiectele în execuție.

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

Referințe

Pentru informaţii suplimentare, faceţi clic pe următoarele numere de articole pentru a le vizualiza în Baza de cunoştinţe Microsoft:

192919 Cum se automatizează o bază de date Access securizată utilizând Visual Basic

237338 Mesaj de eroare utilizând WordMail: "această metodă sau proprietate nu este disponibilă"

240794 Cum se determină calea pentru o aplicație Office

Aveți nevoie de ajutor suplimentar?

Doriți mai multe opțiuni?

Explorați avantajele abonamentului, navigați prin cursurile de instruire, aflați cum să vă securizați dispozitivul și multe altele.

Comunitățile vă ajută să adresați întrebări și să răspundeți la întrebări, să oferiți feedback și să primiți feedback de la experți cu cunoștințe bogate.

Au fost utile aceste informații?

Cât de mulțumit sunteți de calitatea limbajului?
Ce v-a afectat experiența?
Apăsând pe Trimitere, feedbackul dvs. va fi utilizat pentru a îmbunătăți produsele și serviciile Microsoft. Administratorul dvs. IT va avea posibilitatea să colecteze aceste date. Angajamentul de respectare a confidențialității.

Vă mulțumim pentru feedback!

×