요약

이 문서에서는 Visual C++에서 Microsoft Office로 자동화와 관련된 일반적인 질문에 답변합니다.

추가 정보

목차

  1. Automation이란?

  2. Automation을 접하는 경우 자세히 알아볼 수 있는 좋은 리소스는 어디에서 찾을 수 있나요?

  3. Automation을 사용할 수 있는 여러 가지 방법이 있나요?

  4. COM이란?  

  5. Office 애플리케이션의 실행 중인 인스턴스에 연결할 어떻게 할까요? 있나요?

  6. 선택적 매개 변수를 전달할 어떻게 할까요? 있나요?

  7. Office 응용 프로그램에서 노출되는 이벤트를 catch할 어떻게 할까요? 있나요?  

  8. 자동화 코드가 너무 느립니다. 속도를 어떻게 높일 수 있나요?

  9. -2147352573 또는 0x80030002 같은 이러한 거대한 오류 값은 무엇을 의미합니까?

  10. 형식 라이브러리란?

  11. 자동화 코드는 Microsoft Excel 95에서 작동했지만 Microsoft Excel 97에서는 실패했습니다. 그 이유는 무엇입니까?

  12. 프로그램을 완료한 후 자동화하는 애플리케이션이 메모리에 유지되는 이유는 무엇인가요?

  13. Microsoft Office 애플리케이션 사용자로서 무엇을 하고 싶은지 알고 있지만 Automation을 사용하여 프로그래밍 방식으로 이 작업을 수행하려면 어떻게 해야 하나요?

  14. 포함된 Microsoft Office 애플리케이션을 자동화할 수 있나요?

  15. Microsoft Office 문서에서 내 문서 속성에 액세스할 어떻게 할까요? 있나요?

질문 및 답변

  1. Automation이란? Automation(이전의 OLE Automation)은 기존 프로그램의 기능을 활용하여 사용자 고유의 애플리케이션에 통합할 수 있는 기술입니다. 예를 들어 사용자에게 Microsoft Word를 표시하지 않고도 Microsoft Word 맞춤법 및 문법 검사 기능을 애플리케이션에 활용할 수 있습니다. 모든 Microsoft Excel 차트, 인쇄 및 데이터 분석 도구를 사용할 수도 있습니다. 이 기술은 개발 속도를 크게 단순화하고 가속화할 수 있습니다.  

  2. Automation을 접하는 경우 자세히 알아볼 수 있는 좋은 리소스는 어디에서 찾을 수 있나요? David Kruglinski의 "Inside Visual C++"(ISBN:1-57231-565-2)의 24장은 일반적인 개요와 몇 가지 좋은 예를 제공합니다. 또한 Microsoft 기술 자료는 좋은 정보 원본입니다.예를 들어 학습을 선호하는 경우 Microsoft 기술 자료에서 다음 문서를 참조하세요.  

    179706 HOWTO MFC를 사용하여 Excel 자동화 & 새 통합 문서 만들기/서식 지정

  3. Automation을 사용할 수 있는 여러 가지 방법이 있나요? Automation을 사용할 수 있는 세 가지 기본 방법은 MFC, #import 및 C/C++입니다.  

    • MFC를 사용하면 Visual C++ ClassWizard를 사용하여 Microsoft Office 형식 라이브러리에서 "래퍼 클래스"를 생성합니다. 이러한 클래스뿐만 아니라 COleVariant, COleSafeArray, COleException과 같은 다른 MFC 클래스는 자동화 작업을 간소화합니다. 이 메서드는 일반적으로 다른 방법보다 권장되며 대부분의 Microsoft 기술 자료 예제에서는 MFC를 사용합니다.

    • Visual C++ 5.0에서 사용할 수 있게 된 새 지시문인 #import 지정된 형식 라이브러리에서 VC++ "스마트 포인터"를 만듭니다. 매우 강력하지만 일반적으로 Microsoft Office 애플리케이션과 함께 사용할 때 발생하는 참조 계산 문제로 인해 권장되지 않는 경우가 많습니다.

    • C/C++ 자동화는 훨씬 더 어렵지만 MFC의 오버헤드 또는 #import 문제를 방지하기 위해 필요할 수 있습니다. 기본적으로 CoCreateInstance()와 같은 API 및 IDispatch 및 IUnknown과 같은 COM 인터페이스로 작업합니다.

    COM은 C++ 클래스를 중심으로 설계되었기 때문에 일반 C와 비교했을 때 C++의 자동화 간에 약간의 차이가 있다는 점에 유의해야 합니다.  

  4. COM이란? 자동화는 COM(구성 요소 개체 모델)을 기반으로 합니다. COM은 인터페이스를 기반으로 하는 표준 소프트웨어 아키텍처이며 코드를 자체 포함 개체로 구분하도록 설계되었습니다. OOP(개체 지향 프로그래밍) 패러다임의 확장이라고 생각하지만 별도의 애플리케이션에 적용할 수 있습니다. 각 개체는 인터페이스 집합을 노출하며 초기화, 알림 및 데이터 전송과 같은 개체에 대한 모든 통신은 이러한 인터페이스를 통해 발생합니다.COM은 운영 체제와 함께 설치된 DLL(동적 연결 라이브러리)에서 제공하는 서비스 집합이기도 합니다. Automation은 이러한 서비스를 많이 사용합니다. 한 가지 예는 클라이언트 애플리케이션의 호출을 서버 애플리케이션 인터페이스의 멤버 함수에 패키지하고 인수를 사용하여 서버 애플리케이션에 전달하는 "마샬링" 서비스입니다. 서버의 인터페이스가 클라이언트의 메모리 공간에 노출되는 것처럼 보입니다. 클라이언트가 자체 프로세스 공간에서 실행되는 .exe 그렇지 않습니다. 또한 마샬링에서는 서버의 메서드에서 반환 값을 프로세스 경계를 넘어 클라이언트 호출의 손에 안전하게 가져옵니다. 다양한 COM 라이브러리에서 제공하는 Automation에 필수적인 다른 많은 서비스가 있습니다. 이러한 정보에 대한 정보 출처에는 Kraig Brockschmidt의 "Inside Ole - Second Edition", ISBN 1-55615-843-2, 데일 로저슨의 "Inside COM" - ISBN 1-57231-349-8 및 "Automation 프로그래머의 참조", ISBN 1-57231-584-9가 포함됩니다.

  5. Office 애플리케이션의 실행 중인 인스턴스에 연결할 어떻게 할까요? 있나요? GetActiveObject() API를 사용합니다. Automation 서버는 RegisterActiveObject() API를 통해 ROT(실행 중인 개체 테이블)에 등록합니다. Automation 클라이언트는 다음과 같은 코드를 사용하여 실행 중인 인스턴스에서 가져올 수 있습니다.  

          // Translate server ProgID into a CLSID. ClsidFromProgID
          // gets this information from the registry.
          CLSID clsid;
          CLSIDFromProgID(L"Excel.Application", &clsid);  
    
          // Get an interface to the running instance, if any..
          IUnknown *pUnk;
          HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
    
          ASSERT(!FAILED(hr));
    
          // Get IDispatch interface for Automation...
          IDispatch *pDisp;
          hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pDisp);
          ASSERT(!FAILED(hr));
    
          // Release the no-longer-needed IUnknown...
          pUnk->Release();
    
    

    참고: 연결하려는 Office 응용 프로그램을 실행하는 여러 인스턴스가 있는 경우 GetActiveObject() API를 사용하여 시작된 첫 번째 인스턴스에만 연결할 수 있습니다.이론적으로는 각 개별 인스턴스에 대해 ROT를 반복할 수 있지만 모니커 자체가 항상 동일하기 때문에 다른 인스턴스가 이미 ROT에 있는 경우 Office 앱은 자체적으로 등록되지 않습니다(어쨌든 구분할 수 없음). 즉, 첫 번째 인스턴스를 제외하고 인스턴스에 연결할 수 없습니다. 그러나 Office 앱이 해당 문서를 ROT에 등록하기 때문에 ROT를 반복하여 특정 문서를 찾고 첨부한 다음 Application 개체를 가져오면 다른 인스턴스에 성공적으로 첨부할 수 있습니다.단일 인스턴스 애플리케이션이므로 PowerPoint에 대해 이 작업을 수행할 필요가 없습니다. 하나의 인스턴스만 실행할 수 있습니다.

  6. 선택적 매개 변수를 전달할 어떻게 할까요? 있나요? 일부 메서드에는 "선택적" 매개 변수가 있습니다. Visual Basic에서는 메서드를 호출할 때 자연스럽게 생략할 수 있습니다. 그러나 Visual C++를 사용하여 호출할 때 .vt 필드가 VT_ERROR .scode 필드가 DISP_E_PARAMNOTFOUND 특수 VARIANT를 전달해야 합니다. 말하자면:  

          // VARIANT used in place of optional-parameters.
          VARIANT varOpt;
          varOpt.vt = VT_ERROR;
          varOpt.scode = DISP_E_PARAMNOTFOUND;
    

    이것이 바로 Visual Basic이 백그라운드에서 수행하는 작업입니다.

  7. Office 응용 프로그램에서 노출되는 이벤트를 catch할 어떻게 할까요? 있나요? 기본적으로 catch하려는 이벤트 인터페이스("싱크")를 구현하고 애플리케이션("원본")과의 자문 연결을 설정합니다.일반적으로 권고 연결을 설정하려면 서버의 IConnectionPointContainer를 가져와서 이벤트 인터페이스의 IID를 사용하여 FindConnectionPoint()를 호출합니다. 이렇게 하면 IConnectionPoint 인터페이스가 제공되고 남은 것은 이벤트 인터페이스의 인스턴스를 사용하여 Advise()를 호출하는 것입니다. 그러면 서버는 이러한 이벤트가 발생할 때 이 인터페이스를 통해 다시 호출합니다.

  8. 자동화 코드가 너무 느립니다. 속도를 어떻게 높일 수 있나요? 자동화의 속도 문제의 일반적인 원인은 반복적인 데이터 읽기 및 쓰기입니다. 이는 Excel Automation 클라이언트에 일반적입니다. 그러나 대부분의 사람들은 이 데이터를 SAFEARRAY를 사용하여 한 번에 기록하거나 읽을 수 있다는 것을 인식하지 못합니다. 자세한 내용 및 정보 제공 예제는 다음 Microsoft 기술 자료 문서를 참조하세요.

    179706 HOWTO: MFC를 사용하여 Excel 자동화 및 새 통합 문서 만들기/서식 지정 또한 클립보드를 사용하면 성능이 향상될 수 있다는 점을 지적하는 것이 중요합니다. 예를 들어 데이터를 클립보드에 복사한 다음 자동화를 사용하여 서버에 붙여넣도록 지시할 수 있습니다. 또는 그 반대의 경우도 마찬가지입니다. 서버에 클립보드로 복사하도록 지시하고 애플리케이션에 붙여넣습니다.

  9. -2147352573 또는 0x80030002 같은 이러한 거대한 오류 값은 무엇을 의미합니까? 이러한 값을 HRESULT라고 하며 winerror.h에 정의됩니다. 첫 번째 비트가 오류 결과인지 여부를 나타내기 때문에 숫자가 너무 큽니다. Visual C++와 함께 제공되는 ErrLook.Exe 유틸리티를 사용하여 이러한 숫자를 의미 있는 설명으로 변환할 수 있습니다.프로그래밍 방식으로 오류에 대한 설명을 가져오려면 FormatMessage() API를 사용할 수 있습니다.

    참고: Visual C++ 6.0을 사용하고 디버그 조사식 창에 이 값이 포함된 변수가 있는 경우 ", hr"(따옴표 없이)을 추가하여 Visual C++가 번역되도록 합니다.

  10. 형식 라이브러리란? 형식 라이브러리는 C/C++ 헤더 파일과 비슷합니다. 여기에는 서버가 게시하는 인터페이스, 메서드 및 속성이 포함됩니다. Visual C++와 함께 제공되는 OLE/COM 개체 뷰어(Oleview.exe)를 사용하여 형식 라이브러리를 볼 수 있습니다. 다음은 Microsoft Office 95, 97 및 2000의 형식 라이브러리 파일 이름 목록입니다. Office 애플리케이션 | 형식 라이브러리 ------------------------+---------------- Word 95 및 이전 | wb70en32.tlb Excel 95 및 이전 | xl5en32.olb Powerpoint 95 및 이전 | Powerpoint.tlb Access 95 및 이전 | msaccess.tlb 바인더 95 | binder.tlb Schedule+ | sp7en32.olb 프로젝트 | pj4en32.olb 팀 관리자 | mstmgr1.olb Word 97 | msword8.olb Excel 97 | excel8.olb Powerpoint 97 | msppt8.olb Access 97 | msacc8.olb 바인더 97 | msbdr8.olb 그래프 97 | graph8.olb Outlook 97 | msoutl8.olb Outlook 98 | msoutl85.olb Word 2000 | msword9.olb Excel 2000 | excel9.olb Powerpoint 2000 | msppt9.olb Access 2000 | msacc9.olb Outlook 2000 | msoutl9.olb Word 2002 | msword.olb Excel 2002 | excel.exe Powerpoint 2002 | msppt.olb Access 2002 | msacc.olb Outlook 2002 | msoutl.olb  

  1. 내 자동화 코드는 Excel 95에서 작동했지만 Excel 97에서는 실패했습니다. 무슨 일이죠? Excel의 개체 모델은 버전 95에서 97로 크게 변경되었습니다. Excel 95는 IDispatch의 단일 구현에서 모든 메서드와 속성을 구현했습니다. 즉, 개체 Y에서 개체 X에 대한 메서드를 호출할 수 있는 경우가 많습니다. 이는 좋은 디자인이 아니므로 Office 97에서는 각 개체에 별도의 Idispatch 구현이 있습니다. 즉, 개체 X의 메서드 또는 속성을 별도의 개체 Y에서 요청하면 "멤버를 찾을 수 없습니다."라는 오류 0x80020003 2147352573. 이 오류를 방지하려면 호출하는 기본 IDispatch 인터페이스가 의미상 올바른 인터페이스인지 확인해야 합니다.  

  2. 자동화하는 애플리케이션은 프로그램이 완료된 후 메모리에 유지됩니다. 무슨 일이죠? 가장 가능성이 높은 이유는 획득된 인터페이스를 해제하는 것을 잊어버렸기 때문이며 추적해야 하기 때문입니다. 다음은 몇 가지 일반적인 제안 사항과 검색할 사항입니다.  

    • #import 사용하는 경우 연결된 참조 계산 버그 중 하나가 실행될 가능성이 큽니다. 종종 버그를 해결할 수 있지만 일반적으로 다른 Automation 메서드 중 하나를 사용하는 것이 좋습니다. 형식 라이브러리와 사용은 매우 복잡하기 때문에 #import Office 응용 프로그램에서는 잘 작동하지 않습니다. 또한 이러한 참조 계산 문제는 #import 사용할 때 많은 인터페이스 수준 COM 호출이 백그라운드에 있기 때문에 추적하기 어렵습니다.

    • IDispatch * (LPDISPATCH)를 반환하는 Open 또는 New와 같은 메서드를 호출하고 반환 값을 무시하는지 확인합니다. 이 경우 반환된 인터페이스를 포기하고 더 이상 필요하지 않은 경우 코드를 해제하도록 코드를 변경해야 합니다.

    • 문제가 사라질 때까지 코드 섹션을 점진적으로 주석 처리한 다음 신중하게 다시 추가하여 문제가 시작되는 위치를 추적합니다.

    • 사용자가 애플리케이션을 "터치"한 경우 일부 애플리케이션은 계속 실행됩니다. 자동화하는 동안 이 문제가 발생하면 나중에 애플리케이션이 계속 실행될 수 있습니다. Office 애플리케이션에는 이 동작을 변경하기 위해 읽고 쓸 수 있는 Application 개체에 "UserControl" 속성이 있습니다.

    • 또한 일부 애플리케이션은 충분한 사용자 인터페이스 "작업"이 발생한 경우 계속 실행되도록 결정합니다. 애플리케이션을 종료하려는 경우 Application 개체에서 Quit() 메서드를 호출합니다. 종료가 호출될 때 참조 수에 관계없이 Word가 종료됩니다. 이는 예상된 COM 동작이 아닙니다. 그러나 Excel은 제대로 자신을 숨기지만 모든 미해결 인터페이스가 릴리스될 때까지 계속 실행됩니다. 일반적으로 모든 미해결 참조를 해제하고 애플리케이션을 종료하려는 경우에만 Quit()을 호출해야 합니다.

  3. Office 애플리케이션 사용자로서 무엇을 하고 싶은지 알고 있지만 Automation을 통해 프로그래밍 방식으로 이 작업을 수행하려면 어떻게 해야 하나요? 관심 있는 것은 사용해야 하는 개체, 메서드 및 속성입니다. 사용자로 수행하려는 작업을 기반으로 Word, Excel 및 Powerpoint의 개체 모델을 탐색하는 가장 좋은 방법은 매크로 레코더를 사용하는 것입니다. 도구 메뉴에서 매크로\'새 매크로 기록'을 선택하고 관심 있는 작업을 실행한 다음 매크로\'기록 중지'를 선택합니다. 녹화가 완료되면 도구 메뉴에서 매크로\매크로를 선택하고, 기록한 매크로를 선택한 다음, 편집을 클릭합니다. 이렇게 하면 기록된 작업을 수행하는 생성된 VBA 코드로 연결됩니다. 기록된 매크로는 대부분의 경우 최상의 코드는 아니지만 빠른 예제에서는 매우 잘 작동합니다.

  4. 포함된 Office 애플리케이션을 자동화할 수 있나요? 절대적 으로. 트릭은 IDispatch 포인터를 가져오는 것입니다: Visual C++ Technical Note 39(TN039)에 제공됩니다.  

  5. Office 문서에서 내 문서 속성에 액세스할 어떻게 할까요? 있나요? 문서 속성은 Automation을 통해 또는 IPropertyStorage를 통해 직접 액세스할 수 있습니다.  

도움이 더 필요하세요?

더 많은 옵션을 원하세요?

구독 혜택을 살펴보고, 교육 과정을 찾아보고, 디바이스를 보호하는 방법 등을 알아봅니다.

커뮤니티를 통해 질문하고 답변하고, 피드백을 제공하고, 풍부한 지식을 갖춘 전문가의 의견을 들을 수 있습니다.