Smart |
Отправлено: 28.05.2006, 16:32 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 35
|
Здравствуйте, господа!
Потратил пару часов на поиск в инете примера такого экспорта, но увы...
Есть ADOQuery, через DataSource в DBGrid получаю ответ от сервера — таблицу данных.
Вопрос в том, как теперь эту таблицу (все ячейки) переслать в Excel?
Если можно, рабочий пример. |
|
AVC |
Отправлено: 29.05.2006, 10:08 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
Потратил пару часов на поиск в инете примера такого экспорта, но увы...
|
Простите, плохо искали. Ответы и готовые решения есть прямо тут. В уроках или в поиске.
Например
Отчет на C++Builder в Excel, Передача данных из DBGrid в Excel
Что быстрее XML, dBase, Excel? (последние посты) |
|
Smart |
Отправлено: 29.05.2006, 20:35 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 35
|
AVC, спасибо большое!
Искал и вправду долго и безуспешно.
Возможная причина неудачных поисков — искал "экспорт", "DBGrid" и "Excel".
Про "передачу данных" не спрашивал... |
|
olegenty |
Отправлено: 31.05.2006, 09:28 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
экспорт DBGrid в Excel не возможен по определению, DBGrid не содержит данные, а только отображает их. исключение из правил — DBGridEh, имеющий метод экспорта в Excel самого себя с учётом цвета и пр. в соответствии с GetCellParams
|
|
Smart |
Отправлено: 01.06.2006, 21:19 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 35
|
К сожалению сцылка, приведенная AVC, практически ничего не прояснила по причине невнятности подобных конструкций:
CODE |
CExcelExp::Export(ex, "C1", fdsSignsSIGN->AsString);
CExcelExp::Export(ex, "C2", fdsSignsNAME->AsString);
CExcelExp::Export(ex, "C3", fdsSignsPRINT_SIGN->AsInteger);
CExcelExp::Export(ex, "C4", fdsSignsDESCRIPTION->AsString);
|
Вроде разобрался, помогли исходники на Паскале, других не нашел
Сейчас запощу, мож кому пригодится. |
|
Smart |
Отправлено: 01.06.2006, 21:28 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 35
|
Итак, _реально_ работающий экспорт из DBGrid.
Вот тока не надо про то, что "экспорт DBGrid в Excel невозможен по определению" — все уши прожужжали в форумах вместо конкретных примеров доступа к ячейкам данных. :~E
CODE |
Variant XLSAPP;
//===============================================
int f4_ExcelInit(AnsiString File){//Подключение к Excel
try{//Если Excel запущен — подключиться к нему
XLSAPP=Variant::GetActiveObject("Excel.Application");}
catch (...){//Если Excel не запущен — запустить его
try{XLSAPP=Variant::CreateObject("Excel.Application");}
catch (...){
Application->MessageBox("Невозможно открыть Microsoft Excel."
"Возможно, Excel не установлен на компьютере.","Ошибка",MB_OK+MB_ICONERROR);}
}
try{
if(File!=""){
XLSAPP.OlePropertyGet("WorkBooks").OleProcedure("Open",File.c_str());}//Открыть документ
else XLSAPP.OlePropertyGet("WorkBooks").OleProcedure("add");//Создать новый документ
}
catch (...){
Application->MessageBox("Ошибка открытия файла Microsoft Excel.",
"Ошибка",MB_OK+MB_ICONERROR);return -1;}
return 1;
}
//===============================================
int f4_ExcelVisible(bool i){//Показать/скрыть Excel
if(!XLSAPP.IsEmpty())XLSAPP.OlePropertySet("Visible",i);
return 1;
}
//===============================================
int f4_ExcelSend(int Sheet, int Stolb, int Stroka, AnsiString Str, bool asText=false){//>>>
Variant ExcelSheet,Cur;//Запись данных в Excel (Лист, столбец, строка, "данные",как_текст?)
AnsiString ErrStr;
if(Str=="")return 1;//Не писать "пустоту"
ErrStr="Ошибка при записи: лист "+IntToStr(Sheet)+", столбец "+IntToStr(Stolb)+", строка "+IntToStr(Stroka);
try{ExcelSheet=XLSAPP.OlePropertyGet("WorkSheets",Sheet);}
catch (...){Application->MessageBox(ErrStr.c_str(),
"Ошибочный номер листа Microsoft Excel",MB_OK+MB_ICONERROR); return -1;}
try{Cur=ExcelSheet.OlePropertyGet("Cells",Stroka,Stolb);
if(asText)Cur.OlePropertySet("NumberFormat","@");//Форматировать ячейку как текст
Cur.OlePropertySet("Value",Str.c_str());}
catch (...){Application->MessageBox(ErrStr.c_str(),
"Ошибка Microsoft Excel",MB_OK+MB_ICONERROR); return -1;}
return 1;
}
//===============================================
int f4_SaveToExcel(){//Экспорт всех ячеек в Excel
TBookmark bm;
int result,col, row;
Screen->Cursor=crHourGlass;
Application->ProcessMessages();
result=f4_ExcelInit("");//Инициализация Excel
if(result==-1){Screen->Cursor=crDefault;return -1;}
Form1->DBGrid1->DataSource->DataSet->DisableControls();
bm=Form1->DBGrid1->DataSource->DataSet->GetBookmark();//Текущая ячейка
Form1->DBGrid1->DataSource->DataSet->First();
for(col=0;col<Form1->DBGrid1->FieldCount;col++){//добавляем имена колонок
result=f4_ExcelSend(1,col+1,1,Form1->DBGrid1->Fields[col]->DisplayLabel,true);
if(result==-1){Screen->Cursor=crDefault;return -1;}
}
Form1->ProgressBar1->Position=0;//Прогрессбар
Form1->ProgressBar1->Max=Form1->DBGrid1->DataSource->DataSet->RecordCount;
for(row=0;row<Form1->DBGrid1->DataSource->DataSet->RecordCount;row++){// получаем данные
Form1->ProgressBar1->Position=row;//Прогрессбар
for(col=0;col<Form1->DBGrid1->FieldCount;col++){
result=f4_ExcelSend(1,col+1,row+2,Form1->DBGrid1->Fields[col]->AsString,true);
if(result==-1){Screen->Cursor=crDefault;return -1;}
}
Form1->DBGrid1->DataSource->DataSet->Next();
}
Form1->DBGrid1->DataSource->DataSet->GotoBookmark(bm);//Текущая ячейка
Form1->DBGrid1->DataSource->DataSet->FreeBookmark(bm);
Form1->DBGrid1->DataSource->DataSet->EnableControls();
f4_ExcelVisible(true);//Сделать видимым Excel
Form1->ProgressBar1->Position=0;//Прогрессбар
Screen->Cursor=crDefault;
Application->ProcessMessages();
return 1;
}
|
Отредактировано Smart — 01/06/2006, 21:29 |
|
AVC |
Отправлено: 02.06.2006, 08:32 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE (Smart @ 01/06/2006, 20:19) | К сожалению сцылка, приведенная AVC, практически ничего не прояснила по причине невнятности подобных конструкций:
CODE |
CExcelExp::Export(ex, "C1", fdsSignsSIGN->AsString);
CExcelExp::Export(ex, "C2", fdsSignsNAME->AsString);
CExcelExp::Export(ex, "C3", fdsSignsPRINT_SIGN->AsInteger);
CExcelExp::Export(ex, "C4", fdsSignsDESCRIPTION->AsString);
|
Вроде разобрался, помогли исходники на Паскале, других не нашел
Сейчас запощу, мож кому пригодится. |
Да... Простите, но внимательно читать вы, похоже, так и не научились.
В том же посте olegenty от 26/08/2004, 09:01 где и CExcelExp::Export(ex, "C1", fdsSignsSIGN->AsString); но строк на 30 ниже приведено описание и реализация класса CExcelExp. Реализация метода Export тривиальна и, вполне, очевидна.
QUOTE |
Вот тока не надо про то, что "экспорт DBGrid в Excel невозможен по определению" — все уши прожужжали в форумах вместо конкретных примеров доступа к ячейкам данных. :~E
|
Надо. Вы не понимаете принципа. Из ячеек данных DBGrid'а можно экспортировать, причем ценой значительных усилий, содержимое только видимых в настоящий момент строк.
Вы же сами пишете
> for(row=0;rowDBGrid1->DataSource->DataSet->RecordCount;row++){// получаем данные
похоже без понимания происходящего.
PS. Готовое рабочее решение приведено в том же посте olegenty от 26/08/2004, 09:01. А если в нем вынести fdsSignJoins и имя файла в параметры то оно станет просто универсальным (у меня метод с такими параметрами добавлен в класс, аналогичный CExcelExp).
Отредактировано AVC — 02/06/2006, 07:33 |
|
Smart |
Отправлено: 02.06.2006, 12:17 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 35
|
Про принципы отображения DBGrid я в курсе, и беру данные через датасет с пониманием происходящего.
Заданный вопрос-то ведь все равно понятен, но во многих форумах получал отповедь о виртуальности грида и больше ничего.
Хочу подчеркнуть, что проблемы с Excel у меня не было, была проблема доступа к ячейкам датасета.
QUOTE |
Готовое рабочее решение приведено в том же посте olegenty от 26/08/2004, 09:01.
|
Оно не готовое. Попробуйте уяснить из приведенного куска, что такое fdsSignsSIGN, fdsSignsNAME, fdsSignsPRINT_SIGN, fdsSignsDESCRIPTION
Я не смог, наверное слабый мозк.
Отредактировано Smart — 02/06/2006, 12:22 |
|
avc* |
Отправлено: 02.06.2006, 12:40 |
|
Не зарегистрирован
|
QUOTE |
Попробуйте уяснить из приведенного куска, что такое fdsSignsSIGN, fdsSignsNAME, fdsSignsPRINT_SIGN, fdsSignsDESCRIPTION
|
Элементарно.
Мы знаем, что на входе есть выборка (DataSet). Увидев ->AsString и привыкнув работать с dataset'ами я тут же предположил, что это TField или его наследник. Посмотрел в Help'е — действительно на название AsString имеет монополию класс TField (и его наследники). Следовательно неопубликованный кусок кода выглядит примерно так
TField* fdsSignsSIGN;
fdsSignsSIGN = некий_не_интересующий_нас_dataset->FieldByName("не_интересное_имя_поля");
(или FindField, хотя я в этом сомневаюсь)
|
|
Smart |
Отправлено: 02.06.2006, 12:59 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 35
|
Ну, для меня это не элементарно...
Но все равно спасибо! |
|
|