TClientDataSet[5]: 讀取數據

本例用到:數組


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;
相關文章
相關標籤/搜索