//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <comobj.hpp>
#include <utilcls.h>
#include <oleauto.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
class TAutoLocale {
LCID lcid;
public:
TAutoLocale() {
lcid = ::GetThreadLocale();
::SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL),
SORT_DEFAULT));
}
~TAutoLocale() {
::SetThreadLocale(lcid);
}
};
//---------------------------------------------------------------------------
static String rows(int index) {
return index;
}
//---------------------------------------------------------------------------
static String cols(int index) {
index--;
if (index < 26)
return (char)(index+'A');
else
return (String)(char)((index/26)+'A'-1) + (char)((index%26)+'A');
}
//---------------------------------------------------------------------------
static void ArrayPropertySet(LPDISPATCH dispatch, LPOLESTR name, Variant&
value) {
DISPID dispid;
HRESULT hr = dispatch->GetIDsOfNames(IID_NULL, &name, 1, ::GetThreadLocale(),
&dispid);
if (FAILED(hr))
return;
DISPPARAMS dispparams;
memset(&dispparams, 0, sizeof(dispparams));
DISPID dispidNamed = DISPID_PROPERTYPUT;
dispparams.cNamedArgs = 1;
dispparams.rgdispidNamedArgs = &dispidNamed;
dispparams.cArgs = 1;
dispparams.rgvarg = new VARIANTARG[1];
*dispparams.rgvarg = value;
/*hr = */dispatch->Invoke(dispid, IID_NULL, ::GetThreadLocale(),
DISPATCH_PROPERTYPUT, &dispparams, 0, 0, 0);
delete[] dispparams.rgvarg;
}
//---------------------------------------------------------------------------
static void ArrayPropertyGet(LPDISPATCH dispatch, LPOLESTR name, Variant&
value) {
DISPID dispid;
HRESULT hr = dispatch->GetIDsOfNames(IID_NULL, &name, 1, ::GetThreadLocale(),
&dispid);
if (FAILED(hr))
return;
DISPPARAMS dispparams;
memset(&dispparams, 0, sizeof(dispparams));
/*hr = */dispatch->Invoke(dispid, IID_NULL, ::GetThreadLocale(),
DISPATCH_METHOD | DISPATCH_PROPERTYGET, &dispparams, (VARIANT*)&value, 0, 0);
}
//---------------------------------------------------------------------------
class TExcel {
private:
Variant Range;
...
protected:
Variant getRows(int row);
Variant getRows(int firstrow, int lastrow);
Variant getCols(int col);
Variant getCols(int firstcol, int lastcol);
Variant getCells(int row, int col);
Variant getRange(int row, int col);
Variant getRange(int firstrow, int firstcol, int lastrow, int lastcol);
...
public:
...
};
//---------------------------------------------------------------------------
#pragma warn -lvc
Variant TExcel::getRows(int row) {
Range = Sheet.OlePropertyGet("Rows", rows(row));
return Range;
}
//---------------------------------------------------------------------------
#pragma warn -lvc
Variant TExcel::getRows(int firstrow, int lastrow) {
Range = Sheet.OlePropertyGet("Rows", rows(firstrow) + ":" + rows(lastrow));
return Range;
}
//---------------------------------------------------------------------------
#pragma warn -lvc
Variant TExcel::getCols(int col) {
Range = Sheet.OlePropertyGet("Columns", cols(col));
return Range;
}
//---------------------------------------------------------------------------
#pragma warn -lvc
Variant TExcel::getCols(int firstcol, int lastcol) {
Range = Sheet.OlePropertyGet("Columns", cols(firstcol) + ":" +
cols(lastcol));
return Range;
}
//---------------------------------------------------------------------------
#pragma warn -lvc
Variant TExcel::getCells(int row, int col) {
Range = Sheet.OlePropertyGet("Cells", row, col);
return Range;
}
//---------------------------------------------------------------------------
#pragma warn -lvc
Variant TExcel::getRange(int row, int col) {
String name = cols(col) + rows(row);
Range = Sheet.OlePropertyGet("Range", name);
return Range;
}
//---------------------------------------------------------------------------
#pragma warn -lvc
Variant TExcel::getRange(int firstrow, int firstcol, int lastrow, int lastcol)
{
String name = cols(firstcol) + rows(firstrow) + ":" + cols(lastcol) +
rows(lastrow);
Range = Sheet.OlePropertyGet("Range", name);
return Range;
}
//---------------------------------------------------------------------------
#pragma warn -lvc
void TExcel::getCells(int firstrow, int firstcol) {
TAutoLocale al;
int bounds[] = { 0, RowCount, 0, ColCount };
Variant values(bounds, 3, varOleStr);
Variant models(bounds, 3, varOleStr);
getRange(firstrow, firstcol, firstrow + RowCount - 1, firstcol + ColCount -
1);
ArrayPropertyGet(Range, L"Value", values);
ArrayPropertyGet(Range, L"Formula", models);
for (int i = 0; i < RowCount; i++) {
for (int j = 0; j < ColCount; j++) {
String value = values.GetElement(i+1, j+1);
String model = models.GetElement(i+1, j+1);
// do something with it
}
}
values.Clear();
models.Clear();
}
//---------------------------------------------------------------------------
/*
TAutoLocale - вспомогательный класс для временной установки и
восстановления нейтральной локали, нужно создавать в каждой
внешней функции, которая работает с экселем.
TExcel - вспомогательный класс работы с экселем.
"Правильные" функции - ArrayPropertyGet/Set.
Пример использования функций ArrayPropertyGet в getCells.
*/