2017-06-23 33 views
1

我試圖在運行時在TFDMemTable中創建一個新字段,該字段必須是Combobox,我想查找Combobox中的項目第二個TFDMemTable
我該如何做到這一點?
這是我需要的樣本,我有一個主表和一個輔助表,我試圖在主表中有一個輔助表中的項目。
我試圖做這樣的事情:如何在運行時在TFdMemTable中創建查找字段

//First i try creating the second table with the values for the combobox 
FDMemTableQualityLiterals.FieldDefs.Add('QualityID', ftInteger, 0, false); 
FDMemTableQualityLiterals.FieldDefs.Add('IdValue', ftString, 20, false); 
FDMemTableQualityLiterals.CreateDataSet; 

FDMemTableQualityLiterals.Open; 
FDMemTableQualityLiterals.AppendRecord([1, '480p']); 
FDMemTableQualityLiterals.AppendRecord([2, '720p']); 
FDMemTableQualityLiterals.AppendRecord([3, '1080p']); 


// then i try to create the main table with a few field including the qualityID field 
FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false); 
FDMemTable1.FieldDefs.Add('Name', ftString, 30, false); 
FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false); 
FDMemTable1.CreateDataSet; 
FDMemTable1.Close; 
//i try to link/create a new field like qualityID that has literal values instead of an id 
CreateLookupField(TDataset(FDMemTable1), 'QualityLookup', TDataset(FDMemTableQualityLiterals), 'QualityID', 'QualityID', 'IdValue'); 
FDMemTable1.CreateDataSet; 

FDMemTable1.open; 
FDMemTable1.AppendRecord([0, 'item1', 1]); 
FDMemTable1.AppendRecord([1, 'item2', 2]); 
FDMemTable1.AppendRecord([2, 'item3', 3]); 
// i use this code to show the result in devExpress 
cxGrid1DBTableView1.DataController.DataSource := DataSource1; 
cxGrid1DBTableView1.DataController.CreateAllItems(); 


Procedure TForm1.CreateLookupField(ATable: TDataSet; AFieldName: String; ALookupDataset: TDataset; AKeyfields: String; ALookupKeyfields: String; ALookupResultField : String); 
Var 
    I : Integer; 
    NewField : TField; 
Begin 
    with ATable do begin 
    if FieldDefs.Updated = False then 
     FieldDefs.Update; 
    If FindField(AFieldName) = Nil then 
    begin 
     NewField := TStringField.Create(ATable); 
     NewField.FieldName := AFieldName; 
     NewField.KeyFields := AKeyFields; 
     NewFIeld.LookupDataSet := ALookupDataset; 
     NewField.LookupKeyFields := ALookupKeyFields; 
     NewField.LookupResultField := ALookupResultField; 
     NewField.FieldKind := fkLookup; 
     NewField.Dataset := ATable; 
    end; 
    end; 
End; 

但它不工作,我得到一個錯誤說的qualityID不存在,即使我們排除錯誤,就是這種做法是否正確?這是如何做到這一點?

+0

確切地說哪一行會出現'QualityID'不存在的錯誤? – MartynA

+0

@MartynA它發生在我調用'FDMemTable.createDatSet;''createLookupField'後面' –

+0

@aliahmadi時,請參閱我編輯的答案 –

回答

3

TFieldDefs是字段定義列表而不是字段列表,CreateDataSet方法從TFieldDefs創建字段列表,但是當您關閉數據集時,字段列表將被清除。

要創建LoockUp字段,必須關閉數據集,並且封閉數據集具有空字段列表,但在創建查找字段時需要字段!因此,您應該爲封閉的數據集手動創建您的字段列表,請執行如下操作:

var 
I : Integer; 
begin 
    FDMemTable1.FieldDefs.Add('ID', ftInteger, 0, false); 
    FDMemTable1.FieldDefs.Add('name', ftString, 30, false); 
    FDMemTable1.FieldDefs.Add('QualityID', ftInteger, 0, false); 

    FDMemTable1.CreateDataSet; //This is unnecessary 
    FDMemTable1.Close; 

    for I := 0 to FDMemTable1.FieldDefs.Count - 1 do 
    begin 
    if FDMemTable1.FindField(FDMemTable1.FieldDefs[i].Name) = Nil then 
    FDMemTable1.FieldDefs.Items[i].CreateField(FDMemTable1); 
    end; 

    CreateLookupField(TDataset(FDMemTable1), 'QualityLookup', TDataset(FDMemTableQualityLiterals), 'QualityID', 'QualityID', 'IdValue'); 
    FDMemTable1.CreateDataSet; 



    //FDMemTable1.open; //not need to `FDMemTable1.open` after `FDMemTable1.CreateDataSet`, `CreateDataSet` method sets Active = True 
    FDMemTable1.AppendRecord([0, 'Ali', 1]); 
    FDMemTable1.AppendRecord([1, 'Ali2', 2]); 
    FDMemTable1.AppendRecord([2, 'Ali3', 3]); 
    //FDMemTable1.AppendRecord([1, 'Ali', 1, 1]); 
    //FDMemTable1.AppendRecord([1, 'Ali']); 
    //FDMemTable1.Close; 

// FDMemTable1.CreateDataSet; 
// cxGrid1DBTableView1.DataController.DataSource := DataSource1; 

    //FDMemTable1.Active := true; 
// cxGrid1DBTableView1.DataController.CreateAllItems(); 
end; 
+0

沒辦法。您只需添加字段定義並創建數據集(爲您創建字段)。 – Victoria

+1

@KenWhite他正在創建持久字段,這是創建查找字段所必需的。 –

+0

@Victoria關閉數據集時,字段列表將被清除,請參閱編輯答案 –