?? 20000806011.htm
字號(hào):
<HTML>
<HEAD>
<TITLE>用C++Builder存取Excel</TITLE>
<META content="MSHTML 5.00.2314.1000" name=GENERATOR>
</HEAD>
<BODY aLink=#FF0000 bgColor=#ffffff leftMargin=0 link=#187800 topMargin=0
vLink=#990099>
<div align="center">
<table width="744" border="0" cellspacing="0" cellpadding="0" height="76">
<tr>
<td>
<p align="center"><span style="FONT-SIZE: 9pt"><strong><font size="3"><br>
用C++Builder存取Excel</font></strong></span></p>
<p>--- C++Builder是Borland公司繼Delphi之后又一成功的產(chǎn)品,她集VB、VC++ 及 Delphi 的優(yōu)點(diǎn)于一體而深得C語(yǔ)言愛(ài)好者的青睞。由于多數(shù)操作者愛(ài)用
MicroSoft公司的Excel組織數(shù)據(jù),為此本文介紹了用C++Builder存取Excel 文件的兩種方法。<br>
<br>
---- 一.用OLE技術(shù)操縱Excel<br>
<br>
---- OLE(對(duì)象鏈接與嵌入)是微軟提出的標(biāo)準(zhǔn),是應(yīng)用程序間交換數(shù)據(jù)、相互操作的一種方式,MS OFFICE 提供了很強(qiáng)的 OLE
服務(wù)功能,VB、Delphi 及C++Builder等語(yǔ)言都可以以客戶方式向Excel提交命令,以存取其數(shù)據(jù),其中VB和Delphi最為簡(jiǎn)單,在語(yǔ)法上就采用類VBA的語(yǔ)句,本報(bào)九九年第48期的《在Delphi中操作Excel》一文曾介紹了Delphi的做法。我們?cè)詾镃++Builder照搬Delphi,結(jié)果語(yǔ)法編譯都未能通過(guò),查不到這方面具體介紹的資料。經(jīng)反復(fù)試驗(yàn)方知:原來(lái)C++Builder采用間接的辦法,利用變體類Variant所提供的四個(gè)“方法”向OLE服務(wù)程序提交操縱命令:<br>
<br>
Variant Variant::OlePropertyGet(屬性名,參數(shù)….);<br>
// 取對(duì)象屬性<br>
Void Variant::OlePropertySet(屬性名,參數(shù)….);<br>
// 設(shè)置對(duì)象屬性<br>
Variant Variant::OleFunction(函數(shù)名,參數(shù)….);<br>
// 運(yùn)行對(duì)象的函數(shù)<br>
void Variant::OleProcedure(過(guò)程名,參數(shù)….);<br>
// 運(yùn)行對(duì)象的過(guò)程<br>
<br>
其頭文件“vcl\utilcls.h”必須嵌在用戶程序中,<br>
對(duì)于這四個(gè)長(zhǎng)長(zhǎng)的方法名可在程序中用宏語(yǔ)句重新定義一下:<br>
#define PG OlePropertyGet<br>
#define PS OlePropertySet<br>
#define FN OleFunction<br>
#define PR OleProcedure<br>
<br>
例如對(duì)于VB的提交語(yǔ)句:<br>
Ex.ActiveWorkBook.ActiveSheet.Cells(1,2).Value=3<br>
為便于理解在C++Builder對(duì)應(yīng)的語(yǔ)句可分解為如下四句:<br>
Variant t1=Ex.OlePropertyGet("ActiveWorkBook");<br>
Variant t2=t1.OlePropertyGet("ActiveSheet");<br>
Variant t3=t2.OlePropertyGet("Cells,1,2);<br>
t3.OlePropertySet("Value",3);<br>
可去掉中間變量將這四句合為一句,就是:<br>
Ex.PG("ActiveWorkBook").PG("ActiveSheet").<br>
PG("Cells",1,2).PS("Value",3);<br>
我們將下面的VB程序片段改成對(duì)應(yīng)的C++Builder程序以供參考:<br>
Private Sub Command1_Click() ' Visual Basic程序片段<br>
Dim Ex As Object,Wb As Object, Sh1 As Object<br>
Set Ex = CreateObject("Excel.Application")<br>
Ex.WorkBooks.Open("c:\book1.xls")<br>
Set Wb = Ex.Activeworkbook<br>
Set Sh1 = Wb.ActiveSheet<br>
Text1.Text = Sh1.Cells(1, 1).Value<br>
For i = 1 To 10: For j = 1 To 10<br>
Sh1.Cells(i, j).Value = i * 100 + j<br>
Next j: Next i<br>
Wb.save: Wb.Close: Ex.Quit<br>
End Sub ' - - - - - -- - - - - - - - - - -<br>
<br>
#include "Unit1.h" // C++Builder程序片段<br>
#include "vcl\utilcls.h" // util classes實(shí)用類說(shuō)明<br>
// …省寫此處原一段代碼<br>
// 請(qǐng)?jiān)诖颂幉迦肷厦嫣峒暗乃膫€(gè)宏定義語(yǔ)句<br>
void __fastcall TForm1::Button1Click(TObject *Sender)<br>
{ Variant Ex,Wb,Sh1;<br>
Ex=Variant::CreateObject("Excel.Application");<br>
Ex.PG("WorkBooks").PR("Open","c:\\book1.xls");<br>
Wb=Ex.PG("ActiveWorkBook"); Sh1=Wb.PG("ActiveSheet");<br>
Edit1->Text=Sh1.PG("Cells",1,1).PG("Value");<br>
for (int i=1;i<=10;i++)<br>
for (int j=1;j<=10;j++)<br>
Sh1.PG("Cells",i,j).PS("Value",i*100+j);<br>
Wb.PR("Save"); Wb.PR("Close");<br>
}<br>
<br>
---- 使用這種方法的程序運(yùn)行時(shí),必須保證系統(tǒng)中同時(shí)有MS OFFICE;下面我們?cè)俳榻B另一種脫離MS OFFICE也能存取Excel表格的方法。<br>
---- 二.用ODBC數(shù)據(jù)庫(kù)技術(shù)存取Excel<br>
<br>
---- ODBC就是開(kāi)放式數(shù)據(jù)庫(kù)鏈接標(biāo)準(zhǔn),不同種類的數(shù)據(jù)庫(kù)只需提供各自的ODBC 驅(qū)動(dòng)程序就可按相同的命令操縱,微軟同樣為Excel提供了ODBC驅(qū)動(dòng)程序,我們可在程序中象數(shù)據(jù)庫(kù)一樣存取Excel表格。定義好ODBC數(shù)據(jù)源后,實(shí)際試驗(yàn)中并沒(méi)有如想象的那樣簡(jiǎn)單,在控件Table的屬性TableName中總是檢索不到表名,同樣也沒(méi)有相關(guān)的資料可供查閱。通過(guò)對(duì)Excel的分析,終于發(fā)現(xiàn)了問(wèn)題的關(guān)鍵所在:ODBC的表名并不就是Excel的工作表名(如Sheet1),在Excel
表格中必須對(duì)要求操作的行列區(qū)域定義一個(gè)“名稱”作為數(shù)據(jù)庫(kù)的表名,該區(qū)域的首行各列必須是字段名(否則首行數(shù)據(jù)會(huì)當(dāng)成字段名),可以定義多個(gè)表名。具體操作步驟如下:<br>
<br>
---- 1.在Excel上定義“表名”:<br>
<br>
---- 運(yùn)行Excel程序,打開(kāi)或新建一表格,按下鼠標(biāo)左鍵選擇一片區(qū)域(起始行先填上字段名),再將鼠標(biāo)位置點(diǎn)到左上角的地址欄,輸入一表名如ABC,或者在菜單上選:“插入(I)”-“名稱(N)”-“定義(D)”,再輸入表名(若已定義,
可在此處刪除掉),存盤退出(假定文件名取為c:\Book.xls),若嫌字段名行多余,存盤前可隱藏掉;<br>
<br>
---- 2.定義ODBC數(shù)據(jù)源:<br>
<br>
---- 從Windows桌面“我的電腦"進(jìn)入“控制面板”,雙擊“32位ODBC”圖標(biāo),運(yùn)行“用戶DSN”中的“添加(D)"后選“Excel
Driver(*.xls)", 再點(diǎn)“完成”便彈出對(duì)話框,在“數(shù)據(jù)源名(N)"右邊填一名稱,如:excel01,在“版本(V)"上選“Excel97",
點(diǎn)中“選項(xiàng)”取消“只讀”,在“選定工作目錄”中,選定Excel文件名(本例 c:\Book1.xls),再點(diǎn)“確定”直至退出;<br>
<br>
---- 3.設(shè)置Database控件避免登錄檢查:<br>
<br>
---- 運(yùn)行C++Builder,在Form1中加上Data Access的三個(gè)控件:Database1、 DataSource1、Table1,加入Database1的目的是為了避免打開(kāi)數(shù)據(jù)庫(kù)時(shí)出現(xiàn)登錄框,為此雙擊此控件彈出一對(duì)話框,在Alias
name中選ODBC數(shù)據(jù)源名(本例為Excel01),在Name中填上一新的別名(本例取Excel02),再點(diǎn)“Defaults” 出現(xiàn)一批參數(shù)缺省值,最后取消Options中的兩項(xiàng)“Login
prompt"與"Keep inactive connect”,點(diǎn)OK退出;<br>
<br>
---- 4.設(shè)置其它控件屬性:<br>
<br>
---- 將Table1的屬性DatabaseName選為步驟3中的新別名Excel02,再將另一屬性TableName選為步驟1的表名(本例為ABC);將控件DataSource1的屬性
DataSet選為Table1;雙擊Form1,在FormCreate事件子程序內(nèi)加上一句 Table1- >Open( );<br>
<br>
---- 5.查看數(shù)據(jù)庫(kù)內(nèi)容:<br>
<br>
---- 為了直接看到Excel數(shù)據(jù),在Form1中再加上Data Controls的控件DBGrid1 和DBNavigator1,將兩者的屬性DataSource都選為DataSource1,雙擊Table1
的屬性Active將值改為true,等待數(shù)秒就可看到DBGrid1中出現(xiàn)數(shù)據(jù),最后恢復(fù)Tabel1- >Active為false;<br>
<br>
---- 注意:程序編譯前,必須將剛打開(kāi)的表關(guān)閉,即:使Table1- >Active為false, 否則程序運(yùn)行時(shí)報(bào)告出錯(cuò),因?yàn)镋xcel表總是被ODBC以“獨(dú)占”方式打開(kāi);<br>
<br>
---- 我們使用的是C++ Builder 4.0專業(yè)版,電子表格為Excel 97</p>
</td>
</tr>
</table>
</div>
</BODY></HTML>
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -