本例用到:數組
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 }
先窗體上放置 ClientDataSet一、DataSource一、DBGrid一、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,v9: 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[fName]; { FieldValues 是默認的數組屬性 } v6 := ClientDataSet1.FieldList[0].Value; v7 := ClientDataSet1.FieldList.FieldByName(fName).Value; v8 := ClientDataSet1.FieldList.Find(fName).Value; v9 := 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;