Przejdź do głównej zawartości
Pomoc techniczna
Zaloguj się przy użyciu konta Microsoft
Zaloguj się lub utwórz konto.
Witaj,
Wybierz inne konto.
Masz wiele kont
Wybierz konto, za pomocą którego chcesz się zalogować.

Symptomy

Podczas próby zautomatyzowania aplikacji pakietu Microsoft Office przy użyciu funkcji GetObject (Microsoft Visual Basic) lub GetActiveObject (Microsoft Visual C++) jest wyświetlany jeden z następujących komunikatów o błędach, mimo że aplikacja pakietu Office jest uruchomiona:

Komunikat o błędzie 1

Błąd czasu wykonywania '429':
Składnik ActiveX nie może tworzyć obiektu

Komunikat o błędzie 2

Błąd: 0x800401e3 "Operacja niedostępna"

Przyczyna

Mimo że aplikacja pakietu Office jest uruchomiona, może nie być zarejestrowana w tabeli uruchomionego obiektu (ROT). Uruchomione wystąpienie aplikacji pakietu Office musi zostać zarejestrowane w funkcji ROT, zanim będzie można je dołączyć do korzystania z funkcji GetObject (Visual Basic) lub GetActiveObject (Visual C++).

Po uruchomieniu aplikacji pakietu Office nie rejestruje natychmiast uruchomionych obiektów. Optymalizuje to proces uruchamiania aplikacji. Zamiast rejestrować się przy uruchamianiu, aplikacja pakietu Office rejestruje swoje uruchomione obiekty w rot po utracie koncentracji. Dlatego jeśli spróbujesz użyć getobject lub GetActiveObject do dołączenia do uruchomionego wystąpienia aplikacji pakietu Office, zanim aplikacja utraci fokus, może zostać wyświetlony jeden z powyższych błędów.

Rozwiązanie

Za pomocą kodu możesz zmienić fokus z aplikacji pakietu Office na własną aplikację (lub na inną aplikację), aby umożliwić jej zarejestrowanie się w funkcji ROT. Ponadto, jeśli kod uruchamia plik exe aplikacji pakietu Office, może być konieczne zaczekanie na zakończenie ładowania aplikacji pakietu Office przed podjęciem próby dołączenia do uruchomionego wystąpienia. Przykład kodu jest podany jako obejście w sekcji "Więcej informacji".

Stan

Takie działanie jest celowe.

Więcej informacji

W większości sytuacji deweloperzy, którzy chcą zautomatyzować aplikację pakietu Office, muszą użyć funkcji CreateObject (Visual Basic) lub CoCreateInstance (Visual C++), aby uruchomić nowe wystąpienie aplikacji pakietu Office.

Jednak w niektórych przypadkach warto zautomatyzować uruchomioną już aplikację pakietu Office: na przykład jeśli użytkownik wcześniej uruchomił aplikację pakietu Office. Lub, jeśli uruchomiono aplikację pakietu Office wykonywalną przy użyciu kodu, dzięki czemu można określić przełączniki wiersza polecenia dla aplikacji. Aby zautomatyzować uruchamianie aplikacji pakietu Office, musisz użyć funkcji GetObject lub GetActiveObject.

Procedura odtwarzania zachowania

  1. Uruchom program Microsoft Visual Basic i utwórz nowy projekt Standard EXE. Domyślnie tworzony jest formularz1.

  2. Dodawanie kontrolki CommandButton do formularza Form1.

  3. Dodaj następujący kod do modułu kodu formularza.

    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. Upewnij się, że lokalizacja Excel.exe jest poprawna w przykładzie kodu.

  5. Zamknij program Microsoft Excel, jeśli jest już uruchomiony.

  6. Naciśnij klawisz F5, aby uruchomić projekt, a następnie kliknij polecenie Command1.

Obejście

Aby obejść ten problem, możesz wykonać następujące czynności:

  • Skoncentruj się na aplikacji pakietu Office, zmieniając drugi argument funkcji Powłoka na vbMinimizedFocus, vbMaximizedFocus lub vbNormalFocus.

  • Nadaj fokus formularzowi w języku Visual Basic.

  • Spróbuj pobraćObject podczas uwzględniania czasu ładowania aplikacji pakietu Office.

Ten obejście przedstawiono w poniższym zmienionym kodzie.

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

Obejście problemu dla klawiszy C++

Jeśli programujesz w języku C++, w poniższym przykładzie kodu przedstawiono podobne obejście, jak pokazano w powyższym przykładzie języka Visual Basic. Zwróć uwagę, że funkcja SetForegroundWindow służy do przenoszenia fokusu z dala od programu Excel, co pozwala zarejestrować uruchomione obiekty.

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

Informacje

Aby uzyskać więcej informacji, kliknij następujące numery artykułów, aby wyświetlić ten artykuł:

Jak znaleźć ścieżkę instalacji aplikacji pakietu Office

Potrzebujesz dalszej pomocy?

Chcesz uzyskać więcej opcji?

Poznaj korzyści z subskrypcji, przeglądaj kursy szkoleniowe, dowiedz się, jak zabezpieczyć urządzenie i nie tylko.

Społeczności pomagają zadawać i odpowiadać na pytania, przekazywać opinie i słuchać ekspertów z bogatą wiedzą.

Czy te informacje były pomocne?

Jaka jest jakość języka?
Co wpłynęło na Twoje wrażenia?
Jeśli naciśniesz pozycję „Wyślij”, Twoja opinia zostanie użyta do ulepszania produktów i usług firmy Microsoft. Twój administrator IT będzie mógł gromadzić te dane. Oświadczenie o ochronie prywatności.

Dziękujemy za opinię!

×