我正在尝试创建一个能够加载到delphi
中的tcxtreelist的查询我有这样的结构
- 季节
月
- 周
我只有结构。我仍然需要知道如何构造我的查询,因此我可以将其加载到我的Treelist
上如果有人知道该怎么做,那真的很感谢您的帮助
我不确定我的第一个想法是真正适合您的目的,因为它仅适用于自我引用数据集(请参阅Devex在线帮助这意味着什么)。另一方面,它非常简单,如果有点长时间设置CXTreeList来显示您的数据。
在以下示例中,为简单起见,我省略了"一周"。您的结构水平并取代了"季节"按A Quarts"四分之一"(三个月)一个。
尝试以下示例:
-
创建一个新项目,并在其形式上丢弃一个名为CDS1和TCXTREELIST的TCLIENTDATASET。
另外,将tdatasource和tdbgrid放在表单上,并以通常的方式将其连接到CD,以便您可以看到您正在使用的数据。
-
编辑主表单的代码,如下所示。如果您创建一个新的,这可能是最简单的
OnCalcFields
CDS1
ond的事件,然后将Calcfields代码粘贴到其中。 -
从代码中看到,计算出的字段实际上是
fkInternalCalc
类型的。这样做的原因是可以在它们上索引CD(与fxCalculated
字段不同不允许这个)。 -
该项目的目的是尽可能独立:这就是CDS的原因字段和cxtreelist列都是在代码中创建的,以及为什么该项目使用CD作为数据集,以便可以在代码中创建所有数据,并且不需要外部数据库或服务器。
-
您会看到,一旦
Quarter
和Month
节点设置了,这很微不足道&quot hang'单个数据将它们排除(在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;