증상

Microsoft Office 응용 프로그램을 자동화 하기 위해 GetObject (Microsoft visual Basic) 또는 getactiveobject (Microsoft visual c + +)를 사용 하려고 하면 Office 응용 프로그램이 실행 되 고 있는 경우에도 다음 오류 메시지 중 하나가 나타납니다.

오류 메시지 1

런타임 오류 ' 429 ': ActiveX 구성 요소에서 개체를 만들 수 없음

오류 메시지 2

오류: 0x800401e3 "작업을 사용할 수 없음"

원인

Office 응용 프로그램이 실행 되 고 있는 경우에도 ROT (실행 개체 테이블)에 등록 되지 않았을 수 있습니다. Office 응용 프로그램의 실행 인스턴스는 GetObject (visual Basic) 또는 getactiveobject (visual c + +)를 사용 하 여 연결할 수 있으려면 ROT에 등록 되어 있어야 합니다. Office 응용 프로그램이 시작 되 면 실행 중인 개체를 즉시 등록 하지 않습니다. 이렇게 하면 응용 프로그램의 시작 프로세스가 최적화 됩니다. Office 응용 프로그램은 시작 시에 등록 하는 대신 포커스를 잃었을 때 ROT에 실행 중인 개체를 등록 합니다. 따라서 응용 프로그램이 포커스를 손실 하기 전에 GetObject 또는 getactiveobject 를 사용 하 여 Office 응용 프로그램의 실행 중인 인스턴스에 연결 하려고 하면 위의 오류 중 하나가 나타날 수 있습니다.

해결 방법

코드를 사용 하 여 Office 응용 프로그램에서 사용자의 응용 프로그램 (또는 일부 다른 응용 프로그램)으로 포커스를 변경 하 여 ROT에 자신을 등록할 수 있습니다. 또한 코드에서 Office 응용 프로그램의 exe 파일을 실행 하는 경우, 실행 중인 인스턴스에 연결을 시도 하기 전에 Office 응용 프로그램이 로드를 마치기를 기다려야 할 수 있습니다. 코드 샘플은 "추가 정보" 섹션에서 해결 방법으로 제공 됩니다.

상태

이것은 의도적으로 설계된 동작입니다.

추가 정보

대부분의 경우 Office 응용 프로그램을 자동화 하려는 개발자는 CreateObject (visual Basic) 또는 CoCreateInstance (visual c + +)를 사용 하 여 office 응용 프로그램의 새 인스턴스를 시작 해야 합니다. 그러나 사용자가 이전에 Office 응용 프로그램을 시작한 경우와 같이 이미 실행 중인 Office 응용 프로그램을 자동화 하는 경우가 있습니다. 또는 코드를 사용 하 여 Office 응용 프로그램의 실행 파일을 시작한 경우에는 응용 프로그램의 명령줄 스위치를 지정할 수 있습니다. 실행 중인 Office 응용 프로그램을 자동화 하기 위해서는 GetObject 또는 getactiveobject를 사용 해야 합니다.

동작을 재현 하는 단계

  1. Microsoft Visual Basic을 시작 하 고 새 표준 EXE 프로젝트를 만듭니다. Form1이 기본적으로 만들어집니다.

  2. Form1에 CommandButton 컨트롤을 추가 합니다.

  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. 코드 샘플에서 excel.exe의 위치가 올바른지 확인 하세요.

  5. Microsoft Excel이 이미 실행 중인 경우 종료 합니다.

  6. F5 키를 눌러 프로젝트를 실행 하 고 Command1를 클릭 합니다.

해결 방법

이 문제를 해결 하려면 다음을 수행할 수 있습니다.

  • Shell 함수의 두 번째 인수를 vbMinimizedFocus, VbMaximizedFocus또는 vbnormalfocus중 하나로 변경 하 여 Office 응용 프로그램에 포커스를 부여 합니다.

  • 시각적 기본 폼에 포커스를 제공 합니다.

  • Office 응용 프로그램의 로드 시간을 계정으로 하는 동안 GetObject 를 시도 합니다.

다음 수정 코드는이 해결 방법을 보여 줍니다.

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 기술 자료 문서를 참조하세요.

192919 Visual Basic을 사용 하 여 보안 된 Access 데이터베이스를 자동화 하는 방법

237338 WordMail을 사용 하는 오류 메시지: "이 메서드 또는 속성을 사용할 수 없습니다."

240794 Office 응용 프로그램의 경로를 확인 하는 방법

추가 도움이 필요하신가요?

기술 향상
교육 살펴보기
새로운 기능 우선 가져오기
Microsoft Insider 참가

이 정보가 유용한가요?

번역 품질에 얼마나 만족하시나요?
사용 경험에 어떠한 영향을 주었나요?

소중한 의견에 감사드립니다.

×