Se connecter avec Microsoft
S'identifier ou créer un compte.
Bonjour,
Sélectionnez un autre compte.
Vous avez plusieurs comptes
Choisissez le compte avec lequel vous voulez vous connecter.

Symptômes

Lorsque vous essayez d’utiliser GetObject (Microsoft Visual Basic) ou GetActiveObject (Microsoft Visual C++) pour automatiser une application Microsoft Office, vous recevez l’un des messages d’erreur suivants, même si l’application Office est en cours d’exécution :

Message d’erreur 1

Erreur d’exécution « 429 » :
Le composant ActiveX ne peut pas créer d’objet

Message d’erreur 2

Erreur : 0x800401e3 « Opération non disponible »

Cause

Bien que l’application Office soit en cours d’exécution, elle n’est peut-être pas inscrite dans la table d’objets en cours d’exécution (ROT). Un instance en cours d’exécution d’une application Office doit être inscrit dans le ROT avant de pouvoir être attaché à l’aide de GetObject (Visual Basic) ou GetActiveObject (Visual C++).

Lorsqu’une application Office démarre, elle n’inscrit pas immédiatement ses objets en cours d’exécution. Cela optimise le processus de démarrage de l’application. Au lieu de s’inscrire au démarrage, une application Office inscrit ses objets en cours d’exécution dans le ROT une fois qu’elle perd le focus. Par conséquent, si vous essayez d’utiliser GetObject ou GetActiveObject pour attacher à un instance en cours d’exécution d’une application Office avant que l’application n’ait perdu le focus, vous pouvez recevoir l’une des erreurs ci-dessus.

Résolution

À l’aide du code, vous pouvez passer de l’application Office à votre propre application (ou à une autre application) pour lui permettre de s’inscrire dans le ROT. En outre, si votre code lance le fichier exe de l’application Office, vous devrez peut-être attendre la fin du chargement de l’application Office avant de tenter de l’attacher à l’instance en cours d’exécution. Un exemple de code est fourni comme solution de contournement dans la section « Plus d’informations ».

État

Ce comportement est inhérent au produit.

Informations supplémentaires

Dans la plupart des cas, les développeurs qui souhaitent automatiser une application Office doivent utiliser CreateObject (Visual Basic) ou CoCreateInstance (Visual C++) pour lancer une nouvelle instance de l’application Office.

Toutefois, dans certains cas, vous pouvez préférer automatiser une application Office qui est déjà en cours d’exécution : par exemple, si l’utilisateur a déjà démarré l’application Office. Ou, si vous avez lancé l’exécutable de l’application Office à l’aide de code afin de pouvoir spécifier des commutateurs de ligne de commande pour l’application. Pour automatiser l’application Office en cours d’exécution, vous devez utiliser GetObject ou GetActiveObject.

Étapes pour reproduire le comportement

  1. Démarrez Microsoft Visual Basic et créez un projet EXE Standard. Form1 est créé par défaut.

  2. Ajoutez un contrôle CommandButton à Form1.

  3. Ajoutez le code suivant au module de code du formulaire.

    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. Vérifiez que l’emplacement de l'Excel.exe est correct dans l’exemple de code.

  5. Quittez Microsoft Excel s’il est déjà en cours d’exécution.

  6. Appuyez sur F5 pour exécuter le projet, puis cliquez sur Commande1.

Solution de contournement 

Pour contourner le problème, vous pouvez :

  • Donnez le focus à l’application Office en remplaçant le deuxième argument de la fonction Shell par vbMinimizedFocus, vbMaximizedFocus ou vbNormalFocus.

  • Donnez le focus à votre formulaire Visual Basic.

  • Essayez GetObject tout en tenant compte du temps de chargement de l’application Office.

Le code révisé suivant illustre cette solution de contournement.

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

Solution de contournement pour C++

Si vous programmez en C++, l’exemple de code suivant illustre une solution de contournement similaire à celle présentée dans l’exemple Visual Basic ci-dessus. Notez que SetForegroundWindow est utilisé pour éloigner le focus d’Excel, ce qui lui permet d’inscrire ses objets en cours d’exécution.

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

Références

Pour plus d’informations, cliquez sur les numéros d’article suivants pour afficher l’article :

Comment trouver le chemin d’installation d’une application Office

Besoin d’aide ?

Vous voulez plus d’options ?

Explorez les avantages de l’abonnement, parcourez les cours de formation, découvrez comment sécuriser votre appareil, etc.

Les communautés vous permettent de poser des questions et d'y répondre, de donner vos commentaires et de bénéficier de l'avis d'experts aux connaissances approfondies.

Ces informations vous ont-elles été utiles ?

Dans quelle mesure êtes-vous satisfait(e) de la qualité de la langue ?
Qu’est-ce qui a affecté votre expérience ?
En cliquant sur Envoyer, vos commentaires seront utilisés pour améliorer les produits et services de Microsoft. Votre administrateur informatique sera en mesure de collecter ces données. Déclaration de confidentialité.

Nous vous remercions de vos commentaires.

×