티스토리 뷰
How to identify multiple instances of excel ( in Excel Automation Visual C++ MFC )
Jake Yoon 2010. 8. 25. 16:15엑셀 자동화를 사용하다보면, GetObject 혹은 GetActiveObject 함수를 이용하여, 현재 실행되고있는 엑셀 인스턴스의 디스패치를 얻어서 사용하게 될 경우가 발생한다.
이론적으로 ROT(Runtime Object Table) 에서 각 개별 인스턴스를 추출할 수 있지만 항상 모니커가 응용프로그램에 종속되므로 다른 인스턴스가 이미 ROT에 등록 되어있으면 Office 응용 프로그램은 인스턴스를 ROT에 등록하지 않는다.( 모니커는 등록되지만 인스턴스는 등록되지 않는다는 뜻 ). 즉, 첫 번째 제외한 모든 인스턴스에 연결할 수 없는 상태가 발생한다. 이를 해결할 수 있는 방법이 존재하는데, Office에서 문서 각각도 ROT에 등록이 된다는 점을 응용하여 해당 인스턴스의 문서를 특별하게 저장해두고 ROT에서 그 문서를 찾아 그 문서를 가지고 있는 인스턴스를 찾는 방법으로 해결할 수 있다.
아래의 내용은, ROT에 인스턴스의 워크북 디스패치를 등록하는 방법이다.
//새로운 엑셀 인스턴스 생성후 워크북까지 만듬, 그리고 Save As로 워크북의 이름을 지정함
TRACE_DEBUG( "[CExFinDlg][Install]2.1" );
if ( !xl.CreateDispatch("Excel.Application") ) {
THROW( CWinException::CreateException( "엑셀을 실행할 수 없습니다." ) );
}
TRACE_DEBUG( "[CExFinDlg][Install][CreateDispatch]2.2" );
books = xl.GetWorkbooks();
book = books.Add( covOptional );
TRACE_DEBUG( "[CExFinDlg][install][GetWorkbook]2.3" );
book.SaveAs(COleVariant(xlsPath), covOptional, covOptional,covOptional,covOptional,
covOptional,0,covOptional,covOptional,covOptional,covOptional);
다음으로, 등록한 워크북의 디스패치를 ROT에서 검색하고, 워크북 디스패치를 통해
어플리케이션의 디스패치를 얻어 리턴하는 함수를 구현한다.
IRunningObjectTable * pRot = NULL;
IEnumMoniker * pEnum = NULL;
IDispatch *pDisp = NULL;
HRESULT hr;
if( SUCCEEDED( GetRunningObjectTable( 0, &pRot )))
{
CString sCurName;
if( SUCCEEDED( pRot->EnumRunning( &pEnum )))
{
IMoniker *pMoniker = NULL;
IMoniker *prevMoniker = NULL;
while( SUCCEEDED( pEnum->Next( 1, &pMoniker, NULL )) && (NULL != pMoniker)
&& (pMoniker != prevMoniker))
{
IBindCtx * pContext = NULL;
if( SUCCEEDED( CreateBindCtx( 0, &pContext )))
{
WCHAR *wCurName = NULL;
hr = pMoniker->GetDisplayName( pContext, NULL, &wCurName );
sCurName = wCurName;
if( (SUCCEEDED( hr )) && (sCurName.Find( xlsPath ) > -1 ))
{
pMoniker->BindToObject( pContext, NULL, IID_IDispatch, (void **)&pDisp);
Workbooks wbs = Workbooks( pDisp );
pDisp = wbs.GetApplication();
break;
}
}
prevMoniker = pMoniker;
}
//pMoniker->Release();
//prevMoniker->Release();
}
}
pRot->Release();
pEnum->Release();
return pDisp;
위 두 가지 과정을 통해 엑셀 자동화기능을 통한 접근에서, 엑셀의 인스턴스를 따로 생성하여 이용할 수 있도록 GetObject 함수를 수정해보았다.
이 기능에서, 워크북 파일을 내부에 생성하게 되므로, 프로그램이 실행되었을 때, 엑셀 워크북이 ROT에 존재하는지 먼저 체크하고 ROT에 존재한다면 AttachDispatch 를 실행. 존재하지 않는다면 워크북 파일이 로컬에 존재하는지 체크하여 삭제 후 다시 새로운 워크북 생성후 저장
등 조금은 더러운 코딩이 되었다 흑흑...
참조 문서
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNo=20&no=608230&ref=608230 (코드)
http://www.trilightzone.org/board/about2285.html (이론적내용)
'Study > Application > Windows' 카테고리의 다른 글
SQLite와 MFC연동을 위한 정보들.. (링크) (0) | 2010.12.01 |
---|---|
MFC 에서 다른 응용프로그램을 실행시켜보자. (0) | 2010.10.05 |
[펌] HINSTANCE VS HWND (0) | 2010.08.23 |
MFC 리스트 컨트롤에 소팅기능 추가하기 (2) | 2010.08.18 |
OLE 작업 (0) | 2010.08.12 |
- Total
- Today
- Yesterday
- 창조경제혁신센터
- GDG SSU
- 리눅스 커널 2.6 구조와 원리
- 리눅스
- WatchFaceHack
- AndroidWear
- 그래비트랙스
- 소설네트워크2
- jaeseokyoon
- Developing on AWS
- yjaeseok
- Linux
- GDG
- 서버개발자
- 리눅스 커널 2.6
- 리눅스2.6
- 숭실대
- gdgssu
- watchface
- Jake Yoon
- gdg watchfacehack
- 안드로이드폰
- 윤재석
- 핸즈온머신러닝
- jakeyoon
- 창의과학교구
- 릴레이대회본선
- 안드로이드
- 하쭈서쭈
- 해커톤
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |