我正在尝试创建一个能够加载到delphi中的tcxtreelist的查询
我有这样的结构
-Season
月
我只有结构。我仍然需要知道如何构造我的查询,所以我可以将它加载到我的treelist
如果有人知道如何做到这一点,那真的很感谢你的帮助
答案 0 :(得分:1)
我不确定cxDBTreeList,这是我的第一个想法, 非常适合您的目的,因为它只适用于自引用数据集(参见 Devex在线帮助(这意味着什么)。另一方面,它非常简单, 如果有点啰嗦设置一个cxTreeList来显示你的数据。
在下面的示例中,为简单起见,我省略了结构的“周”级别 并将“季节”级别替换为“季度”(三个月)。
尝试以下示例:
创建一个新项目,并在其表单上删除名为CDS1和TcxTreelist的TClientDataSet。
此外,将TDataSource和TDBGrid拖放到表单上,并以通常的方式将它们连接到CDS,以便您可以看到您正在使用的数据。
编辑主窗体的代码,如下所示。如果你创建一个新的,这可能是最简单的
OnCalcFields
ond的CDS1
事件然后cut'n将calcfields代码粘贴到其中。
正如您在代码中看到的那样,计算字段实际上是fkInternalCalc
类型。
这样做的原因是CDS可以在它们上编制索引(与fxCalculated
字段不同
不允许这样做。)
该项目旨在尽可能独立:这就是CDS的原因 字段和cxTreeList列都是在代码中创建的,以及项目的原因 使用CDS作为数据集,以便可以在代码中创建所有数据,而不需要 外部数据库或服务器。
您会看到,Quarter
和Month
节点一旦设置完毕,就会非常简单
将各个数据行“挂起”(在while not CDS1.eof
循环中)。
Description
计算列就是为了能够显示一些信息
特定于cxTreeList中的单个数据行。显然,如果您愿意,可以使用从各个数据集字段中获取值的列。
代码:
type
TForm1 = class(TForm)
cxTreeList1: TcxTreeList;
CDS1: TClientDataSet;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
procedure FormCreate(Sender: TObject);
procedure CDS1CalcFields(DataSet: TDataSet);
private
CDS1ID: TIntegerField;
CDS1ADate: TDateTimeField;
CDS1Name: TStringField;
CDS1Month: TIntegerField;
CDS1Description: TStringField;
CDS1Quarter: TIntegerField;
colQuarter : TcxTreeListColumn;
colMonth: TcxTreeListColumn;
colDataRow: TcxTreeListColumn;
protected
public
QuarterNodes : array[1..4] of TcxTreeListNode;
MonthNodes : array[1..12] of TcxTreeListNode;
end;
[...]
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
Quarter,
Month : Integer;
NewNode : TcxTreeListNode;
begin
// First, create the dataset's fields
CDS1ID := TIntegerField.Create(Self);
CDS1ID.FieldName := 'ID';
CDS1ID.DataSet := CDS1;
CDS1Name := TStringField.Create(Self);
CDS1Name.Size := 20;
CDS1Name.FieldName := 'Name';
CDS1Name.DataSet := CDS1;
CDS1ADate := TDateTimeField.Create(Self);
CDS1ADate.FieldName := 'Date';
CDS1ADate.DataSet := CDS1;
CDS1Quarter := TIntegerField.Create(Self);
CDS1Quarter.FieldName := 'Quarter';
CDS1Quarter.FieldKind := fkInternalCalc;
CDS1Quarter.DataSet := CDS1;
CDS1Month := TIntegerField.Create(Self);
CDS1Month.FieldName := 'Month';
CDS1Month.FieldKind := fkInternalCalc;
CDS1Month.DataSet := CDS1;
CDS1Description := TStringField.Create(Self);
CDS1Description.Size := 80;
CDS1Description.FieldName := 'Description';
CDS1Description.FieldKind := fkInternalCalc;
CDS1Description.DataSet := CDS1;
// Next create the dataset's index and data rows
CDS1.CreateDataSet;
CDS1.IndexFieldNames := 'Quarter;Month;ID';
for i := 1 to 20 do begin
CDS1.Insert;
CDS1ID.AsInteger := i;
CDS1Name.AsString := 'Row' + IntToStr(i);
CDS1ADate.AsDateTime := Now - 365 + random(366); // This sets the ADate field
// to a date in the past year
CDS1.Post;
end;
try
// Next set up the cxTreeList's columns
cxTreeList1.BeginUpdate;
colQuarter := cxTreeList1.CreateColumn(Nil);
colQuarter.Caption.Text := 'Quarter';
colMonth := cxTreeList1.CreateColumn(Nil);
colMonth.Caption.Text := 'Month';
colDataRow := cxTreeList1.CreateColumn(Nil);
colDataRow.Caption.Text := 'DataRow';
colDataRow.Width := 300;
// Set up the top level (Quarter) and next level (Month) nodes
for Quarter := 1 to 4 do begin
QuarterNodes[Quarter] := cxTreeList1.Root.AddChild;
QuarterNodes[Quarter].Values[0] := Quarter;
for Month := 1 to 3 do begin
MonthNodes[(Quarter - 1) * 3 + Month] := QuarterNodes[Quarter].AddChild;
MonthNodes[(Quarter - 1) * 3 + Month].Values[0] := QuarterNodes[Quarter].Values[0];
MonthNodes[(Quarter - 1) * 3 + Month].Values[1] := (Quarter - 1) * 3 + Month;
end;
end;
// Next, create individual nodes for the Data rows and add them as children
// of the relevant month
CDS1.DisableControls;
try
CDS1.First;
while not CDS1.Eof do begin
Month := CDS1Month.AsInteger;
NewNode := MonthNodes[Month].AddChild;
NewNode.Values[0] := MonthNodes[Month].Values[0];
NewNode.Values[1] := MonthNodes[Month].Values[1];
NewNode.Values[2] := CDS1Description.AsString;
CDS1.Next;
end;
finally
CDS1.First;
CDS1.EnableControls;
end;
finally
cxTreeList1.FullExpand;
cxTreeList1.EndUpdate;
end;
end;
procedure TForm1.CDS1CalcFields(DataSet: TDataSet);
var
AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word;
ADayNumber,
AWeekNumber : Word;
ADate : TDateTime;
S : String;
begin
ADate := CDS1ADate.AsDateTime;
DecodeDateTime(ADate, AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond);
CDS1Quarter.AsInteger := 1 + AMonth div 4;
CDS1Month.AsInteger := AMonth;
CDS1Description.AsString := Format('ID: %d, Name: %s, Date: %s', [CDS1ID.AsInteger, CDS1Name.AsString, CDS1ADate.AsString]);
end;