欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Delphi與Excel的親密接觸--Lark工作室


  Delphi作為一個(gè)出色的RAD,強大的數據庫功能是其最重要的特色之一,但是操縱困難的QuickReport控件常常不能滿(mǎn)足數據庫報表的需要。如果你的報表非常復雜,或者要求靈活地改變格式,那么使用Excel作為報表服務(wù)器是一個(gè)不錯的選擇。Delphi從版本5開(kāi)始提供的Excel組件極大地簡(jiǎn)化了OLE自動(dòng)化技術(shù)的應用。不過(guò)缺漏多多的幫助文件一直是Delphi最令人詬病的地方,這些新組件也不例外,本文試圖對此作一較詳細地介紹。
Excel的對象模型是一個(gè)樹(shù)狀的層次結構,根是應用程序本身,工作簿W(wǎng)orkBook是根對象的屬性對象,本文主要討論的用于數據交換的WorkSheet則是工作簿的屬性對象,詳情參閱MSOffice提供的Excel VBA幫助文件。在Delphi中控制Excel首先要與服務(wù)器程序建立連接,打開(kāi)工作簿,然后與目標工作表交換數據,最后斷開(kāi)連接。

打開(kāi)Excel工作簿
  我們的例子從一個(gè)帶有TStringGrid(當然要填上一些數據)和兩個(gè)按鈕的主窗體開(kāi)始,從控制面板的Servers頁(yè)簽中拖一個(gè)TExcelApplication控件放到窗體上。首先把ConnectKind設為ckRunningOrNew,表示如果能夠檢測到運行的Excel實(shí)例則與其建立聯(lián)系,否則啟動(dòng)Excel。另外,如果希望程序一運行即與服務(wù)器程序建立聯(lián)系,可以把AutoConnect屬性設為T(mén)rue。
與Excel建立聯(lián)系只要一條語(yǔ)句就可以了:
Excel . Connect;
也許你已經(jīng)注意到Servers頁(yè)簽上還有其他幾個(gè)Excel控件,這些控件通過(guò)ConnectTo方法可以與前面的Excel聯(lián)系在一起:
ExcelWorkbook1.ConnectTo(Excel . ActiveWorkbook);
ExcelWorksheet1.ConnectTo(Excel . ActiveSheet as _Worksheet);
ExcelWorksheet2.ConnectTo(Excel . Worksheets.Item[‘Sheet2‘] as _Worksheet);
要注意,使用ConnectTo方法前必須先打開(kāi)相應的工作簿或工作表,另外這些控件在多數情況下并不會(huì )帶來(lái)額外的便利,因此最好只使用一個(gè)TExcelApplication。
一旦與Excel服務(wù)器建立聯(lián)系,就可以創(chuàng )建新的工作簿:
var
wkBook : _WorkBook;
LCID : Integer;
...
LCID := GetUserDefaultLCID();
wkBook := Excel.Workbooks.Add(EmptyParam, LCID);
Add函數的第一個(gè)參數用于定義新建工作簿所使用的模板,可以使用xlWBATChart、xlWBATExcel4IntlMacroSheet、 xlWBATExcel4MacroSheet或者xlWBATWorksheet常量,也可以是已有的xls文件名。這里的EmptyParam是Variants單元與定義的變量,表示使用默認的通用模板創(chuàng )建新工作簿。
如果打開(kāi)已有的xls文檔,則應把要打開(kāi)的文件名作為第一個(gè)參數傳遞給Open函數:
wkBook:=Excel.WorkBooks.Open(edtDesFile.text,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,LCID);
要知道,所有的數據操作主要是針對活動(dòng)工作表而言的,下面的語(yǔ)句使用一個(gè)_WorkSheet變量代表當前的活動(dòng)單元格。如果知道工作表的名稱(chēng),其中的索引號可以用工作表名代替:
wkSheet:=wkBook.Sheets[1] as _WorkSheet;
完成數據交換后需要保存工作簿:
Excel.ActiveWorkBook.SaveAs (‘MyOutput‘, EmptyParam,EmptyParam,
EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, LCID);
或者:
Excel.ActiveWorkBook.Save(LCID);
最后要關(guān)閉工作簿并斷開(kāi)與Excel的連接:
wkBook.Close(True, SaveAsName, EmptyParam, LCID);
//Excel.Quit;
Excel.Disconnect;
這里的Close方法包含有保存的功能,第一個(gè)參數說(shuō)明在關(guān)閉工作簿之前是否保存所做的修改,第二個(gè)參數給出要保存的文件名,第三個(gè)參數用于多位作者處理文檔的情況。第二行要求終止Excel的運行。

與工作表交換數據
  輸入數據是對活動(dòng)工作表的某個(gè)單元格或區域進(jìn)行的,Range與cells都是工作表的對象屬性。Cells是單元格的集合,如果沒(méi)有指定具體位置可以代表整個(gè)工作表的所有單元格,但一般使用它是為了引用某個(gè)具體的單元格,比如WS.Cells.Item[1,1]就表示最左上角的單元格A1,注意在VBA中Item是Cells的默認屬性可以省略,但在Delphi中就沒(méi)有這種便利了。為單元格賦值要引用其Value屬性,不言而喻,該屬性是一個(gè)Variant變量,例如:
wkSheet.Cells.Item[1, 1].Value := ‘通訊錄‘;
當然你也可以為單元格指定公式:
var
AFormula:String;
……
AFormula:=‘=Rand()‘;
wkSheet.Range[‘F3‘,‘G6‘].Value:=AFormula;
上面的方法非常直接簡(jiǎn)單,但是速度非常慢,不適合作大型報表。那么能不能把所有的數據依次傳遞給Excel呢?我們可以使用Range,這個(gè)對象代表工作表中的一個(gè)區域,象我們用鼠標拖出的那樣,一般是一個(gè)矩形區域,只要給定其左上角和右下角單元格的位置就可以了,如Range[‘C3‘,‘J42‘]。
這里還有一個(gè)小問(wèn)題,因為如果數據超出26列(比如有100列)或者需要在運行中確定目標區域范圍的話(huà),使用字符名稱(chēng)標記單元格就比較麻煩?;叵胍幌?,既然"C3"是單元格的標記,那么我們當然也可以使用Cells,比如Range[Cells.Item[1,1], Cells.Item[100,100]]。
可以想象,Range的值應該是數組,但是絕對不能用Delphi中的Array給它賦值!要記住,在Delphi中,Excel對象的值總是Variant類(lèi)型的。
var
Datas : Variant;
Ir, ic: Integer;
……
Datas:= varArrayCreate([1,ir,1,ic],varVariant); //這里創(chuàng )建100*100的動(dòng)態(tài)數組
…… //這里為數組元素賦值
with wkSheet do
Range[cells.Item[3,1],cells.Item[ir+2,ic]].Value:=Datas;
要注意,工作表與Range都有Cells屬性,為了明確起見(jiàn),這里使用了with語(yǔ)句。此外,Range是有方向性的,用VarArrayCreate建立的一維數組只能賦給單行的Range,如果要為單列的Range定義值,必須使用二維數組,比如:
Datas:=VarArrayCreate([1,100,1,1], varVariant);//創(chuàng )建100*1的動(dòng)態(tài)數組。
順便提一下,Cells.Item[]實(shí)際上返回的也是Range對象。
從工作表中取回數據基本上是寫(xiě)數據的逆過(guò)程,稍微需要注意的是如何確定工作表的數據范圍:
var
ir, ic : Integer;
……
wkSheet.Cells.SpecialCells(xlCellTypeLastCell,EmptyParam).Activate;
ir := Excel.ActiveCell.Row;
ic := Excel.ActiveCell.Column;
這里巧妙地利用特殊單元格函數SpecialCells取得包含數據的最后一個(gè)單元格。

數據編輯
下面是數據編輯的兩個(gè)例子。
var
DestRange: OleVariant;
begin
DestRange := Excel.Range[‘C1‘, ‘D4‘];
Excel.Range[‘A1‘, ‘B4‘].Copy(DestRange);
上面的例子復制了8個(gè)單元格的內容。如果給Copy函數傳遞一個(gè)空參數,則該區域的數據被復制到剪貼板,以后可以用Paste方法粘貼到別的位置。
var
WS: _Worksheet;
……
Excel.Range[‘A1‘, ‘B4‘].Copy(EmptyParam); //在一個(gè)工作表中復制數據到剪貼板
WS := Excel.Activesheet as _Worksheet; //改變活動(dòng)工作表
WS.Range[‘C1‘, ‘D4‘].Select;
WS.Paste(EmptyParam, EmptyParam, lcid); //把剪貼板中的內容粘貼到新的工作表中

格式設置
選擇Excel作為報表服務(wù)器主要是因為它強大的格式化能力。我們首先把標題"通訊錄"進(jìn)行單元格合并,居中顯示,然后修改字體為18磅的"隸書(shū)",粗體:
with wkSheet.Range[‘A1‘,‘D1‘],Font do
begin
Merge(True); //合并單元格
HorizontalAlignment:= xlCenter;
Size:=18;
Name:=‘隸書(shū)‘;
FontStyle:=Bold;
end;
如果單元格內容較長(cháng),將有部分內容無(wú)法顯示,通常的做法是雙擊選定區域右側的邊線(xiàn)是各列的寬度自動(dòng)適應內容的長(cháng)度。在Delphi中通過(guò)AutoFit方法也可實(shí)現自適應的列寬行高,需要注意的是該方法僅能用于整行整列,否則會(huì )提示OLE方法拒絕執行的錯誤:
wkSheet.Columns.EntireColumn.AutoFit;
中式報表通常需要上下封頂的表格線(xiàn),可以使用Borders集合屬性。要注意,VBA中的集合對象通常都有一個(gè)缺省的Item屬性,Delphi中是不能省略的。Weight屬性用于定義表格線(xiàn)的粗細:
with Aname.RefersToRange,Borders do
begin
HorizontalAlignment:= xlRight;
Item[xlEdgeBottom].Weight:=xlMedium;
Item[xlEdgeTop].Weight:=xlMedium;
Item[xlInsideHorizontal].Weight:=xlThin;
item[xlInsideVertical].Weight:=xlThin;
end;

頁(yè)面設置與打印
  頁(yè)面設置是通過(guò)工作表的PageSetUp對象屬性設置的。Excel VBA中預設了40余種紙張常量,需要注意的是某些打印機只支持其中的一部分紙張類(lèi)型。屬性Orientation用于控制打印的方向,常量landscape = 2表示橫向打印。布爾屬性CenterHorizontally和CenterVertically用于確定打印的內容是否在水平和垂直方向上居中。
with wkSheet.PageSetUp do
begin
PaperSize:=xlPaperA4; //Paper type A4
PrintTitleRows := ‘A1:D1‘; //Repeat this row/page
LeftMargin:=18; //0.25" Left Margin
RightMargin:=18; //0.25" will vary between printers
TopMargin:=36; //0.5"
BottomMargin:=36; //0.5"
CenterHorizontally:=True;
Orientation:=1; //橫向打?。╨andscape)=2, portrait=1
end;
打印報表可以調用工作表的PrintOut方法,VBA定義的該方法共有8個(gè)可選參數,前兩個(gè)用于規定起止頁(yè),第三格式打印的份數,不
命名區域與宏
如果報表的格式比較復雜,為特定的表格區域命名然后按名引用是一種比較好的方法。Names是WorkBook的一個(gè)集合對象屬性,它有一個(gè)的Add方法可以完成這項工作。
Var
Aname : Excel2000.Name;
……
Aname := wkBook.Names.Add(‘通訊錄‘,‘=Sheet1!$A$3:$D$7‘, EmptyParam, EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam);
其中Add函數的第一個(gè)參數是定義的名稱(chēng),第二個(gè)參數是名稱(chēng)所表示的單元格區域。要注意區域名稱(chēng)的類(lèi)型必須使用限定符,如果使用類(lèi)型庫(D4),則限定符為Excel_TLB。此外,命名的區域應使用絕對引用方式,即加上"$"符號。
一旦命名了一個(gè)區域,就可以使用這個(gè)名稱(chēng)來(lái)引用它,下面的一行代碼使通訊錄內容以粗體顯示:
AName.RefersToRange.Font.Bold:=True;
不過(guò)最令人驚喜的也許是你能夠在Delphi中動(dòng)態(tài)地修改Excel宏程序!下面的代碼為我們的工作簿創(chuàng )建了一個(gè)宏,在關(guān)閉工作簿時(shí)記錄上一次訪(fǎng)問(wèn)的時(shí)間:
var
LineNo: integer;
CM: CodeModule;
sDate:String;
begin
CM := WkBook.VBProject.VBComponents.Item(‘ThisWorkbook‘).Codemodule;
LineNo := CM.CreateEventProc(‘BeforeClose‘, ‘Workbook‘);
SDate:=‘上次訪(fǎng)問(wèn)日期:‘+DateToStr(Date());
CM.InsertLines(LineNo + 1, ‘ Range("B2").Value = "‘+sDate+‘"‘);
End;
修改宏需要在前面的uses一節加上一個(gè)單元:VBIDE2000,如果使用類(lèi)型庫則相應的單元為VBIDE_TLB。這段代碼的關(guān)鍵是CodeModule對象,遺憾的是在Excel VBA help文中找不到該對象的蹤跡,只能去檢索MSDN了。

Delphi4及以前的版本
Delphi4沒(méi)有提供TExcelApplication對象,需要引入類(lèi)型庫使用OLE自動(dòng)化技術(shù),Excel97的類(lèi)型庫是Excel8.olb。這兩種方法的主要區別在于與服務(wù)器程序建立連接的方法,下面是通過(guò)類(lèi)型庫控制Excel的程序框架:
uses Windows, ComObj, ActiveX, Excel_TLB;
var
Excel: _Application;
LCID: integer;
Unknown:IUnknown;
Result: HResult;
begin
LCID := LOCALE_USER_DEFAULT;
Result := GetActiveObject(CLASS_Application, nil, Unknown); //嘗試捕獲運行中的程序實(shí)例
if (Result = MK_E_UNAVAILABLE) then
Excel := CoApplication.Create //啟動(dòng)新的程序實(shí)例
else begin
{檢查GetActiveObject方法調用過(guò)程中的錯誤}
OleCheck(Result);
OleCheck(Unknown.QueryInterface(_Application, Excel));
end;

…… //進(jìn)行數據處理

Excel.Visible[LCID] := True;
// Excel.DisplayAlerts[LCID] := False; //顯示提示對話(huà)框
Excel.Quit;
End;
這里沒(méi)有采用通常的try…except結構,是因為例外處理機制要進(jìn)行復雜的OLE檢查,降低了except部分的執行速度。要注意,不同的Delphi版本生成的伴隨函數CoApplication和一些常量名可能不同,應查看相應的類(lèi)型庫。在調用Quit方法之前,一定要釋放程序中創(chuàng )建的所有工作簿和工作表變量,否則Excel可能駐留在內存中運行(可以按下Ctrl+Alt+Del查看)。調用GetActiveObject捕獲程序實(shí)例還有一個(gè)小問(wèn)題,如果Excel處于最小化運行狀態(tài),可能出現只顯示程序主框架而用戶(hù)區不可見(jiàn)的情況。
此外,如果不希望引入類(lèi)型庫,還可以采用滯后綁定的方法,不過(guò)速度要慢許多。下面的例子聲明了一個(gè)Variant變量來(lái)代表Excel應用程序:
var
Excel: Variant;
……
try
Excel := GetActiveOleObject(‘Excel.Application‘);
except
Excel := CreateOleObject(‘Excel.Application‘);
end;
Excel.Visible := True;
采用滯后綁定時(shí),編譯器不對調用的Excel對象方法進(jìn)行檢查,而把這些工作交給服務(wù)器程序在執行時(shí)完成,這樣VBA所設置的大量默認參數(經(jīng)常有十幾個(gè))就發(fā)揮了應有的作用,因此這種方法有一個(gè)意料不到的好處--代碼簡(jiǎn)潔:
var
WBk, WS, SheetName: OleVariant;
.…..
WBk := Excel.WorkBooks.Open(‘C:\Test.xls‘);
WS := WBk.Worksheets.Item[‘SheetName‘];
WS.Activate;
……
WBk.Close(SaveChanges := True);
Excel.Quit;
除了運行速度慢以外,如果要使用類(lèi)型庫中定義的常量,就只能自己動(dòng)手了:
const
xlWBATWorksheet = -4167;
……
XLApp.Workbooks.Add(xlWBatWorkSheet);
最后不要忘記關(guān)閉Excel之后釋放變量:
Excel := Unassigned;
以下是本文例子中所用的源代碼,在Delphi6+MSOffice2000下通過(guò)。
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OleServer, Excel2000, Grids, StdCtrls;

type
TForm1 = class(TForm)
 Button1: TButton;
 StringGrid1: TStringGrid;
 Excel: TExcelApplication;
 procedure FormActivate(Sender: TObject);
 procedure Button1Click(Sender: TObject);
private
 { Private declarations }
 
 procedure Write2Xls;
 procedure OpenExl;
 procedure CloseExl;
 procedure AddFormula;
 procedure NameSheet;
 procedure Formats;
 procedure AddMacro;
 procedure Retrieve;
 procedure Printit;
public
 { Public declarations }
end;

var
 Form1: TForm1;

implementation

{$R *.dfm}
uses
 VBIDE2000;

var
 ir,ic:Integer;
 wkSheet:_WorkSheet;
 LCID:Integer;
 wkBook:_WorkBook;
 AName:Excel2000.Name;

procedure TForm1.FormActivate(Sender: TObject);
begin
 with StringGrid1 do
 begin
  Rows[0].CommaText:=‘姓名,性別,年齡,電話(huà)‘;
  Rows[1].CommaText:=‘張三,男,25,010-33775566‘;
  Rows[2].CommaText:=‘李四,男,47,012-6574906‘;
  Rows[3].CommaText:=‘周五,女,18,061-7557381‘;
  Rows[4].CommaText:=‘孫濤,女,31,3324559‘;
 end;
end;

procedure TForm1.OpenExl;
begin
 with Excel do
 begin
  Connect;
  LCID:=GetUserDefaultLCID();
  wkBook:=WorkBooks.Add(EmptyParam,LCID);
  wkSheet:=wkBook.Sheets[1] as _WorkSheet;
 end;
end;

procedure TForm1.Write2Xls;
var
 Datas:Variant;
 i,j:Integer;
begin
 ir:=StringGrid1.RowCount;
 ic:=StringGrid1.ColCount;
 Datas:=varArrayCreate([1,ir,1,ic],varVariant);
 for i:=1 to ir do
  for j:=1 to ic do
   Datas[i,j]:=StringGrid1.Cells[j-1,i-1];

 with wkSheet do
 begin
  Activate(LCID);
  Cells.Item[1,1].Value:=‘通訊錄‘;
  Range[cells.Item[3,1],cells.Item[ir+2,ic]].Value:=Datas;
 end;
 // Excel.Visible[LCID]:=True;

 Datas:=Unassigned;
end;

procedure TForm1.Retrieve;
var
 Datas:Variant;
 i,j:Integer;
begin
 with wkSheet do
 begin
  Cells.SpecialCells(xlCellTypeLastCell,EmptyParam).Activate;
  ir:=Excel.ActiveCell.Row;
  ic:=Excel.ActiveCell.Column;
  Datas:=Range[Cells.Item[1,1],Cells.Item[ir,ic]].Value;
  with StringGrid1 do
  begin
   ColCount:=ic;
   RowCount:=ir;
   ScrollBars:=ssBoth;
   for i:=0 to ir-1 do
   for j:=0 to ic-1 do
   Cells[j,i]:=Datas[i+1,j+1];
  end;
  Datas:=UnAssigned;
 end;
end;

procedure TForm1.CloseExl;
const
 SaveAsName=‘test.xls‘;
begin
 wkBook.Close(True,SaveAsName,EmptyParam,LCID);
 Excel.Quit;
 Excel.Disconnect;
end;

procedure TForm1.NameSheet;
begin
 AName:=wkBook.Names.Add(‘通訊錄‘,‘=Sheet1!$A$3:$D$7‘,EmptyParam,EmptyParam,
 EmptyParam,EmptyParam,EmptyParam,EmptyParam,
 EmptyParam,EmptyParam,EmptyParam);
end;

procedure TForm1.AddFormula;
var
 AFormula:String;
begin
 AFormula:=‘=Rand()‘;
 wkSheet.Range[‘F3‘,‘G6‘].Value:=AFormula;
end;

procedure TForm1.Formats;
begin
 with wkSheet.Range[‘A1‘,‘D1‘],Font do
 begin
  Merge(True); //合并單元格
  HorizontalAlignment:= xlCenter;
  Size:=18;
  Name:=‘隸書(shū)‘;
  FontStyle:=Bold;
 end;
 wkSheet.Columns.EntireColumn.AutoFit;
 with Aname.RefersToRange,Borders do
 begin
  HorizontalAlignment:= xlRight;
  Item[xlEdgeBottom].Weight:=xlMedium;
  Item[xlEdgeTop].Weight:=xlMedium;
  Item[xlInsideHorizontal].Weight:=xlThin;
  item[xlInsideVertical].Weight:=xlThin;
 end;
end;

procedure TFOrm1.AddMacro;
var
 LineNo: integer;
 CM: CodeModule;
 sDate:String;
begin
 CM := WkBook.VBProject.VBComponents.Item(‘ThisWorkbook‘).Codemodule;
 LineNo := CM.CreateEventProc(‘BeforeClose‘, ‘Workbook‘);
 SDate:=‘上次訪(fǎng)問(wèn)日期:‘+DateToStr(Date());
 CM.InsertLines(LineNo + 1, ‘ Range("B2").Value = "‘+sDate+‘"‘);
end;

procedure TForm1.Printit;
begin
 with wkSheet.PageSetUp do
 begin
  PaperSize:=xlPaperA4; //Paper type A4
  PrintTitleRows := ‘A1:D1‘; //Repeat this row/page
  LeftMargin:=18; //0.25" Left Margin
  RightMargin:=18; //0.25" will vary between printers
  TopMargin:=36; //0.5"
  BottomMargin:=36; //0.5"
  CenterHorizontally:=True;
  Orientation:=1; //橫向打?。╨andscape)=2, portrait=1
 end;

 wkSheet.PrintOut(EmptyParam,EmptyParam,1,
 EmptyParam,EmptyParam,EmptyParam,
 EmptyParam,EmptyParam,LCID);

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 try
  OpenExl;
  Write2xls;
  AddFormula;
  NameSheet;
  Formats;
  PrintIt;
  AddMacro;
  ReTrieve;
 finally
  CloseExl;
 end;
end;

end.

 

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
基于Delphi的Excel動(dòng)態(tài)報表技術(shù)
DELPHI如何將數據導出到指定格式的EXCEL模版
在delphi中操縱excel--[心筆留香]
網(wǎng)頁(yè)里表格的數據通過(guò)delphi寫(xiě)的程序導入到數據庫中去
JSON 之 SuperObject(16): 實(shí)例
Delphi控制Excel自動(dòng)生成報表1
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久