Applies ToOffice Products

Gejala

Ketika Anda mencoba menggunakan GetObject (Microsoft Visual Basic) atau Getactiveobject (Microsoft Visual C++) untuk mengotomatisasi aplikasi Microsoft Office, Anda mendapatkan salah satu pesan kesalahan berikut, meskipun aplikasi Office sedang berjalan:

Pesan galat 1

Kesalahan run-time ' 429 ': komponen ActiveX tidak dapat membuat objek

Pesan galat 2

Kesalahan: 0x800401e3 "operasi tidak tersedia"

Penyebab

Meskipun aplikasi Office berjalan, mungkin tidak terdaftar dalam tabel objek berjalan (BUSUK). Contoh aplikasi Office yang sedang berjalan harus didaftarkan dalam ROT sebelum bisa dilampirkan untuk menggunakan GetObject (Visual Basic) atau Getactiveobject (Visual C++). Saat aplikasi Office dimulai, aplikasi tersebut tidak segera mendaftarkan objek jalannya. Ini mengoptimalkan proses startup aplikasi. Alih-alih mendaftarkan pada startup, aplikasi Office mendaftarkan objek yang berjalan dalam ROT setelah kehilangan fokus. Oleh karena itu, jika Anda mencoba menggunakan GetObject atau Getactiveobject untuk melampirkan ke contoh aplikasi Office yang berjalan sebelum aplikasi telah kehilangan fokus, Anda mungkin menerima salah satu kesalahan di atas.

Pemecahan Masalah

Menggunakan kode, Anda bisa mengubah fokus dari aplikasi Office ke aplikasi Anda sendiri (atau ke beberapa aplikasi lainnya) untuk memungkinkannya mendaftarkan dirinya dalam ROT. Selain itu, jika kode Anda meluncurkan file EXE aplikasi Office, Anda mungkin harus menunggu aplikasi Office selesai dimuat sebelum mencoba melampirkan ke contoh yang sedang berjalan. Sampel kode disediakan sebagai solusi dalam bagian "informasi selengkapnya".

Status

Perilaku ini merupakan bagian dari rancangan program.

Informasi Selengkapnya

Dalam kebanyakan situasi, pengembang yang ingin mengotomatisasi aplikasi Office harus menggunakan CREATEOBJECT (Visual Basic) atau CoCreateInstance (Visual C++) untuk meluncurkan contoh baru dari aplikasi Office. Namun, ada kasus di mana Anda mungkin lebih suka mengotomatisasi aplikasi Office yang sudah berjalan: misalnya, jika pengguna sebelumnya memulai aplikasi Office. Atau, jika Anda meluncurkan aplikasi Office yang dapat dieksekusi menggunakan kode sehingga Anda bisa menentukan Sakelar baris-perintah untuk aplikasi tersebut. Untuk mengotomatisasi aplikasi Office yang berjalan, Anda harus menggunakan GetObject atau Getactiveobject.

Langkah-langkah untuk mereproduksi perilaku

  1. Mulai Microsoft Visual Basic dan buat proyek standar EXE baru. Form1 dibuat secara default.

  2. Menambahkan kontrol CommandButton untuk Form1.

  3. Tambahkan kode berikut ke modul kode formulir.

    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. Pastikan lokasi Excel. exe sudah benar di sampel kode.

  5. Keluar dari Microsoft Excel jika sudah berjalan.

  6. Tekan F5 untuk menjalankan proyek, dan klik command1.

Penyelesaian Masalah

Untuk mengatasi masalah ini, Anda bisa:

  • Berikan fokus ke aplikasi Office dengan mengubah argumen kedua fungsi shell ke Vbminimizedfocus, vbmaximizedfocus, atau vbnormalfocus.

  • Beri bentuk fokus pada Visual Basic.

  • Mencoba GetObject saat akuntansi untuk waktu muat aplikasi Office.

Kode revisi berikut ini mengilustrasikan solusi ini.

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

Penanganan masalah untuk C++

Jika Anda pemrograman dalam C++, sampel kode berikut ini memperlihatkan solusi yang sama seperti yang diperlihatkan dalam contoh Visual Basic di atas. Perhatikan bahwa Setforegroundwindow digunakan untuk memindahkan fokus menjauh dari Excel, yang memungkinkannya untuk mendaftarkan objek yang berjalan.

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

Referensi

Untuk informasi selengkapnya, klik nomor artikel berikut untuk melihat artikel di Pangkalan Pengetahuan Microsoft:

192919 Cara mengotomatisasi database Access aman menggunakan Visual Basic

237338 Pesan kesalahan menggunakan WordMail: "metode ini atau properti tidak tersedia"

240794 Cara menentukan jalur untuk aplikasi Office

Perlu bantuan lainnya?

Ingin opsi lainnya?

Jelajahi manfaat langganan, telusuri kursus pelatihan, pelajari cara mengamankan perangkat Anda, dan banyak lagi.

Komunitas membantu Anda bertanya dan menjawab pertanyaan, memberikan umpan balik, dan mendengar dari para ahli yang memiliki pengetahuan yang luas.