IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> С++ Builder6 & Excel
сообщение
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Здравствуйте!

Подскажите пожалуйста, можно ли содержимое компонента-таблицы StringGrid экспортировать в документ Excel?
Если да, то как это делается?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Можно... В Drkb есть пример на Дельфи: "VCL -> TStringGrid -> Сохранение и загрузка, импорт и экспорт -> Экспорт TStringGrid в Excel", я думаю, что перенести на Builder не составит труда?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 4.10.2009 22:16) *

Можно... В Drkb есть пример на Дельфи: "VCL -> TStringGrid -> Сохранение и загрузка, импорт и экспорт -> Экспорт TStringGrid в Excel", я думаю, что перенести на Builder не составит труда?

Спасибо, справлюсь:)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


 
#include <vcl.h>
#include <math.h>
#pragma hdrstop

#include <utilcls.h>
#include <sysvari.h>
#include <ComObj.hpp>

#include "Unit_Stochastic_variables.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2MS *Form2MS;

.......

AnsiString RefToCell(int ARow, int ACol)
{
return ("A" + ACol - 1) + IntToStr(ARow);
}
//---------------------------------------------------------------------------
bool SaveAsExcelFile(TStringGrid AGrid, AnsiString ASheetName, AnsiString AFileName)
{
int xlWBATWorksheet = -4167;
int Row, Col;
AnsiString GridPrevFile;
OleVariant XLApp, Sheet, Data;
int i, j;
// Prepare Data
Data = VarArrayCreate([1, AGrid.RowCount, 1, AGrid.ColCount], varVariant);
for (i=0;i<=AGrid.ColCount-1;i++)
for (j=0;j<=AGrid.RowCount-1;j++)
Data[j+1][i+1] = AGrid.Cells[i][j];
// Create Excel-OLE Object
Result = false;
XLApp = CreateOleObject("Excel.Application");
try
{
// Hide Excel
XLApp.Visible = false;
// Add new Workbook
XLApp.Workbooks.Add(xlWBatWorkSheet);
Sheet = XLApp.Workbooks[1].WorkSheets[1];
Sheet.Name = ASheetName;
// Fill up the sheet
Sheet.Range[RefToCell(1, 1), RefToCell(AGrid.RowCount,
AGrid.ColCount)].Value = Data;
// Save Excel Worksheet
try
{
XLApp.Workbooks[1].SaveAs(AFileName);
Result = true;
}
catch (...)
{
// Error ?
}
catch (...)
{
// Quit Excel
if (!VarIsEmpty(XLApp))
{
XLApp.DisplayAlerts = false;
XLApp.Quit;
XLAPP = Unassigned;
Sheet = Unassigned;
}
}
}
}




и вооот такой список ошибок..
[C++ Error] Unit_Stochastic_variables.cpp(66): E2188 Expression syntax
[C++ Error] Unit_Stochastic_variables.cpp(69): E2247 '_fastcall Variant::operator [](const int)' is not accessible
[C++ Error] Unit_Stochastic_variables.cpp(71): E2451 Undefined symbol 'Result'
[C++ Error] Unit_Stochastic_variables.cpp(76): E2288 Pointer to structure required on left side of -> or ->*
[C++ Error] Unit_Stochastic_variables.cpp(78): E2316 'Workbooks' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(78): E2451 Undefined symbol 'xlWBatWorkSheet'
[C++ Error] Unit_Stochastic_variables.cpp(79): E2316 'Workbooks' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(80): E2316 'Name' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(82): E2316 'Range' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(87): E2316 'Workbooks' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(93): E2174 The '...' handler must be last
[C++ Error] Unit_Stochastic_variables.cpp(97): E2064 Cannot initialize 'const Variant &' with 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(97): E2342 Type mismatch in parameter 'V' (wanted 'const Variant &', got 'OleVariant')
[C++ Error] Unit_Stochastic_variables.cpp(99): E2316 'DisplayAlerts' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(100): E2316 'Quit' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(101): E2451 Undefined symbol 'XLAPP'
[C++ Error] Unit_Stochastic_variables.cpp(106): E2252 'catch' expected
[C++ Warning] Unit_Stochastic_variables.cpp(106): W8070 Function should return a value
[C++ Warning] Unit_Stochastic_variables.cpp(106): W8004 'xlWBATWorksheet' is assigned a value that is never used

Большое количество ошибок типа "is not member of OleVariant", и поскольку имею дело с Билдером, не знаю как переделать..
Помогите пожалуйста довести до ума начатое!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Гость






