全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:7239
推到 Plurk!
推到 Facebook!

如何用 OLE 取得 Excel 內容.

尚未結案
erosme
初階會員


發表:5
回覆:44
積分:29
註冊:2002-12-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-03-18 22:30:03 IP:61.216.xxx.xxx 未訂閱
Dear All, 由於我某一個Excel Files 內容並無規則可言, 故我無法使用ODBC 或 ADO 的方式來讀取內容. 所以我被迫使用 OLE 來取得資料. 我想請問誰有 OLE 的所有參數表.( ps: For C Builder ) 或是有誰會取得 Excel Files 有幾個 Sheet, SheetName, Row Count,Col Count . PS: 一定要在 C Builder 可以使用的,且是取出資料; Delphi 的存取我已經有了.
GaryKao99
中階會員


發表:46
回覆:102
積分:54
註冊:2002-08-23

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-04-03 18:43:43 IP:210.201.xxx.xxx 未訂閱
http://delphi.ktop.com.tw/topic.php?topic_id=22668 這個是你要的嗎
erosme
初階會員


發表:5
回覆:44
積分:29
註冊:2002-12-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-04-06 15:19:18 IP:218.166.xxx.xxx 未訂閱
引言: http://delphi.ktop.com.tw/topic.php?topic_id=22668 這個是你要的嗎
Dear GaryKao99 , 很感謝你的回覆, 但我需要的是由 excel file 取出資料.
tender
初階會員


發表:23
回覆:90
積分:37
註冊:2002-09-26

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-04-07 09:35:33 IP:61.30.xxx.xxx 未訂閱
    如果你是用 Microsoft Jet 4.0 Provider Properties 在Extended Properties 的設定如下,可以任何格式        Extended Properties Property Settings The following table lists the Extended Properties property values to use for the data sources supported by the Jet database engine. Table 14. Extended Properties property values Data Source Extended Properties Property Value dBASE dBASE III dBASE IV dBASE 5.0 soft Excel Excel 3.0 Excel 4.0 Excel 5.0 Excel 8.0 FoxPro FoxPro tables are accessed by using the Microsoft FoxPro ODBC driver. Lotus Lotus WK1 Lotus WK3 Lotus WK4 ODBC ODBC Paradox Paradox 3.x Paradox 4.x Paradox 5.x Paradox 7.x HTML HTML Import Microsoft Exchange Exchange 4.03 Text Text 1 The Excel 5.0 source database type string is used to specify both Microsoft Excel 5.0 and 7.0 workbooks. 2 The Excel 8.0 source database type string is used to specify both Microsoft Excel 8.0 and 9.0 workbooks. 3 The Exchange 4.0 source database type string is used to specify Microsoft Exchange 4.0, 5.0, and Outlook folders and address books.
erosme
初階會員


