Could somebody tell me how to open a specific Excel file (full path and file name known) from this e

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
Hello again:
Im new to Visual C++ express edition and Windows operating system, however I have experience in C/C++ languages. Im desperately trying to open an Excel file and read/write their cells. Im using a Windows form as an interface between the user and the Excel file (the user will click a "read" or "write" button on the Windows form, and cell(s) value(s) will be read or written in the Excel file.
So far I have received several suggestions, but unfortunately the code samples sent dont compile (errors appear during compilation).
THE CODE IM INCLUDING BELOW REALLY WORKS! IT COMPILES AND EXECUTES OK! IT CREATES AND INSTANCE OF AN EXCEL FILE NAMED (WORK)BOOK1 AND FILLS IN 15x15 CELLS WITH DATA ON SHEET1...this is very close to what I need.
IS IT POSSIBLE TO -SLIGHTLY- MODIFY THIS CODE IN ORDER TO OPEN A SPECIFIC EXCEL FILE (path and file name already known) INSTEAD OF CREATING A NEW INSTANCE of Excel?Finally, IS IT POSSIBLE TO ACTIVATE A DIFFERENT SHEET (Sheet2, mySheet, whatsoever) ON THAT EXCEL FILE AND WRITE(or Read) DATA TO THAT SPECIFIC SHEET?
I would appreaciate it if you could include the modifications required. Thank you very much in advance! Regards,
Ps. The Message boxes were the only lines that didnt compile, therefore I removed them.
#include
<ole2.h>// OLE2 Definitions
// AutoWrap() - Automation helper function...

HRESULT AutoWrap(
int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) {
// Begin variable-argument list...
va_list marker;
va_start(marker, cArgs);
if(!pDisp) {
// MessageBox(NULL, "NULL IDispatch passed to AutoWrap()", "Error", 0x10010);

_exit(0);
}
// Variables used...
DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
HRESULT hr;
char buf[200];
char szName[200];
// Convert down to ANSI
WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
// Get DISPID for name passed...
hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
if(FAILED(hr)) {
sprintf_s(buf,
"IDispatch::GetIDsOfNames("%s") failed w/err 0x%08lx", szName, hr);
// MessageBox(NULL, buf, "AutoWrap()", 0x10010);

_exit(0);
return hr;
}
// Allocate memory for arguments...
VARIANT *pArgs =
new VARIANT[cArgs+1];
// Extract arguments...
for(int i=0; i<cArgs; i++) {
pArgs = va_arg(marker, VARIANT);
}
// Build DISPPARAMS
dp.cArgs = cArgs;
dp.rgvarg = pArgs;
// Handle special-case for property-puts!
if(autoType & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}
// Make the call!
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);
if(FAILED(hr)) {
sprintf_s(buf,
"IDispatch::Invoke("%s"=%08lx) failed w/err 0x%08lx", szName, dispID, hr);
// MessageBox(NULL, buf, "AutoWrap()", 0x10010);

_exit(0);
return hr;
}
// End variable-argument section...
va_end(marker);
delete [] pArgs;
return hr;
}
 
 

int
_tmain(int argc, _TCHAR* argv[])
{
// Initialize COM for this thread...
CoInitialize(NULL);
// Get CLSID for our server...
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L
"Excel.Application", &clsid);
//HRESULT hr = CLSIDFromProgID(L"C:UsuariosjgarciaamMis documentosMONITOREOS_v24_pruebas", &clsid);
if(FAILED(hr)) {
// ::MessageBox(NULL, "CLSIDFromProgID() failed", "Error", 0x10010);

return -1;
}
// Start server and get IDispatch...
IDispatch *pXlApp;
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (
void **)&pXlApp);
if(FAILED(hr)) {
// ::MessageBox(NULL, "Excel not registered properly", "Error", 0x10010);

return -2;
}
// Make it visible (i.e. app.visible = 1)
{
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlApp, L
"Visible", 1, x);
}
// Get Workbooks collection
IDispatch *pXlBooks;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L
"Workbooks", 0);
pXlBooks = result.pdispVal;
}
// Call Workbooks.Add() to get a new workbook...
IDispatch *pXlBook;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBooks, L
"Add", 0);
pXlBook = result.pdispVal;
}
// Create a 15x15 safearray of variants...
VARIANT arr;
arr.vt = VT_ARRAY | VT_VARIANT;
{
SAFEARRAYBOUND sab[2];
sab[0].lLbound = 1; sab[0].cElements = 15;
sab[1].lLbound = 1; sab[1].cElements = 15;
arr.parray = SafeArrayCreate(VT_VARIANT, 2, sab);
}
// Fill safearray with some values...
for(int i=1; i<=15; i++) {
for(int j=1; j<=15; j++) {
// Create entry value for (i,j)
VARIANT tmp;
tmp.vt = VT_I4;
tmp.lVal = i*j;
// Add to safearray...
long indices[] = {i,j};
SafeArrayPutElement(arr.parray, indices, (
void *)&tmp);
}
}
// Get ActiveSheet object
IDispatch *pXlSheet;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L
"ActiveSheet", 0);
pXlSheet = result.pdispVal;
}
// Get Range object for the Range A1:O15...
IDispatch *pXlRange;
{
VARIANT parm;
parm.vt = VT_BSTR;
parm.bstrVal = ::SysAllocString(L
"A1:O15");
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheet, L
"Range", 1, parm);
VariantClear(&parm);
pXlRange = result.pdispVal;
}
// Set range with our safearray...
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlRange, L
"Value", 1, arr);
// Wait for user...
// ::MessageBox(NULL, "All done.", "Notice", 0x10000);

// Set .Saved property of workbook to TRUE so we arent prompted
// to save when we tell Excel to quit...
{
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlBook, L
"Saved", 1, x);
}
// Tell Excel to quit (i.e. App.Quit)
AutoWrap(DISPATCH_METHOD, NULL, pXlApp, L
"Quit", 0);
// Release references...
pXlRange->Release();
pXlSheet->Release();
pXlBook->Release();
pXlBooks->Release();
pXlApp->Release();
VariantClear(&arr);
// Uninitialize COM for this thread...
CoUninitialize();
return 0;
 
}


View the full article
 
Back
Top