https://community.embarcadero.com/index.php/blogs/entry/firedac-in-memory-dataset-tfdmemtable
ClientDataSet FieldDefs Add Field CreateDataSet 动态创建字段
FDMemTable1.Close();
FDMemTable1.FieldDefs.Clear();
FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, True);
FDMemTable1.FieldDefs.Add('Name', ftString, 20, false);
FDMemTable1.CreateDataSet();
FDMemTable1.AppendRecord([101, 'aaa']);
FDMemTable1.AppendRecord([102, 'bbb']);
FDMemTable1.AppendRecord([103, 'ccc']);
TFDMemTable *table= new TFDMemTable();
delete table;
void __fastcall TForm1::createField()
{
ClientDataSet1->Close(); ClientDataSet1->Fields->Clear();
ClientDataSet1->FieldDefs->Clear(); ClientDataSet1->Open();
ClientDataSet1->Close();
for(int i = ;i < ClientDataSet1->Fields->Count ;i++)
ClientDataSet1->Fields->Fields[]->Free();//释放所有的静态字段 for(int i = ;i < ClientDataSet1->FieldDefs->Count ;i++)
ClientDataSet1->FieldDefs->Items[i]->CreateField(ClientDataSet1); TBooleanField *NewField;
NewField = new TBooleanField(ClientDataSet1);
NewField->FieldName="SelectMe";
NewField->DisplayLabel = "选择";
NewField->FieldKind=fkInternalCalc;
NewField->DataSet=ClientDataSet1;
NewField->Index = ;
ClientDataSet1->Open();
}
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
sql = "select from TABLE1 ";
this->ADOQuery1->Close();
this->ADOQuery1->SQL->Clear();
this->ADOQuery1->SQL->Add(this->sql);
this->ADOQuery1->Open();
this->createField();
}
cds1->Close();
cds1->FieldDefs->Clear();
cds1->FieldDefs->Add("ID", ftInteger, , true);
cds1->FieldDefs->Add("Name", ftString, , false);
cds1->FieldDefs->Add("DT", ftDateTime, , false);
cds1->CreateDataSet();
cds1->AppendRecord( ARRAYOFCONST((,"aaa",Now().DateTimeString() )));
cds1->AppendRecord( ARRAYOFCONST((,"bbb",Now().DateTimeString() )));
cds1->AppendRecord( ARRAYOFCONST((,"ccc",Now().DateTimeString() )));
ClientDataSet1.Close();
ClientDataSet1.FieldDefs.Clear();
ClientDataSet1.FieldDefs.Add('ID', ftInteger, , true);
ClientDataSet1.FieldDefs.Add('Name', ftString, , false);
ClientDataSet1.FieldDefs.Add('DT', ftDateTime, , false);
ClientDataSet1.FieldDefs.Add('chk', ftBoolean, , false);
ClientDataSet1.CreateDataSet();
ClientDataSet1.Open;
ClientDataSet1.Append;
ClientDataSet1.FieldByName('id').Value := ;
ClientDataSet1.FieldByName('name').Value := 'abc';
ClientDataSet1.FieldByName('dt').Value := Now;
ClientDataSet1.Post;
ClientDataSet1.AppendRecord([,'bbb',Now()]);
ClientDataSet1.AppendRecord([,'ccc',Now()]);
CreateDataSet
FDMemTable1->Close();
FDMemTable1->FieldDefs->Clear();
FDMemTable1->FieldDefs->Add("ID", ftInteger, , true);
FDMemTable1->FieldDefs->Add("Name", ftString, , false);
FDMemTable1->FieldDefs->Add("DT", ftDateTime, , false);
FDMemTable1->CreateDataSet();
FDMemTable1->AppendRecord(ARRAYOFCONST((, "aaa", Now().DateTimeString())));
FDMemTable1->AppendRecord(ARRAYOFCONST((, "bbb", Now().DateTimeString())));
FDMemTable1->AppendRecord(ARRAYOFCONST((, "ccc", Now().DateTimeString())));
FDMemTable1->First();
AddFieldDef
with CDS2 do
begin
with FieldDefs.AddFieldDef do
begin
DataType := ftInteger;
Name := 'Field1';
end;
with FieldDefs.AddFieldDef do
begin
DataType := ftString;
Size := ;
Name := 'Field2';
end;
with IndexDefs.AddIndexDef do
begin
Fields := 'Field1';
Name := 'IntIndex';
end;
CreateDataSet;
C++也可以这样写
TVarRec row[] = {user, password, purview, "", 0};
int value_size =8;
qry->AppendRecord(row, value_size);
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TFieldDefs *pDefs = CDS2->FieldDefs;
TFieldDef *pDef = pDefs->AddFieldDef();
pDef->DataType = ftInteger;
pDef->Name = "Field1"; pDef = pDefs->AddFieldDef();
pDef->DataType = ftString;
pDef->Size = ;
pDef->Name = "Field2"; TIndexDef *pIDef = CDS2->IndexDefs->AddIndexDef();
pIDef->Fields = "Field1";
pIDef->Name = "IntIndex"; CDS2->CreateDataSet();
}
2016.8.25 FDMemTable 试验成功 ,三种创建的方式都最终成了InternalCalcField字段。
ClientDataSet1->Close(); ClientDataSet1->Fields->Clear();
ClientDataSet1->FieldDefs->Clear(); TFieldDef *fd;
fd = ClientDataSet1->FieldDefs->AddFieldDef();
fd->InternalCalcField = true;
fd->Name = "calc1";
fd->DataType = ftString;
fd->Size = ; fd = ClientDataSet1->FieldDefs->AddFieldDef();
fd->InternalCalcField = true;
fd->Name = "flag";
fd->DataType = ftBoolean; ClientDataSet1->FieldDefs->Add("ID", ftString, , false);
ClientDataSet1->FieldDefs->Add("Name", ftString, , false);
ClientDataSet1->FieldDefs->Add("DT", ftString, , false);
ClientDataSet1->FieldDefs->Add("my", ftString, , false);
ClientDataSet1->FieldDefs->Find("my")->InternalCalcField = true; for(int i = ;i < ClientDataSet1->FieldDefs->Count ;i++)
ClientDataSet1->FieldDefs->Items[i]->CreateField(ClientDataSet1); TBooleanField *NewField;
NewField = new TBooleanField(ClientDataSet1);
NewField->FieldName="SelectMe";
NewField->DisplayLabel = "选择";
NewField->FieldKind=fkInternalCalc;
NewField->DataSet=ClientDataSet1; // ClientDataSet1->CreateDataSet(); 有了上面的CreateField,此句可不要。仅此句还不能创建fkInternalCalc字段,创建变成了fkData
ClientDataSet1->Open(); for (int i = ; i < ClientDataSet1->Fields->Count; i++)
{ ClientDataSet1->Fields->Fields[i]->FieldName;
ClientDataSet1->Fields->Fields[i]->FieldKind;
}
如果dfm窗体文件定义了字段,那么不用createDataSet了,只要open就可以了。
object ds1: TFDMemTable
OnCalcFields = ds1CalcFields
FieldDefs = <>
CachedUpdates = True
IndexDefs = <>
FetchOptions.AssignedValues = [evMode]
FetchOptions.Mode = fmAll
ResourceOptions.AssignedValues = [rvSilentMode]
ResourceOptions.SilentMode = True
UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
UpdateOptions.CheckRequired = False
UpdateOptions.AutoCommitUpdates = True
StoreDefs = True
Left = 352
Top = 160
object ds1Field: TDateTimeField
FieldName = aaa
end
object ds1Field2: TStringField
FieldName = bbb
end
object ds1Field3: TStringField
FieldName = ccc
end
ds1->Close();
ds1->Open();