發表:5
回覆:44
積分:29
註冊:2002-12-23

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-04-11 20:01:37 IP:218.166.xxx.xxx 未訂閱
很感謝你的回覆, 但我是用OLE.
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-04-14 14:32:24 IP:61.218.xxx.xxx 未訂閱
erosme 您好:    試試看這篇文章 http://www.yesky.com/20030213/1651912.shtml    在C++ Builder中用Ole控制Excel表   作者: 姜宏華    筆者在實際工作中經常用Excel表做數據報表,大多數表格的數據都要從數據庫中讀取,這樣我就用C++Builder做了一個報表程序,方便了很多,現在把它共享給C++Builder愛好者們,就算為豐富C++Builder的文檔資料做點事情吧。     首先把Excel報表文件保存到一個指定目錄下,最好放在可執行程序的子目錄下,作為模板文件。可以把報表標題、表頭等設置好。這裡是保存在trpt子目錄下。     然後建一個report目錄,作為報表目標文件夾,存放填好數據的報表,可以由用戶直接操作。     首先確定在你的機器中裝有Office。這裡一Office2000為例。     在C++Builder中新建一個工程,在窗體Form1上面放一個兩個按鈕SaveButton和ReadButton,分別用來保存數據到Excel表和顯示剛剛保存的Excel表。     在SaveButton按鈕的單擊事件中把從數據庫中取到的數據放入到指定的Excel表中並將改文件拷貝到report目錄下。在ReadButto按鈕的單擊事件中顯示report目錄下的報表文件,方便用戶修改和另外保存。     在Form1.h頭文件中定義幾個變量:
private:
Variant Ex,Wb,Sheet,ERange,EBorders;       並在文件頭中包含如下語句:    #include "Excel_2K_SRVR.h"
#include        在Form1.cpp的文件頭中加入    #pragma link "Excel_2K_SRVR"       主要代碼如下:    void __fastcall TForm1:: SaveButtonClick(TObject *Sender)
{
try
{
SaveButton->Enabled = false;
ReadButton->Enabled = false;//使兩個按鈕無效    file://取報表文件CardSend.xls的完整目錄名
AnsiString ExcelFileName = GetCurrentDir() "\\trpt\\table.xls";     if(!FileExists(ExcelFileName))
{
Application->MessageBox("報表模板文件不存在,無法打開!",
"錯誤",MB_ICONSTOP|MB_OK);
return;
}
file://建立Excel的Ole對像Ex
try
{
Ex = Variant::CreateObject("Excel.Application");
}
catch(...)
{
Application->MessageBox("無法啟動Excel","錯誤",MB_ICONSTOP|MB_OK);
return;
}
file://設置Excel為不可見
Ex.OlePropertySet("Visible",false);
file://打開指定的Excel報表文件。報表文件中最好設定只有一個Sheet。
Ex.OlePropertyGet("WorkBooks").OleProcedure("Open",ExcelFileName.c_str());
Wb = Ex.OlePropertyGet("ActiveWorkBook");
Sheet = Wb.OlePropertyGet("ActiveSheet");//獲得當前默認的Sheet    file://清空Excel表,這裡是用循環清空到第300行。對於一般的表格已經足夠了。
AnsiString strRowTemp; 
AnsiString strRange;
int iCols,iRows;//記錄列數和行數    /*從第三行開始,到第300行止。一般第一行是表標題,第二行是副標題或者製表日期。*/
for(iRows=3;iRows<300;iRows  )
{ file://假設只有6列。
for (iCols = 1;iCols < 7; iCols  )
{
file://清空行
Sheet.OlePropertyGet("Cells",iRows,iCols).OlePropertySet("Value","");
}
file://去掉表格邊框
strRange = "A" IntToStr(iRows) ":F" IntToStr(iRows);//獲取操作範圍
ERange = Sheet.OlePropertyGet("Range",strRange.c_str());
EBorders = ERange.OlePropertyGet("Borders");//獲取邊框對像
EBorders.OlePropertySet("linestyle",xlNone);
}    AnsiString strPtrDate; file://存放當前日期,作為製表日期
DateSeparator = '-';
ShortDateFormat = "yyyy/m/d";//設置為年/月/日格式    strPtrDate = DateToStr(Date());//取當前日期    AnsiString strYear = strPtrDate.SubString(1,4);
strPtrDate = strPtrDate.SubString(6,strPtrDate.Length()-5);
AnsiString strMonth = strPtrDate.SubString(1,strPtrDate.Pos("-")-1);
AnsiString strDay = 
strPtrDate.SubString(strPtrDate.Pos("-") 1,
strPtrDate.Length()-strPtrDate.Pos("-"));
strPtrDate = strYear "年" strMonth "月" strDay "日";    AnsiString strData = "報表標題";//報表標題
file://將報表標題置於第一行第一列。在此之前,應將報表文件的標題格式設定好。
Sheet.OlePropertyGet("Cells",1,1).OlePropertySet("Value",
strData.c_str());
file://將製表日期置於表格第二行的右側。
Sheet.OlePropertyGet("Cells",2,5).OlePropertySet("Value",
strPtrDate.c_str());    iRows = 3;//在第三行放置表格的列名
Sheet.OlePropertyGet("Cells",iRows,1).OlePropertySet("Value","列名1");
Sheet.OlePropertyGet("Cells",iRows,2).OlePropertySet("Value","列名2");
Sheet.OlePropertyGet("Cells",iRows,3).OlePropertySet("Value","列名3");
Sheet.OlePropertyGet("Cells",iRows,4).OlePropertySet("Value","列名4");
Sheet.OlePropertyGet("Cells",iRows,5).OlePropertySet("Value","列名5");
Sheet.OlePropertyGet("Cells",iRows,6).OlePropertySet("Value","列名6");
file://畫表格邊框,在A3:F3之間取範圍
strRange = "A" IntToStr(iRows) ":F" IntToStr(iRows);
ERange = Sheet.OlePropertyGet("Range",strRange.c_str());
EBorders = ERange.OlePropertyGet("Borders");
EBorders.OlePropertySet("linestyle",xlContinuous);
EBorders.OlePropertySet("weight",xlThin);
EBorders.OlePropertySet("colorindex",xlAutomatic);
iRows  ;
file://從數據庫中取數據(略),假設數據集放入Query1中。
Query1->Open();//打開數據集
file://循環取數
while(!Query1->Eof)
{ 
file://循環取字段的數據放到Excel表對應的行列中
for(iCols=1;iCols<7;iCols  )
{ 
strRowTemp = Query1->Fields->Fields[iCols-1]->AsString;
Sheet.OlePropertyGet("Cells",iRows,iCols).OlePropertySet("Value",
strRowTemp.c_str());
}
file://畫該行的表格邊框
strRange = "A" IntToStr(iRows) ":F" IntToStr(iRows);
ERange = Sheet.OlePropertyGet("Range",strRange.c_str());
EBorders = ERange.OlePropertyGet("Borders");
EBorders.OlePropertySet("linestyle",xlContinuous);
EBorders.OlePropertySet("weight",xlThin);
EBorders.OlePropertySet("colorindex",xlAutomatic);
iRows  ;
Query1->Next();
}//while結束    Wb.OleProcedure("Save");//保存表格
Wb.OleProcedure("Close");關閉表格
Ex.OleFunction("Quit");退出Excel
file://定義目標文件名
AnsiString DestinationFile =
GetCurrentDir() "\\report\\table.xls";
file://將剛剛修改的Excel表格文件table.xls拷貝到report目錄下
if(!CopyFile(ExcelFileName.c_str(),DestinationFile.c_str(),false))
{
Application->MessageBox("複製文件操作失敗,Excel文件可能正在使用中!",
"錯誤",MB_ICONSTOP|MB_OK);
return;
}
Application->MessageBox("成功完成報表保存!\n可以按\'打開Excel文件\'
按鈕進行報表工作","提示",MB_ICONINFORMATION|MB_OK);    SaveButton ->Enabled = true;
ReadButton ->Enabled=true;
}//try結束
catch(...)
{
Application->MessageBox("操作Excel表格失敗!",
"錯誤",MB_ICONSTOP|MB_OK);
Wb.OleProcedure("Close");
Ex.OleFunction("Quit");
SaveButton ->Enabled = true;
ReadButton ->Enabled=false;
}
}       至此,完成報表數據的寫入工作。如果要對完成的Excel表進行操作,可以點擊"打開Excel表文件按鈕"(ReadButton),進行修改,保存,打印等操作。ReadButton的單擊事件如下實現:    void __fastcall TForm1:: ReadButtonClick(TObject *Sender)
{
try
{
file://指定report目錄下的報表文件用於用戶操作
AnsiString ExcelFileName = 
GetCurrentDir(); "\\report\\table.xls";    if(!FileExists(ExcelFileName))
{
Application->MessageBox("Excel表文件不存在,無法打開!",
"錯誤",MB_ICONSTOP|MB_OK);
return;
}    try
{
Ex = Variant::CreateObject("Excel.Application");
}
catch(...)
{
Application->MessageBox("無法啟動Excel","錯誤",MB_ICONSTOP|MB_OK);
return;
}
file://使Excel可見
Ex.OlePropertySet("Visible",true);
file://打開Excel表格文件Table.xls
Ex.OlePropertyGet("WorkBooks").OleProcedure("Open",ExcelFileName.c_str());
}
catch(...)
{
Application->MessageBox("操作Excel表格錯誤!","錯誤",MB_ICONSTOP|MB_OK);
Ex.OleFunction("Quit");
}
}
       以上關於C  BuilderExcel表格的操作僅作為個人觀點和水平呈獻給關心此問題的讀者,如果有更好的方式方法,敬請指教,不勝感激。
聯盟----Visita網站http://www.vista.org.tw ---[ 發問前請先找找舊文章 ]---
erosme
初階會員


發表:5
回覆:44
積分:29
註冊:2002-12-23

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-04-26 18:14:09 IP:218.166.xxx.xxx 未訂閱
Dear axsoft,    很謝謝你熱心回覆, 但我想用OLE 取得 Excel Files 內的 Sheet Count, SheetName, Row Count,Col Count 等參數.
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-04-26 18:53:28 IP:61.221.xxx.xxx 未訂閱
引言: 但我想用OLE 取得 Excel Files 內的 Sheet Count, SheetName, Row Count,Col Count 等參數.
基本上 Rows.Count 和 Columns.Count 都是固定的大小, 因為 excel 先天上的格式就是如此, Rows.Count 會是 65536, Columns.Count 會是 256, 這個值是固定的. 若是要取得 sheetcount 的話, 可以使用: Ex.OlePropertyGet("WorkBooks").OlePropertyGet("WorkSheets").OlePropertyGet("Count"); 就可以得到內共有多少工作頁, 若要取得 sheet name 的話, 可以使用: Ex.OlePropertyGet("WorkBooks").OlePropertyGet("WorkSheets[1]").OlePropertyGet("Name"); 即可!
erosme
初階會員


發表:5
回覆:44
積分:29
註冊:2002-12-23

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-05-03 22:22:04 IP:218.166.xxx.xxx 未訂閱
Dear axsoft,    感謝你的幫助, Sheet Count, SheetName,我已取得成功. 對我來說要改成如下才可使用. FExcel = CreateOleObject("Excel.Application"); FExcel.OlePropertyGet("WorkBooks").OleProcedure("Open","t.xls"); FWorkBooks=FExcel.OlePropertyGet("ActiveWorkBook"); sheetConut = FWorkBooks.OlePropertyGet("WorkSheets").OlePropertyGet("Count"); 另外你說Rows.Count 和 Columns.Count 都是固定的大小 , 那麼你是否知道 ADO 為何可以取得Rows.Count 和 Columns.Count , 其OLE 是否有類似的參數可用. 我之前是用 ADOTable1->RecordCount 及 ADOTable1->FieldCount , 來取得資料筆數的大約值.
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-05-21 00:17:14 IP:61.221.xxx.xxx 未訂閱
弟有一個想法. 就是利用函數計算的方式. 試著使用 =COUNTIF($1:$1,"<>") 及 =COUNTIF($A:$A,"<>") 但是又只能用     -------------VBA MACRO-----------     Range("A2").Select     ActiveCell.FormulaR1C1 = "=COUNT(R1,""<>"")" -------------VBA MACRO-----------    這種語法. 那可不可以自行 evaluate 出來這個 =COUNT($A:$A,"<>") 呢, 我想這是一個高階語言的環境應該是可以實現的, 所以找了又找, 花了1個多小時, 終於給我找出來了, 在巨集中可以使用:      MsgBox Excel.Worksheets(1).Evaluate("=COUNT($1:$1,"<>")")    哇. 這樣就不得了了, 好一個高階的語法, 可以自行計算出欄不是空白和列不是空白的個數了嗎, 稍微寫了一下程式, 發現真不錯用呢. 請試試看:    
procedure TForm1.Button1Click(Sender: TObject);
var
  rows, columns : Integer;
  FExcel : variant;
begin      try
    FExcel := CreateOLEObject( 'Excel.Application' );
    FExcel.WorkBooks.Open('c:\b.xls');
  except
    raise Exception.Create('無法啟動excel');
    exit;
  end;
  //FExcel.visible := True;
  columns := StrToInt(VarToStr(FExcel.WorkBooks[1].WorkSheets[1].Evaluate('=COUNTIF($1:$1,"<>")')));
  rows    := StrToInt(VarToStr(FExcel.WorkBooks[1].WorkSheets[1].Evaluate('=COUNTIF($A:$A,"<>")')));
  FExcel.Quit;
  FExcel := UnAssigned;
  showmessage('columns=' inttostr(columns) ',  rows=' inttostr(rows));
end;
重點在於可以利用 worksheet 的 evaluate function 來進行公式的計算哦~
erosme
初階會員


發表:5
回覆:44
積分:29
註冊:2002-12-23

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-05-22 21:47:06 IP:218.166.xxx.xxx 未訂閱
Dear timhuang, 若是用 BCB 則應該如何寫. 感謝你的幫忙.
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-05-22 23:27:30 IP:61.221.xxx.xxx 未訂閱
若是用 BCB 則應該這樣寫..    
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  int rows, columns;
  Variant FExcel, FWorkBooks;
  try
  {
    FExcel = Comobj::CreateOleObject("Excel.Application");
    FExcel.OlePropertyGet("WorkBooks").OleFunction("open","C:\\b.xls");
    columns = StrToInt(VarToStr(FExcel.OlePropertyGet("WorkBooks",1).OlePropertyGet("WorkSheets",1).OleFunction("Evaluate", "=COUNTIF($1:$1,\"<>\")")));
    rows    = StrToInt(VarToStr(FExcel.OlePropertyGet("WorkBooks",1).OlePropertyGet("WorkSheets",1).OleFunction("Evaluate", "=COUNTIF($A:$A,\"<>\")")));
  }
  catch ( ... )
  {
    ShowMessage("Error Operation Excel");
  }
    FExcel.OleProcedure("Quit");
    FExcel = Unassigned;
    ShowMessage("columns=" IntToStr(columns) ",  rows=" IntToStr(rows));
}
erosme
初階會員


發表:5
回覆:44
積分:29
註冊:2002-12-23

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-05-25 12:30:43 IP:218.166.xxx.xxx 未訂閱
Dear timhuang, 謝謝你的幫忙.該段程式可以用. 不過有個小麻煩,就是若想要確實知道 Rows.Count 和 Columns.Count ; 則必須對該 Excel File 作 Row & Col 掃描 ,取出最大值. 且空白位置會被忽略不記,則在取出資料時必須特別注意. 不知是否有更好用的參數. Thanks.
系統時間:2024-03-29 2:19:11
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!