GetObject หรือ GetActiveObject ไม่พบแอปพลิเคชัน Office ที่กำลังทำงานอยู่

นำไปใช้กับ: Office Products

อาการ


เมื่อคุณพยายามใช้ GetObject (Microsoft visual Basic) หรือ GetActiveObject (microsoft visual c ++) เพื่อทำให้แอปพลิเคชัน microsoft office เป็นแบบอัตโนมัติคุณจะได้รับข้อความแสดงข้อผิดพลาดอย่างใดอย่างหนึ่งต่อไปนี้แม้ว่าแอปพลิเคชัน Office กำลังทำงานอยู่ให้ทำดังนี้
ข้อความแสดงข้อผิดพลาด 1:
ข้อผิดพลาดขณะเรียกใช้ ' ๔๒๙ ': คอมโพเนนต์ ActiveX ไม่สามารถสร้างวัตถุได้
ข้อความแสดงข้อผิดพลาด 2
ข้อผิดพลาด: 0x800401e3 "การดำเนินการไม่พร้อมใช้งาน"

สาเหตุ


แม้ว่าแอปพลิเคชัน Office กำลังทำงานอยู่อาจไม่มีการลงทะเบียนในตารางวัตถุที่ใช้งานอยู่ (เน่า) อินสแตนซ์ที่กำลังทำงานของแอปพลิเคชัน 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 มาตรฐานใหม่ Form1 จะถูกสร้างขึ้นตามค่าเริ่มต้น
  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 = NothingEnd Sub
  4. ตรวจสอบให้แน่ใจว่าตำแหน่งที่ตั้งของ outlook.exe ถูกต้องในตัวอย่างโค้ด
  5. ออกจาก Microsoft Excel ถ้ามีการใช้งานอยู่แล้ว
  6. กด F5 เพื่อเรียกใช้โครงการแล้วคลิกCommand1

วิธีแก้ไขปัญหาชั่วคราว

เมื่อต้องการแก้ไขปัญหานี้คุณสามารถทำได้ดังนี้
  • ให้โฟกัสไปยังแอปพลิเคชัน Office โดยการเปลี่ยนอาร์กิวเมนต์ที่สองของฟังก์ชัน Shell เป็น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 IfEnd 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();

อ้างอิง


สำหรับข้อมูลเพิ่มเติมให้คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:
๑๙๒๙๑๙ วิธีการทำให้ฐานข้อมูล Access ที่มีความปลอดภัยโดยอัตโนมัติโดยใช้ Visual Basic
๒๓๗๓๓๘ ข้อความแสดงข้อผิดพลาดโดยใช้ WordMail: "วิธีการนี้หรือคุณสมบัตินี้ไม่พร้อมใช้งาน"
๒๔๐๗๙๔ วิธีกำหนดเส้นทางสำหรับแอปพลิเคชัน Office