2012-04-24 7 views
0

私はEmbarcadero Delphi 2010を使用しています。現在、そのファイル内にflib.mdbという名前のAccessデータベースファイルを使用しています。MCategoryという名前のテーブルを作成します。codecategoryというテキストと主キーの列はparentcategoryテキストとしてcategoryをテキスト、notesをテキストとして使用します。delphi 2010で親カテゴリを表示するには?

データベース接続の場合、私はADOConnectionを使用します。クエリのために私はADOQueryを使用します。テーブルの場合、私はADOTableを使います。

コードは接頭辞付きで自動的に生成されますが、例では通常の数字を文字列として使用しています。

一つだけROOTあり:codecategory="0" // parentcategory="" // category="ROOT"別ROOT(空parentcategoryとの1)を追加することはできません

は、私の質問は以下の画像のようparentcategoryのすべてをremaskingする方法ですか?そしてそれをDBGridで見る方法は?

parent category masking

私は、再帰的な使用する必要がありますか?これを行う簡単な方法はありますか?

デルファイ2010年の

し、またソースコード.... ^^

+0

使用ヌル値をインターフェース部に

この宣言する。 – MajidTaheri

+0

私はすべてのカテゴリをフェッチせず、パスを構築するために再帰的に反復するのではなく、サーバー側でこのジョブを実行することをお勧めします。 ['this article'](http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/)を読んでみてください。それはMySQL用ですが、必要なツリーパスを取得する方法を含め、階層型データベース構造を設計する方法についての有益な情報があります。さらに速くなると、コーデックカテゴリと親カテゴリをTEXTではなくNUMBERとして使用することになります。 – TLama

+0

うわー、残念ながら、これにはクライアント/サーバは必要ありません。アクセス/ mdbを使用する必要があります。 –

答えて

0

あなたはTStringListのにデータセットのすべてのレコードを変換し、それを並べ替えることができますしてください。実装部に

TForm1=class(...) 
    RecordList:TStringList; 
    constructor Create(AOwner:TComponent);override; 
destructor Destroy;override; 

end; 
TCategoryItem=class 
public: 
    CategoryTitle:string; 
    Id,ParentId:Variant; 
end; 

:使用のForeignKeyのルートとして

constructor TForm1.Create(AOwner: TComponent); 
begin 
    inherited ; 
    RecordList:=TstringList.create(true); // use this code in FormCreate also 


end; 
destructor TForm1.Destroy; 
    begin 
     ... 
    RecordList.Free;// use this code in FormDestory also 

    end; 

procedure TForm1.AdoQuery1AfterOpen(DataSet:TDataSet); 
var 
    Item,RootItem:TCategoryItem; 
begin 
    DataSet.First; 
    DataSet.DisableControls; 

    try 
    (*add abstract root item to RecordList if needed 
    RootItem:=TCategoryItem.Create; 
    RootItem.CategoryTitle:='ROOT'; 
    RecordList.AddObject('',RootItem);*) 
    while not DataSet.Eof do 
    begin 
     Item:=TCategoryItem.Create; 
     Item.CategoryTitle:=DataSet['Cateogory']; 
     Item.Id:=DataSet['CodeCategory']; 
     Item.ParentId:=DataSet['ParentCategory']; 
     RecordList.AddObject(VarToStr(Item.Id),Item); 
     DataSet.Next; 
    end; 
    finally 
    RecordList.Sort; // for use find(binary search) 
    DataSet.EnableControls; 
    DataSet.First; 
    end; 
end; 
procedure TForm1.OnGetFieldText(Sender: TField; var Text: string; 
    DisplayText: Boolean); 
var 
    Idx:Integer; 
    ParentValue:Variant; 
    Item:TCategoryItem; 
    Texts:TStringList; 
begin 
    ParentValue:=Sender.Value; 
    Texts:=TStringList.create; 
    try 
    while RecordList.Find(varToStr(ParentValue),Idx) do 
    begin 
     Item:=RecordList.Objects[Idx] as TCategoryItem; 
     Texts.Insert(0,Item.CategoryTitle); 
     ParentValue:=Item.ParentId; 
    end; 
    Texts.Delimiter:='>'; 
    Text:=Texts.DelimitedText; 
    finally 
    Texts.Free; 
    end; 


end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    ADOQuery1.FieldByName('parentcategory').OnGetText := OnGetFieldText; 
    ADOQuery1.Refresh; 
end; 
+1

フォームのコンストラクタとデストラクタをオーバーライドするのではなく、 'OnCreate'と' OnDestroy'イベントを使用します。また、 'TField.OnGetText'は、データセットの計算ではなく、1つのフィールドに表示するテキストを変更する場合にも使用されます。これは 'TDataset.OnCalcFields'のタスクですが、DBエンジン側でこれを行うことをお勧めします。すべてのカテゴリをフェッチせず、各フィールドに対して再帰的に反復するのではありません(大量のデータ)。 – TLama

+0

そして、言いたいことを忘れてしまった、OPはDelphi 2010を使用しています。 'TStringList'ではなく' TDictionary'です。 – TLama

+0

私はこれを最初に試してみよう^^ –

関連する問題