如何用 OLE 取得 Excel 內容. |
尚未結案
|
erosme
初階會員 ![]() ![]() 發表:5 回覆:44 積分:29 註冊:2002-12-23 發送簡訊給我 |
|
GaryKao99
中階會員 ![]() ![]() ![]() 發表:46 回覆:102 積分:54 註冊:2002-08-23 發送簡訊給我 |
|
erosme
初階會員 ![]() ![]() 發表:5 回覆:44 積分:29 註冊:2002-12-23 發送簡訊給我 |
|
tender
初階會員 ![]() ![]() 發表:23 回覆:90 積分:37 註冊:2002-09-26 發送簡訊給我 |
如果你是用
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 發送簡訊給我 |
|
axsoft
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:681 回覆:1056 積分:969 註冊:2002-03-13 發送簡訊給我 |
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 發送簡訊給我 |
|
timhuang
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
引言: 但我想用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 發送簡訊給我 |
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 發送簡訊給我 |
弟有一個想法. 就是利用函數計算的方式.
試著使用 =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 發送簡訊給我 |
|
timhuang
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:78 回覆:1815 積分:1608 註冊:2002-07-15 發送簡訊給我 |
若是用 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 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |