本例用到:
TClientDataSet.Fields[]; { 字段集合; 它比 FIEldList 有更多功能, 如可獲取嵌套字段 }
TClientDataSet.FieldList[]; { 字段列表; 它比 FIElds 輕便, 如果只是取值用它快一些 }
TClientDataSet.FIEldByName(); { 根據字段名稱獲取字段對象; 獲取一個字段對象時它比上兩個快 }
TClientDataSet.FindFIEld(); { 根據字段名稱查找字段對象 }
TClientDataSet.FIEldValues[]; { 根據字段名稱獲取字段值; 如果僅是獲取字段值, 這個最快 }
TClIEntDataSet.First; { 到第一個記錄 }
TClIEntDataSet.Next; { 到下一個記錄 }
TClIEntDataSet.Last; { 到最後一個記錄 }
TClIEntDataSet.Prior; { 到上一個記錄 }
TClIEntDataSet.RecNo; { 設置或讀取當前記錄的位置 }
TClIEntDataSet.Bof; { 當前位置是否是第一個記錄 }
TClIEntDataSet.Eof; { 當前位置是否是最後一個記錄 }
TClIEntDataSet.RecordSize; { 一個記錄的大小; 所謂一個記錄就是當前行的所有字段 }
TClIEntDataSet.RecordCount; { 記錄總數; 也就是總行數 }
TClientDataSet.GetFIEldList(); { 根據指定的幾個字段名獲取字段對象的列表 }
TClientDataSet.GetFIEldData(); { 把指定字段的值寫入一個緩沖區 }
TClIEntDataSet.GetCurrentRecord(); { 把當前記錄(不包括 Bolb 字段)寫入到一個緩沖區 }
讀取字段的結構信息可以使用 TFieldDef 對象(一般來源於 FieldDefs 或 FIEldDefList);
現在要讀取其中的數據, 應該使用 TField 對象(一般來源於 Fields 或 FIEldList).
Fields[0]、Fields[1] ... FIElds[n] 獲取的是當前行的第幾個字段, 可用 Next、RecNo 等指定當前位置(行).
下面的例子使用了 Common Files\CodeGear Shared\Data\holdings.XML, 若更換文件需調整代碼.
這是 holdings.XML 的字段信息:
ACCT_NBR { 類型是 r8, 對應 ftFloat, 相當於 Double }
SYMBOL { 類型是 string, 對應 ftString, 相當於 AnsiString; 指定 Size=7, 加上空結束, 大小是 8 }
SHARES { 類型是 r8, 對應 ftFloat, 相當於 Double }
PUR_PRICE { 類型是 r8, 對應 ftFloat, 相當於 Double }
PUR_DATE { 類型是 date, 對應 ftInteger, 相當於 Integer }
先窗體上放置 ClIEntDataSet1、DataSource1、DBGrid1、Memo1 和七個 Button, 然後:
{ 准備數據, 也可在設計時完成 }
procedure TForm1.FormCreate(Sender: TObject);
begin
ChDir(GetEnvironmentVariable('CommonProgramFiles') + '\CodeGear Shared\Data\');
ClIEntDataSet1.LoadFromFile('holdings.XML');
DBGrid1.DataSource := DataSource1;
DataSource1.DataSet := ClIEntDataSet1;
end;
{ 讀取字段值的幾種方法 }
procedure TForm1.Button1Click(Sender: TObject);
var
v1,v2,v3,v4,v5,v6,v7,v8: Variant;
num: Double;
fName: string;
begin
{ 獲取首字段的名稱 }
fName := ClientDataSet1.Fields[0].FIEldName;
{ 獲取第一個字段值的幾種方法: }
v1 := ClientDataSet1.FIElds[0].Value;
v2 := ClientDataSet1.FIEldByName(fName).Value;
v3 := ClientDataSet1.FindFIEld(fName).Value;
v4 := ClientDataSet1.FIEldValues[fName];
v5 := ClientDataSet1.FIEldList[0].Value;
v6 := ClientDataSet1.FieldList.FIEldByName(fName).Value;
v7 := ClientDataSet1.FIEldList.Find(fName).Value;
v8 := ClientDataSet1.FieldList.FIElds[0].Value;
{ 已知這個字段是 Double 類型的, 可同時轉換 }
num := ClientDataSet1.FIElds[0].AsFloat;
{ 查看結果 }
with Memo1.Lines do begin
Clear;
Add(v1); Add(v2); Add(v3); Add(v4); Add(v5); Add(v6); Add(v7); Add(v8);
Add(FloatToStr(num));
end;
end;
{ 遍歷當前行字段的幾種方法 }
procedure TForm1.Button2Click(Sender: TObject);
var
Field: TFIEld;
i: Integer;
begin
Memo1.Clear;
for Field in ClientDataSet1.FIElds do
begin
Memo1.Lines.Add(FIEld.Value);
end;
Memo1.Lines.Add('');
for i := 0 to ClientDataSet1.FIEldCount - 1 do
begin
Memo1.Lines.Add(ClientDataSet1.FIElds[i].Value);
end;
Memo1.Lines.Add('');
for i := 0 to ClientDataSet1.FIEldList.Count - 1 do
begin
Memo1.Lines.Add(ClientDataSet1.FIEldList[i].Value);
end;
Memo1.Lines.Add('');
end;
{ First、Next、Last、Prior、RecNo }
procedure TForm1.Button3Click(Sender: TObject);
var
s1,s2,s3: string;
begin
{ 讀取第二行第二個字段 }
ClIEntDataSet1.First;
ClIEntDataSet1.Next;
s1 := ClientDataSet1.FIElds[1].AsString;
{ 讀取倒數第二行第二個字段 }
ClIEntDataSet1.Last;
ClIEntDataSet1.Prior;
s2 := ClientDataSet1.FIElds[1].AsString;
{ 讀取第四行第二個字段 }
ClIEntDataSet1.RecNo := 4;
s3 := ClientDataSet1.FIElds[1].AsString;
{ 查看結果 }
with Memo1.Lines do begin
Clear;
Add('第二行第二個字段: ' + s1);
Add('倒數第二行第二個字段: ' + s2);
Add('第四行第二個字段: ' + s3);
end;
end;
{ 遍歷指定字段的所有記錄 }
procedure TForm1.Button4Click(Sender: TObject);
var
i: Integer;
begin
if not ClientDataSet1.Bof then ClIEntDataSet1.First;
Memo1.Clear;
while not ClIEntDataSet1.Eof do
begin
Memo1.Lines.Add(ClientDataSet1.FIEldList[0].Value);
ClIEntDataSet1.Next;
end;
Memo1.Lines.Add('-------');
for i := 1 to ClIEntDataSet1.RecordCount do
begin
ClIEntDataSet1.RecNo := i;
Memo1.Lines.Add(ClientDataSet1.FIEldList[1].Value);
end;
end;
{ 通過 GetFieldList 可以讀取幾個指定字段的 TFIEld 對象的列表 }
procedure TForm1.Button5Click(Sender: TObject);
var
List: TList;
Field: TFIEld;
i: Integer;
begin
List := TList.Create;
ClientDataSet1.GetFIEldList(List, 'ACCT_NBR; SYMBOL; SHARES');
Memo1.Clear;
for i := 0 to List.Count - 1 do
begin
FIEld := List[i];
Memo1.Lines.Add(FIEld.Value);
end;
List.Free;
end;
{ GetFIEldData 讀取字段值到指針 }
procedure TForm1.Button6Click(Sender: TObject);
var
F1: Double;
F2: array[0..7] of AnsiChar;
begin
ClientDataSet1.GetFieldData(ClientDataSet1.FIElds[0], @F1);
ClientDataSet1.GetFieldData(ClientDataSet1.FIElds[1], @F2);
with Memo1.Lines do begin
Clear;
Add(FloatToStr(F1));
Add(F2);
end;
end;
//這是後面的例子用到的函數, 轉換 TClIEntDataSet 時間格式到 TDateTime
function TDateTimeRecToDateTime(DataType: TFIEldType; Data: TDateTimeRec): TDateTime;
var
TimeStamp: TTimeStamp;
begin
case DataType of
ftDate:
begin
TimeStamp.Time := 0;
TimeStamp.Date := Data.Date;
end;
ftTime:
begin
TimeStamp.Time := Data.Time;
TimeStamp.Date := DateDelta;
end;
else
try
TimeStamp := MSecsToTimeStamp(Data.DateTime);
except
TimeStamp.Time := 0;
TimeStamp.Date := 0;
end;
end;
Result := TimeStampToDateTime(TimeStamp);
end;
{ GetCurrentRecord 是把當前行的所有字段(不包括 Blob 字段)讀入到緩沖區 }
procedure TForm1.Button7Click(Sender: TObject);
type
THoldingsStruct = packed record { 這是根據 holdings.XML 建立的數據結構 }
ACCT_NBR: Double;
SYMBOL: array[0..7] of AnsiChar; { 其 Size=7, 但後面還有個 #0 }
SHARES: Double;
PUR_PRICE: Double;
PUR_DATE: Integer;
// Other: array[0..4] of Byte; { 它後面還空著若干字節, 其字節數等於前面的字段數 }
end;
var
buf: THoldingsStruct;
DateTimeRec: TDateTimeRec;
begin
//ShowMessage(IntToStr(ClIEntDataSet1.RecordSize)); { 可通過這個值對照上面的結構 }
if ClIEntDataSet1.GetCurrentRecord(@buf) then with Memo1.Lines do
begin
Clear;
Add(FloatToStr(buf.ACCT_NBR));
Add(buf.SYMBOL);
Add(FloatToStr(buf.SHARES));
Add(FloatToStr(buf.PUR_PRICE));
DateTimeRec.Date := buf.PUR_DATE;
Add(DateToStr(TDateTimeRecToDateTime(ftDate, DateTimeRec)));
end;
end;