Не-не-не... smile.gif Билдер - это тебе не Дельфи, тут вся работа происходит через OlePropertyGet/OlePropertySet/OleFuntion/OleProcedure... Вот так работает экспорт в Excel:
bool SaveAsExcelFile(TStringGrid *AGrid, AnsiString ASheetName, AnsiString AFileName)
{
const int xlWBATWorksheet = -4167;

int bounds[4] = {0, AGrid->RowCount, 0 , AGrid->ColCount };
Variant Array = VarArrayCreate(bounds, 3, varVariant);
for(int i = 0; i < AGrid->RowCount; i++)
{
for(int j = 0; j< AGrid->ColCount; j++)
{
Array.PutElement(AGrid->Cells[j][i], i, j );
}
}

Variant XLApp = CreateOleObject("Excel.Application");
try
{
// Hide Excel
XLApp.OlePropertySet("Visible", false);
// Add new Workbook
XLApp.OlePropertyGet("WorkBooks").OleFunction("Add", xlWBATWorksheet);

Variant Sheet =
XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).
OlePropertyGet("Worksheets").OlePropertyGet("Item", 1);

Sheet.OlePropertySet("Name", ASheetName.c_str());

Variant Cell1 = Sheet.OlePropertyGet("Cells", 1, 1);
Variant Cell2 = Sheet.OlePropertyGet("Cells", AGrid->RowCount + 1, AGrid->ColCount + 1);

Variant fRange = Sheet.OlePropertyGet("Range", Cell1, Cell2);
fRange.OlePropertySet("Value", Array);

XLApp.OlePropertySet("DisplayAlerts",false);
XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).OleProcedure("SaveAs", AFileName.c_str());
XLApp.OleProcedure("Quit");
}
catch(...)
{
//
ShowMessage("Экспорт данных - Ошибка !!!");
}
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
// Вызывать - так:
SaveAsExcelFile(sgTable, "test", "F:\\aga.xls");
}
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 16.10.2009 21:14) *

Не-не-не... smile.gif Билдер - это тебе не Дельфи, тут вся работа происходит через OlePropertyGet/OlePropertySet/OleFuntion/OleProcedure... Вот так работает экспорт в Excel:

Ааа) Буду теперь знать! Спасибо!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Натолкнулась ещё на одну проблему..
У меня в StringGrid во время выполнения программы помещается большое количество строк, и их количество больше, чем может вместить один лист в Excel. Можно как-то вставить ещё один лист в книгу, когда обнаружится недостаток строк для экспорта..? Помогите найти выход, пожалуйста!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Цитата
Можно как-то вставить ещё один лист в книгу, когда обнаружится недостаток строк для экспорта..?
Легко:
bool SaveAsExcelFile(TStringGrid *AGrid, AnsiString ASheetName, AnsiString AFileName)
{
const int xlWBATWorksheet = -4167;
const int maxRowsInXL = 550; // Изменишь на 65535 (XL 2002-2003) или 1048576 (XL 2007)

Variant XLApp = CreateOleObject("Excel.Application");
try
{
// Hide Excel
XLApp.OlePropertySet("Visible", false);
// Add new Workbook
XLApp.OlePropertyGet("WorkBooks").OleFunction("Add", xlWBATWorksheet);

Variant Sheet =
XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).
OlePropertyGet("Worksheets").OlePropertyGet("Item", 1);

int currStart = 0, counter = 1;
// А теперь начинается самое интересное...
while(currStart <= AGrid->RowCount)
{
Sheet.OlePropertySet("Name", (ASheetName + IntToStr(counter++)).c_str());

int bounds[4] = {0, maxRowsInXL, 0 , AGrid->ColCount };
Variant Array = VarArrayCreate(bounds, 3, varVariant);
for(int i = 0; i < min(AGrid->RowCount, maxRowsInXL); i++)
{
for(int j = 0; j< AGrid->ColCount; j++)
{
Array.PutElement(AGrid->Cells[j][currStart + i], i, j );
}
}

Variant Cell1 = Sheet.OlePropertyGet("Cells", 1, 1);
Variant Cell2 = Sheet.OlePropertyGet("Cells", maxRowsInXL + 1, AGrid->ColCount + 1);

Variant fRange = Sheet.OlePropertyGet("Range", Cell1, Cell2);
fRange.OlePropertySet("Value", Array);

currStart += maxRowsInXL;

if(currStart <= AGrid->RowCount) {
int count =
XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).
OlePropertyGet("Worksheets").OlePropertyGet("Count");
Variant AfterSheet =
XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).
OlePropertyGet("Worksheets").OlePropertyGet("Item", count);
Sheet =
XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).
OlePropertyGet("Worksheets").OleFunction("Add", Variant().NoParam(), AfterSheet);
}
}

