Article ID: 193039
Article Last Modified on 3/7/2005
#include "excel8.h"
NOTE: If you are automating Excel 2000, this file will be Excel9.h, and if you are automating Excel 2002, this file will be Excel.h.
C:\Program Files\Microsoft Office\Office\
HRESULT GetDocIDispatch( LPDISPATCH* ppDisp );
void CAutomateLinkView::OnAutomatexl()
{
// Query for the dispatch pointer for the embedded object. In
// this case, this is the Excel worksheet.
LPDISPATCH lpDisp;
HRESULT hr = GetDocIDispatch( &lpDisp );
// If you got an IDispatch, then use it to Automate Excel.
if (SUCCEEDED(hr)){
_Workbook wb;
Worksheets wsSet;
_Worksheet ws;
Range range;
//Set _Workbook wb to use lpDisp, the IDispatch* of the
//embedded workbook
wb.AttachDispatch(lpDisp);
//Then get the first worksheet in the workbook
wsSet = wb.GetWorksheets();
ws = wsSet.GetItem(COleVariant((short)1));
//Get the Range object corresponding to cell A1
range = ws.GetRange(COleVariant("A1"), COleVariant("A1"));
// Fill A1 with the string "Hello, World!"
range.SetValue(COleVariant("Hello, World!"));
//NOTE: If you are automating Excel 2002, the Range.SetValue //method has an additional optional parameter specifying the
//data type. Because the parameter is optional, existing code
//will still work correctly, but new code should use the new
//convention. The call for Excel2002 should look
//like the following:
//range.SetValue( ColeVariant( (long)DISP_E_PARAMNOTFOUND,
// VT_ERROR ),
// COleVariant("Hello, World!"));
}
}
/********************************************************************
* GetDocIDispatch -- This method determines if the document is
* embedded or linked and acquires an IDispatch pointer to the
* embedded document server for use in Automation. The document must
* be activated for this method to succeed.
*
* Parameters: ppDisp -- The address of an LPDISPATCH to be filled
* with the IDispatch pointer of the embedded
* document server.
* Returns: S_OK if successful, otherwise
* an HRESULT reporting the error that occurred.
********************************************************************/
HRESULT CAutomateLinkView::GetDocIDispatch(LPDISPATCH *ppDisp)
{
HRESULT hr = S_OK;
IOleLink* lpLink = NULL;
IMoniker* lpMoniker = NULL;
IRunningObjectTable* lpROT = NULL;
IUnknown* lpUnk = NULL;
// First, try to get an IOleLink interface from the document. If
// successful, this indicates that the document is linked as
// opposed to embedded.
hr = m_pSelection->m_lpObject->QueryInterface(IID_IOleLink,
(void**)&lpLink);
if (SUCCEEDED(hr))
{
// Get the moniker of the source document for this link. You
// need this to find the ActiveX Document Server.
hr = lpLink->GetSourceMoniker( &lpMoniker );
if (SUCCEEDED(hr))
{
// For linked documents, search the Running Object
//Table for the relevant server. Do this through the
//IRunningObjectTable interface, which you can get through
// an API call.
hr = GetRunningObjectTable(0, &lpROT );
if (SUCCEEDED(hr))
{
// Search the Running Object Table for the ActiveX
// Document Server of this document. You'll get back an
// IUnknown pointer to that server.
hr = lpROT->GetObject( lpMoniker, &lpUnk );
if (SUCCEEDED(hr))
{
// Finally, get the IDispatch pointer from the
// IUnknown pointer.
hr = lpUnk->QueryInterface( IID_IDispatch,
(void**)ppDisp );
}
}
}
}
// If that failed, try for a direct IDispatch pointer. This
// indicates that the document is embedded.
else
{
hr = m_pSelection->m_lpObject->QueryInterface( IID_IDispatch,
(void**)ppDisp );
}
// Clean up interface pointers you may have acquired along the
// way.
if (lpLink)
lpLink->Release();
if (lpMoniker)
lpMoniker->Release();
if (lpROT)
lpROT->Release();
if (lpUnk)
lpUnk->Release();
return hr;
}
Keywords: kbhowto kbinterop kbautomation kbcode KB193039