Συμπτώματα

Όταν προσπαθείτε να χρησιμοποιήσετε το GetObject (Microsoft Visual Basic) ή το GetActiveObject (Microsoft Visual C++) για να αυτοματοποιήσετε μια εφαρμογή του Microsoft Office, λαμβάνετε ένα από τα ακόλουθα μηνύματα σφάλματος, ακόμα και αν εκτελείται η εφαρμογή του Office:

Μήνυμα σφάλματος 1

Σφάλμα χρόνου εκτέλεσης '429': Το στοιχείο ActiveX δεν μπορεί να δημιουργήσει αντικείμενο

Μήνυμα σφάλματος 2

Σφάλμα: 0x800401e3 "Η λειτουργία δεν είναι διαθέσιμη"

Αιτία

Παρόλο που η εφαρμογή του Office εκτελείται, ενδέχεται να μην έχει καταχωρηθεί στον Πίνακα αντικειμένων που εκτελείται (ROT). Μια τρέχουσα παρουσία μιας εφαρμογής του Office πρέπει να έχει καταχωρηθεί στη ΣΉΨΗ για να μπορέσει να συνδεθεί με τη χρήση του GetObject (Visual Basic) ή του GetActiveObject (Visual C++).Όταν μια εφαρμογή του Office ξεκινά, δεν καταχωρεί αμέσως τα αντικείμενα που εκτελούνται. Αυτό βελτιστοποιεί τη διαδικασία εκκίνησης της εφαρμογής. Αντί να εγγραφεί κατά την εκκίνηση, μια εφαρμογή του Office καταχωρεί τα αντικείμενα που εκτελούνται στη ΣΉΨΗ όταν χάσει την εστίαση. Επομένως, εάν προσπαθήσετε να χρησιμοποιήσετε το GetObject ή το GetActiveObject για να επισυνάψετε σε μια τρέχουσα παρουσία μιας εφαρμογής του Office πριν η εφαρμογή χάσει την εστίαση, ενδέχεται να λάβετε ένα από τα παραπάνω σφάλματα.

Επίλυση

Χρησιμοποιώντας κώδικα, μπορείτε να αλλάξετε την εστίαση από την εφαρμογή του Office στη δική σας εφαρμογή (ή σε κάποια άλλη εφαρμογή) για να της επιτρέψετε να καταχωρηθεί στη ΣΉΨΗ. Επιπλέον, εάν ο κώδικάς σας εκκινεί το αρχείο exe της εφαρμογής του Office, ίσως χρειαστεί να περιμένετε μέχρι να ολοκληρωθεί η φόρτωση της εφαρμογής του Office πριν προσπαθήσετε να επισυνάψετε την παρουσία που εκτελείται. Ένα δείγμα κώδικα παρέχεται ως λύση στην ενότητα "Περισσότερες πληροφορίες".

Κατάσταση

Αυτή η συμπεριφορά οφείλεται στη σχεδίαση.

Περισσότερες πληροφορίες

Στις περισσότερες περιπτώσεις, οι προγραμματιστές που θέλουν να αυτοματοποιήσουν μια εφαρμογή του Office πρέπει να χρησιμοποιήσουν το CreateObject (Visual Basic) ή το CoCreateInstance (Visual C++) για να εκκινήσουν μια νέα παρουσία της εφαρμογής του Office.Ωστόσο, υπάρχουν περιπτώσεις όπου ίσως προτιμάτε να αυτοματοποιήσετε μια εφαρμογή του Office που εκτελείται ήδη: για παράδειγμα, εάν ο χρήστης είχε προηγουμένως ξεκινήσει την εφαρμογή του Office. Εναλλακτικά, εάν εκκινήσατε το εκτελέσιμο αρχείο της εφαρμογής του Office χρησιμοποιώντας κώδικα, ώστε να μπορείτε να καθορίσετε διακόπτες γραμμής εντολών για την εφαρμογή. Για να αυτοματοποιήσετε την εφαρμογή του Office που εκτελείται, πρέπει να χρησιμοποιήσετε το GetObject ή το GetActiveObject.

Βήματα για την αναπαραγωγή της συμπεριφοράς

  1. Ξεκινήστε τη Microsoft Visual Basic και δημιουργήστε ένα νέο τυπικό έργο EXE. Η φόρμα1 δημιουργείται από προεπιλογή.

  2. Προσθήκη στοιχείου ελέγχου CommandButton στο Form1.

  3. Προσθέστε τον παρακάτω κώδικα στη λειτουργική μονάδα κώδικα της φόρμας.

    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. Βεβαιωθείτε ότι η θέση του Excel.exe είναι σωστή στο δείγμα κώδικα.

  5. Κλείστε το Microsoft Excel, εάν εκτελείται ήδη.

  6. Πατήστε το πλήκτρο F5 για να εκτελέσετε το έργο και κάντε κλικ στην επιλογή Command1.

Λύση

Για να επιλύσετε το πρόβλημα, μπορείτε να κάνετε τα εξής:

  • Εστιάστε στην εφαρμογή του Office, αλλάζοντας το δεύτερο όρισμα της συνάρτησης Κελύφους είτε σε vbMinimizedFocus, vbMaximizedFocus ή vbNormalFocus.

  • Δώστε την εστίαση στη φόρμα της Visual Basic.

  • Επιχειρήσετε getObject κατά τη λογιστική διάρκεια φόρτωσης της εφαρμογής του Office.

Ο παρακάτω αναθεωρημένος κώδικας παρουσιάζει αυτή τη λύση.

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

Λύση για το συνδυασμό πλήκτρων C++

Εάν προγραμματίζετε στο κελί C++, το ακόλουθο δείγμα κώδικα παρουσιάζει μια παρόμοια λύση με αυτήν που εμφανίζεται στο παραπάνω δείγμα της Visual Basic. Παρατηρήστε ότι το SetForegroundWindow χρησιμοποιείται για την απομάκρυνση της εστίασης από το Excel, επιτρέποντάς του να καταχωρήσει τα αντικείμενα που εκτελούνται.

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

Αναφορές

Για περισσότερες πληροφορίες, κάντε κλικ στους αριθμούς των ακόλουθων άρθρων για να προβάλετε το άρθρο:

Πώς μπορείτε να βρείτε τη διαδρομή εγκατάστασης μιας εφαρμογής του Office

Χρειάζεστε περισσότερη βοήθεια;

Θέλετε περισσότερες επιλογές;

Εξερευνήστε τα πλεονεκτήματα της συνδρομής, περιηγηθείτε σε εκπαιδευτικά σεμινάρια, μάθετε πώς μπορείτε να προστατεύσετε τη συσκευή σας και πολλά άλλα.

Οι κοινότητες σάς βοηθούν να κάνετε και να απαντάτε σε ερωτήσεις, να δίνετε σχόλια και να ακούτε από ειδικούς με πλούσια γνώση.