XLApp.OlePropertySet("DisplayAlerts",false);
XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).OleProcedure("SaveAs", AFileName.c_str());
XLApp.OleProcedure("Quit");
}
catch(...)
{
ShowMessage("Экспорт данных - Ошибка !!!");
}
}
(тестировал на Excel XP + BDS 2009 на СтрингГриде, содержащем 2000 строк. Так вот эти 200 строк были корректно разбиты на 4 листа)
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Здравствуйте!

Теперь мне требуется импортировать данные из Excel в StringGrid.
Пример в DRKB данной операции я нашла, только возникли затруднения с тем, чтобы переделать примерчик на C++ - не знаю, какие методы нужно использовать взамен имеющихся..
Например, вот такое уже не воспринимается компилятором:

...
XLApp.Visible = False;
// Open the Workbook
XLApp.Workbooks.Open(AXLSFile);
...


Объясните пожалуйста, как это всё должно выглядеть?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






Я ж написал выше:
Цитата
вся работа происходит через OlePropertyGet/OlePropertySet/OleFuntion/OleProcedure
Вот и работаем:
...
Variant XLApp = CreateOleObject("Excel.Application");
XLApp.OlePropertySet("Visible", false);
XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Open", AXLSFile.c_str());
...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Попыталась переделать на C++ импорт из Excel
Но для некоторых моментов не знаю, что нужно использовать из методов OlePropertyGet/OlePropertySet/OleFuntion/OleProcedure...


bool Xls_To_StringGrid(TStringGrid AGrid,String AXLSFile)
{
const xlCellTypeLastCell = 0x0000000B;
OleVariant Sheet;
Variant XLApp, RangeMatrix;
int x, y, k, r;

//Result := False;
XLApp = CreateOleObject("Excel.Application");
//try
{
XLApp.OlePropertySet("Visible", false);
XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Open", AXLSFile.c_str());
//Sheet = XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[1];
//Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
x = XLApp.OlePropertyGet("ActiveCell").OlePropertyGet("Row");
y = XLApp.OlePropertyGet("ActiveCell").OlePropertyGet("Column");

AGrid.RowCount = x;
AGrid.ColCount = y;

//RangeMatrix = XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value;
k = 1;
while (k > x)
{
for (r=1;r<=y;r++)
AGrid.Cells[(r - 1)][(k - 1)] = RangeMatrix[k][r];
k++;
}
RangeMatrix = Unassigned;
}
catch(...)
{
ShowMessage("!!!");
}
if (!VarIsEmpty(XLApp)) then
{
XLApp.OlePropertySet("Quit");
XLApp = Unassigned;
Sheet = Unassigned;
return true;
}
else
return false;
}


void __fastcall TFormRegModel::ButClick(TObject *Sender)
{
if (Xls_To_StringGrid(StringGrid1, 'D:\book1.xls'))
ShowMessage('Table has been exported!');
}




Помогите разобраться, пожалуйста
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Гость






Вот основа кода:
bool Xls_To_StringGrid(TStringGrid *AGrid, String AXLSFile)
{
const xlCellTypeLastCell = 0x0000000B;
Variant XLApp = CreateOleObject("Excel.Application");

XLApp.OlePropertyGet("Application").OlePropertyGet("Workbooks").
OleProcedure("Open", AXLSFile.c_str());
XLApp.OlePropertySet("Visible", false);
Variant Sheet = XLApp.OlePropertyGet("ActiveSheet");

XLApp.OlePropertyGet("Cells").
OlePropertyGet("SpecialCells", xlCellTypeLastCell).OleProcedure("Activate");
int x = XLApp.OlePropertyGet("ActiveCell").OlePropertyGet("Row");
int y = XLApp.OlePropertyGet("ActiveCell").OlePropertyGet("Column");
AGrid->RowCount = x;
AGrid->ColCount = y;

for(int rows = 0; rows < x; rows++)
{
for(int cols = 0; cols < y; cols++)
{
AGrid->Cells[AGrid->FixedCols + cols][AGrid->FixedRows + rows] =
Sheet.OlePropertyGet("Cells").
OlePropertyGet("Item", rows + 1 , cols + 1);
}
}

Sheet = Unassigned;
XLApp.OlePropertyGet("Application").OleProcedure("Quit");
XLApp = Unassigned;
return true;
}

void __fastcall TFormRegModel::ButClick(TObject *Sender)
{
if(Xls_To_StringGrid(StringGrid1, "D:\\book1.xls"))
{
ShowMessage("Table has been exported!");
}
}
, всякие обработки исключений повесь сама...
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 23.04.2024 16:44
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name