我之前使用OLE來控制excel檔案,但是發現好像運行的很慢,而且excel的行程有時沒辦法關閉,所以想改用ADO來控制,但是我是初學者,對這方面完全不熟,有哪位高人能指點一下。最好能有個范例。。謝謝。
uj5u.com熱心網友回復:
這是我自己寫的一個呼叫ole寫入excel的例子,將dbgrid中的資料寫入excel,沒用過ado,但這個例子有關閉excel的方法,你可以借鑒一下,
void __fastcall TForm5::rzbtbtn11Click(TObject *Sender)
{
Variant vExcelApp,vSheet,vInter;
AnsiString name = Trim(edt2->Text);
AnsiString loc = "匯出后的檔案將存放在C盤下。";
AnsiString filename = "C:\\"+name+".xls";
AnsiString MBfile = "C:\\excel\\模板\\123.xls";
loc += loc + ",檔案名為:" ;
loc += name;
loc += ".xls";
loc += "\n在匯出程序中請勿打開excel檔案,否則會造成匯入失敗!" ;
try
{
vExcelApp = Variant::CreateObject("Excel.Application");
Application->MessageBoxA(loc.c_str(),"提示:",MB_OK+48); //提示用戶檔案所在
vExcelApp.OlePropertySet("Visible", false); //隱藏Excel界面
vExcelApp.OlePropertyGet("Workbooks").OleFunction("Open",MBfile.c_str());
//打開excel
vSheet = vExcelApp.OlePropertyGet("ActiveWorkBook").OlePropertyGet("Sheets",1); //操作表
//創建一個作業薄物件 //讓該物件連接sheet1
vSheet.OleProcedure("Select");
dbgrd1->DataSource->DataSet->First();
for(int i = 0; i < dbgrd1->DataSource->DataSet->RecordCount; i++)
{
// 普通資料行的行高16
vExcelApp.OlePropertyGet("Rows", i + 4).OlePropertySet("RowHeight", 16);
//資料從第4行、第4列開始寫入
for(int j = 2 ; j < dbgrd1->Columns->Count; j++)
{
vSheet.OlePropertyGet("Cells", i + 4, j+1).OlePropertySet("Value",
dbgrd1->DataSource->DataSet->FieldByName(dbgrd1->Columns->Items[j]->FieldName)->AsString.c_str());
}
dbgrd1->DataSource->DataSet->Next();
pb1->Position++;
}
vExcelApp.OlePropertyGet("ActiveWorkbook").Exec(Procedure("SaveAs")<<filename); // 保存Excel檔案并退出
vExcelApp.OleFunction("Quit");
vSheet = Unassigned;
vExcelApp = Unassigned;
vInter = Unassigned;// 作業結束
pnl1->Visible = false;
AnsiString tscg = "資料已經成功匯入\n<"+filename+">\n中!";
MessageBox(0, tscg.c_str(),"提示:", MB_OK | MB_ICONINFORMATION);
}
catch(Exception &e)
{
vExcelApp.OleFunction("Quit");
vSheet = Unassigned;
vExcelApp = Unassigned;
vInter = Unassigned;
AnsiString s = e.Message+"\n運行Excel出錯,請確認是否安裝了Excel組件,然后重試!\n如果問題依然存在,請聯系開發人員!";
Application->MessageBoxA(s.c_str(),"錯誤提示 :",MB_OK+16);
return;
}
}
http://www.ccrun.com/article.asp?i=529&d=0iezy5 去妖哥的這里看看,ole呼叫的方法,很全!
uj5u.com熱心網友回復:
不知道樓主是要盡量修復OLE方式還是確實要使用ADO方式
uj5u.com熱心網友回復:
都是用OLE操作Excel,只要代碼運行不出錯,一定是可以關閉Excel的。
uj5u.com熱心網友回復:
用ADO來控制
String ADOConstr , ExcelFile ;
ExcelFile = "E:\\201305\\cb2010\\ado_excel\\Release\\Book1.xls" ;
ADOConstr= String().sprintf(L"Provider=Microsoft.Jet.OLEDB.4.0;\
User ID=Admin;Data Source=%s; \
Mode=Share Deny None;Extended Properties=Excel 8.0;\
HDR=No;Jet OLEDB:System database="";\
Jet OLEDB:Registry Path="";\
Jet OLEDB:Database Password="";\
Jet OLEDB:Engine Type=35;\
Jet OLEDB:Database Locking Mode=0;Jet OLEDB:\
Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;\
Jet OLEDB:New Database Password="";\
Jet OLEDB:Create System Database=False;\
Jet OLEDB:Encrypt Database=False;Jet OLEDB:\
Don't Copy Locale on Compact=False;Jet OLEDB:\
Compact Without Replica Repair=False;Jet OLEDB:SFP=False ",ExcelFile);
con1->Close() ;
con1->ConnectionString = ADOConstr;
con1->Open() ;
con1->GetTableNames(cbb1->Items , false ) ;
void __fastcall TForm1::btn1Click(TObject *Sender)
{
if(cbb1->ItemIndex < 0 ) return ;
qry1->SQL->Clear() ;
qry1->SQL->Add(String().sprintf(L"select * from [%s]", cbb1->Items->Strings[cbb1->ItemIndex].w_str() )) ;
qry1->Open();
ShowMessage( String().sprintf(L"%d * %d",qry1->FieldList->Count,qry1->RecordCount ) );
}
uj5u.com熱心網友回復:
Quote: 參考 1 樓 llsj0522 的回復:
這是我自己寫的一個呼叫ole寫入excel的例子,將dbgrid中的資料寫入excel,沒用過ado,但這個例子有關閉excel的方法,你可以借鑒一下,
我的程式有關閉,和你關閉的方法是一樣的。但是在有些電腦上就是沒辦法關閉,導致電腦直接崩潰。所以我才想改用ADO來控制excel。
uj5u.com熱心網友回復:
參考 2 樓 kfrght 的回復: 不知道樓主是要盡量修復OLE方式還是確實要使用ADO方式
我覺得ole方式的讀取速度有點慢,所以想改用別的方式,ADO或者別的方式。
uj5u.com熱心網友回復:
參考 6 樓 u011415950 的回復: Quote: 參考 2 樓 kfrght 的回復:
不知道樓主是要盡量修復OLE方式還是確實要使用ADO方式
我覺得ole方式的讀取速度有點慢,所以想改用別的方式,ADO或者別的方式。
專門給樓主做了一篇教程,發表在我的博客:http://blog.csdn.net/kfrght/article/details/17019205
具體內容如下:
用ADO控制元件操作Excel的.xls檔案的最詳細的教程(2013.11.29首發)
用ADO操作Excel的.xls檔案有速度快,可以在一定條件下突破Excel的總行數限制(超過這個行數限制在Excel中操作可能會有問題),操作具有真正的隱秘性等優點。
而用OLE操作Excel檔案有兩個弊端,一是操作的效率較低占用資源較大,二是需要安裝Office中的Excel或WPS Office的WPS表格。
但用ADO如資料庫一般操作Excel的.xls檔案使用的人較少,為此我將ADO操作Excel的.xls檔案的方法及注意事項整理如下,供廣大初學者研究和使用:
第一步:準備Excel檔案:
1)新建一個Excel檔案;
2)在檔案的一個作業簿的第一行逐個輸入列名稱;
3)用滑鼠選取第一行包含列名稱的單元格;注意:選中有列名稱的單元格就可以了,否則運行時輸入資料出錯,并且只能操作和顯示選中行數減一的行;
4)在選單“插入->名稱->定義”中彈出的對話框中輸入表名稱;
5)保存Excel檔案的修改。
說明:第一行(列名稱所在的行)可以選擇隱藏,不影響使用。
第二步:設定ADOTable控制元件的連接串:
(1)添加一個ADOTable控制元件至表單上,單擊ConnectionString屬性右方的對話框按鈕,打開資料庫連接對話框;
(2)單擊Use Connection String單選按鈕中的Build..按鈕;
(3)選取Microsoft Jet 4.0 OLE DB Provider驅動程式(該驅動除了可以連接*.mdb的Access檔案外,還可以連接*.xls的Excel檔案);
(4)單擊[資料連接屬性]對話框里[提供者]選項卡的[下一步]按鈕,在里面選擇要連接的Excel檔案;
(5)單擊[資料連接屬性]對話框里的[所有]選項卡標簽,來修改里面的Extended Properties:
雙擊Extend Properties屬性,在文本框里輸入“Excel 8.0”,這代表我們要利用Microsoft Jet 4.0 OLE DB Provider驅動程式來連接Excel檔案而不是Access檔案!
(6)把ADOTable組件的TableName屬性選定為要打開的作業表;注意:帶“$”的不是真正的表名稱,不要選,否則出錯。
注:用ADOQuery等控制元件可以這樣打開:SELECT * FROM [書籍銷售$]; // 要加$?
第三步:在.cpp檔案里添加如下代碼:
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//ADOTable1->ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=BOOK.xls;Extended Properties=Excel 8.0;Persist Security Info=False"; // 典型連接串
ADOTable1->Open();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
ADOTable1->Close();
}
// 連接例子①:-----------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ADOQuery1->Close();
ADOQuery1->SQL->Clear(); // 用于清空ADOQuery
ADOQuery1->ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=作業表.xls;Extended Properties=Excel 8.0;Persist Security Info=False";
//ADOQuery1->Connection=ADOConnection1;
//ADOQuery1->Filtered=false; // 關閉過濾
ADOQuery1->SQL->Add("SELECT * FROM [編碼];");
ADOQuery1->Open();
//ADOQuery1->ExecSQL(); // 寫入洗掉或修改資料時使用
}
// 完整例子②:將SQLServer中的資料寫入Excel資料庫:---------------------------
⑴ 在.cpp檔案中添加:-------------------------
extern PACKAGE TForm1 *Form1;
extern PACKAGE AnsiString iADOcs1; // 主要資料庫的連接串
extern PACKAGE AnsiString iADOcs2; // 主要資料庫的連接串
//---------------------------------------------------------------------------
#endif
⑵ 在.h檔案中添加:---------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
AnsiString iADOcs1; // 主要資料庫的連接串
AnsiString iADOcs2; // 主要資料庫的連接串
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
iADOcs1="Provider=SQLOLEDB.1;Password=qazxsw21;Persist Security Info=True;User ID=pdm;Initial Catalog=pdm;Data Source=wdserver3";
iADOcs2="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=作業表.xls;Extended Properties=Excel 8.0;Persist Security Info=False";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ADOQuery1->Close();
ADOQuery1->SQL->Clear(); // 用于清空ADOQuery
ADOQuery1->ConnectionString=iADOcs1;
ADOQuery1->SQL->Add("SELECT oid,name,doctype,createtime,creater FROM pdmDocmaster ORDER BY createtime DESC;");
ADOQuery1->Open();
ADOQuery1->First();
ADOCommand1->ConnectionString=iADOcs2; // 連接字串
AnsiString iT1,iT2,iT3,iT4,iT5;
ProgressBar1->Max=ADOQuery1->RecordCount; // 設定最大值
ProgressBar1->Position=0; // 設定進度條進度
ProgressBar1->Left=(Form1->Width-ProgressBar1->Width)/2; // 設定進度條的橫向位置在中間
ProgressBar1->Visible=true; // 顯示進度條
while(!ADOQuery1->Eof)//如果不為空
{
iT1=ADOQuery1->FieldByName("oid")->AsString.Trim();
iT2=ADOQuery1->FieldByName("name")->AsString.Trim();
iT3=ADOQuery1->FieldByName("doctype")->AsString.Trim();
iT4=ADOQuery1->FieldByName("createtime")->AsString.Trim();
iT5=ADOQuery1->FieldByName("creater")->AsString.Trim();
ADOCommand1->CommandText="INSERT INTO 編碼(編碼,名稱,類別,時間,人員)VALUES('"+iT1+"','"+iT2+"','"+iT3+"','"+iT4+"','"+iT5+"');";
ADOCommand1->Execute();
ADOQuery1->Next();
ProgressBar1->Position++; // 進度條進度增加
}
ProgressBar1->Visible=false; // 隱藏進度條
}
uj5u.com熱心網友回復:
4樓的很清楚了
uj5u.com熱心網友回復:
參考 4 樓 hyz_cs 的回復: void __fastcall TForm1::btn1Click(TObject *Sender)
{
if(cbb1->ItemIndex < 0 ) return ;
qry1->SQL->Clear() ;
qry1->SQL->Add(String().sprintf(L"select * from [%s]", cbb1->Items->Strings[cbb1->ItemIndex].w_str() )) ;
qry1->Open();
ShowMessage( String().sprintf(L"%d * %d",qry1->FieldList->Count,qry1->RecordCount ) );
}
[/code]
cbb是哪個控制元件啊?
uj5u.com熱心網友回復:
參考 9 樓 u011415950 的回復: cbb是哪個控制元件啊?
TComboBox 用來選擇excel的作業表
uj5u.com熱心網友回復:
參考 10 樓 hyz_cs 的回復: Quote: 參考 9 樓 u011415950 的回復:
cbb是哪個控制元件啊?
TComboBox 用來選擇excel的作業表
那這個TComboBox 是另外寫一段程式來使用咯~~~
uj5u.com熱心網友回復:
參考 11 樓 u011415950 的回復: Quote: 參考 10 樓 hyz_cs 的回復:
Quote: 參考 9 樓 u011415950 的回復:
cbb是哪個控制元件啊?
TComboBox 用來選擇excel的作業表
那這個TComboBox 是另外寫一段程式來使用咯~~~
你應該從手動設定Excel檔案的表結構開始一步一步的來,跨度太大對初學者來說會影響進度的,我的教程里面有很詳細的操作步驟,你一步一步的按斬訓本路子來基本就順了,至少腦袋里不會糊涂,然后你就可以拔高了
uj5u.com熱心網友回復:
TComboBox里的東東屬于獲取資料庫結構的范疇,獲取庫里面的表名稱之后還會有獲取表里面的列名稱等
uj5u.com熱心網友回復:
要先建表,也可以用SQL陳述句建表
uj5u.com熱心網友回復:
參考 12 樓 kfrght 的回復: 你應該從手動設定Excel檔案的表結構開始一步一步的來,跨度太大對初學者來說會影響進度的,我的教程里面有很詳細的操作步驟,你一步一步的按斬訓本路子來基本就順了,至少腦袋里不會糊涂,然后你就可以拔高了
編譯出現“定義了過多欄位”的錯誤,這是什么情況?
uj5u.com熱心網友回復:
參考 15 樓 u011415950 的回復: Quote: 參考 12 樓 kfrght 的回復:
你應該從手動設定Excel檔案的表結構開始一步一步的來,跨度太大對初學者來說會影響進度的,我的教程里面有很詳細的操作步驟,你一步一步的按斬訓本路子來基本就順了,至少腦袋里不會糊涂,然后你就可以拔高了
編譯出現“定義了過多欄位”的錯誤,這是什么情況?
初步懷疑是你定義的列外面的其余列有額外的資料,
根據SQL的建議,盡量不要使用“*”來顯示所有列,而是直接使用列名,如:列1,列2...等
一定要用的話你可以試試兩種方法,一是隱藏定義的列之外的列,二是使用select * from [你的表名字$A:IU];其中的A:IU表示查詢第A列到倒數第二列
uj5u.com熱心網友回復:
初步懷疑是你定義的列外面的其余列有額外的資料,
根據SQL的建議,盡量不要使用“*”來顯示所有列,而是直接使用列名,如:列1,列2...等
一定要用的話你可以試試兩種方法,一是隱藏定義的列之外的列,二是使用select * from [你的表名字$A:IU];其中的A:IU表示查詢第A列到倒數第二列
定義過多欄位這個問題已經解決,是我在設定的時候沒有隱藏定義的列之外的列. " ADOQuery1->SQL->Add("SELECT * FROM [編碼];");"這條查詢陳述句里的編碼是什么意思啊?我真的很菜,謝謝大神的指導了。
uj5u.com熱心網友回復:
在select陳述句中,from后面定義的是表名字,一般的不用括弧,用的話表示其不是保留字,比如在sql的規范的所有版本中AS就是SQL的保留字,用其為資料庫或列名時要用[]括起來
uj5u.com熱心網友回復:
用的話表示其是保留字
[編碼]就是表名稱,可以直接寫成編碼就可以了,使用括弧是我早期在ACCESS的VBA編程中養成的習慣
uj5u.com熱心網友回復:
使用括弧等一些符號可以使代碼在閱讀時比較的直觀
uj5u.com熱心網友回復:
參考 18 樓 kfrght 的回復: 在select陳述句中,from后面定義的是表名字,一般的不用括弧,用的話表示其不是保留字,比如在sql的規范的所有版本中AS就是SQL的保留字,用其為資料庫或列名時要用[]括起來
我定義SQL陳述句總是會出錯,出錯資訊是不正確定義引數。我想請教那個陳述句要怎么寫。比如我現在想搜尋A1到A3的資料,這個要怎么寫?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/130034.html
標籤:基礎類
上一篇:C++請教。。。
下一篇:C++ word添加水印,如果有幾個節,怎么回圈添加?