[英]Adding a new Field to FDMemTable when loading an existing data
我正在使用TFDMemTable
,我創建了一個數據集並用數據填充了我的表,然后使用FDMemTable.saveToFile
保存了我的數據。
現在這是一個問題,我如何才能向已保存的數據添加新Field
,並用默認值填充所有記錄?
我嘗試將新Field
添加到FDMemTable
,然后加載信息,希望它會自動使用它的FieldName
和每個空白字段填充新字段,但出現錯誤:`--------- ------------------
`
我怎樣才能解決這個問題 ? 是否可以為現有數據添加具有默認值的新字段?
這是一個測試用例:
// here is a simple example, i have a few fields
FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);
FDMemTable1.CreateDataSet;
// i fill the the table with some value
FDMemTable1.Open;
FDMemTable1.AppendRecord([1, 'Movie1', 1]);
FDMemTable1.AppendRecord([2, 'Movie2', 2]);
FDMemTable1.AppendRecord([3, 'Movie3', 1]);
// after seeing the value on the grid, i push a button and save the table as XML
FDMemTable1.saveToFile('Data.xml');
// now after closing the program and running it again, i want to load the data with a new FieldDef Called Episode with a default value 0
// the table is connected to cxGrid, and the moment i try to load, i get the error i mentioned.
FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
// this line is NEW
FDMemTable1.FieldDefs.Add('Episode', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);
FDMemTable1.CreateDataSet;
// i try to load but i get an error
FDMemTable1.loadFromFile('Data.xml');
更新1(基於維多利亞的答案):
//All the codes below are executed after the code at the top, after the loadFromFile.
FDMemTable1.ResourceOptions.StoreItems := FDMemTable1.ResourceOptions.StoreItems + [siMeta];
FDMemTable1.Close;
//i tried putting FDMemTable1 as the owner but when i try the line "FDMemTable1.Fields.add" i get an Duplicate error!
// and when i try putting nil, i get access violation ! so i tried putting the owner someother random table and it fixed the problem
fieldDefs := TFieldDefs.Create(someRandomFDMemTable);
fieldDefs.Add('Episodes', ftString, 30, false);
FDMemTable1.Fields.Add(fieldDefs.Items[0].CreateField(FDMemTable1));
FDMemTable1.Open;
如您所見,我有兩個問題,
1-我在添加新字段時遇到問題! 在出現錯誤的地方,我首先嘗試使用TFieldDef
而不是TFieldDefs
但是我無法使其正常工作。
2-所有列均為空並且網格上沒有數據的事實。
當我嘗試強制解決問題1時,就會出現問題2。
下面的代碼對我在Delphi Seattle中的工作正常。 它與您緊密相關,但有一些細微變化(請參閱注釋)和一項重要補充。
關鍵是,如果您仔細觀察FDMemTable1.loadFromFile
,它實際上會清除FieldDefs / Fields,那么首先要重新設置它們沒有太多的意義,因此添加的Episode
字段將被從加載中省略數據集。
為了避免這種情況,我所做的添加工作是使用臨時TFDMemTable,將XML文件加載到其中,然后使用CopyDataSet
將其內容復制到FDMemTable1。 FDMemTable1會在此過程中保留添加的Episode字段,當然,您可以添加代碼以在調用CopyDataSet
設置Episode字段數據。
procedure TForm1.AddFieldTest;
var
DataFN : String;
TempMemTable : TFDMemTable;
begin
// Added, to avoid relative path for data file name
DataFN := ExtractFilePath(Application.ExeName) + 'Data.Xml';
FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);
FDMemTable1.CreateDataSet;
// i fill the the table with some value
FDMemTable1.Open;
FDMemTable1.AppendRecord([1, 'Movie1', 1]);
FDMemTable1.AppendRecord([2, 'Movie2', 2]);
FDMemTable1.AppendRecord([3, 'Movie3', 1]);
// after seeing the value on the grid, i push a button and save the table as XML
FDMemTable1.saveToFile(DataFN);
// Added, close the dataset and clear the FieldDefs
// Without the FieldDefs.Clear call, your code produces a "Duplicate field ID" error
FDMemTable1.Close;
FDMemTable1.FieldDefs.Clear;
// now after closing the program and running it again, i want to load the data with a new FieldDef Called Episode with a default value 0
// the table is connected to cxGrid, and the moment i try to load, i get the error i mentioned.
FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('name', ftString, 30, false);
// this line is NEW
FDMemTable1.FieldDefs.Add('Episode', ftInteger, 0, false);
FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false);
FDMemTable1.CreateDataSet;
// check the FieldCount and existence of the Episode field
Caption := IntToStr(FDMemTable1.FieldCount);
Assert(FDMemTable1.FindField('Episode') <> Nil);
// Create a temporary TFDMemTable
TempMemTable := TFDMemTable.Create(Nil);
try
// load the data into the temporary TFDMemTable
TempMemTable.loadFromFile(DataFN);
// copy the data from the temporary TFDMemTable into FDMemTable1
FDMemTable1.CopyDataSet(TempMemTable, [coAppend]);
// check the FieldCount and existence of the Episode field
Caption := IntToStr(FDMemTable1.FieldCount);
Assert(FDMemTable1.FindField('Episode') <> Nil);
finally
TempMemTable.Free;
end;
end;
添加一個字段(未字段定義)加載從文件中的數據集之后(包括在假設siMeta StoreItems的財產ResourceOptions您的TFDMemTable )。 請注意,將字段添加到字段集合時必須關閉數據集。
因此,從文件加載后立即關閉數據集,添加字段並再次打開它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.