简而言之,就是将二个表分组统计后,显示在一个grid中,为了简单起见,这里做简单的描述,两张表,一张是合同明细,一张是出货记录表,对应每一个合同明细的记录,出货表可能有一条或多条记录,要求是显示当前已出货的总数和产品的一些细节(这些细节是在合同明细表中的). 这个任务如果用sql 来表达的话,很简单
select contractLine.productId,contractLine.productName,sum(deliveryLog.quantity) from deliveryLog inner join contractLine on deliveryLog.contractId=contractLine.contractId and deliveryLog.sequence=contractLine.sequence group by contractLine.productId,contractLine.productName
在ax中实现,着实走了些弯路,主要还是缺少经验,感谢 Farseer的帮助
1.通过视图
创建一个视图,这个途径我考虑过,但我错误的以为视图无法分组(其实现在想起来就是视图无法分组,也可以在form中操作对应的query对象进行分组)
通过Farseer 的指点,很简单,设置字段 的aggregate 属性即可,晕
缺点,排序无法控制,需要在form 中操作query对象进行排序控制,不能使用outer join
2. 针对表变量进行一个sql 查询
这个问题我也考虑过,不知道怎么回事,自己尝试写测试代码时没达到要求,当前,现在是没问题了
首先将deliveryLog和contractLine加入到form datasources中,然后在deliveryLog init事件中写入以下sql (需要把这两个datasource的autoquery设置为no,否则系统会自动构造query进行查询,同时,因为第二datasource并不需要单独发起查询,所以autoSearch也设为no)
select nofetch sum(quantity) from deliverylog join productId,productName from contractLine group by productId,productName where deliveryLog.contractId=contractLine.contractId && deliveryLog.sequence==contractline.sequence
注意两个表中group by都要写上,现在向来失败的原因可能是group by 写的不太对,这里需要个表中需要分组的字段均要提供,否则可能得到不你想要的结果
你可以参见farseer的blog http://www.cnblogs.com/Farseer1215/archive/2006/12/29/607123.html ,里面有对这个用法描述.我个人的理解是table 变量其内部可能是一个类似ado recordset这样的流标引擎. 这样就解释了while/next之类的语句,虽然从外表来看table变量好像只是某一行的数据, 但它可能极有可能保留着数据库连接和上一次查询语句.所以在上一次查询的语句会在下次执行查询(如果没有对table变量进行设置新查询语句的话)
优点: 可以通过调整group by中的字段设置排序顺序和asc/dec ,缺点,由于没有query对象,无法利用ax的内置高级查询/排序机制
3. 手动设置query对象(这个方案最完美)
在datsources 加入deliverylog和contractLine, 将deliverylog的joinsource 设置为contractLine,将joinMode设置为outerjoin,将contractLine的autosearch设置为No(它不需要发起查询)
覆盖form的init,加入代码
public void init()
{
QueryBuildDataSource ds1;
QueryBuildDataSource ds2;
super();
ds1=contractLine_ds.query().dataSourceNo(1);
ds2=deliveryLog_ds.query().dataSourceTable(tableNum(DelieryLog)); //由于deliveryLog ds join到contractLine,所以该ds下面有两个 datasource,特别的用tableNum来取出想要的
ds2.orderMode(OrderMode::GroupBy);
ds1.orderMode(OrderMode::GroupBy);
ds1.addSortField(fieldnum(ContractLine,productId));
ds1.addSortField(fieldnum(ContractLine,productName));
// ds1.addSelectionField(fieldnum(ContractLine,productId),SelectionField::Database);
// ds1.addSelectionField(fieldnum(ContractLine,productName),SelectionField::Database); 不需要分组的字段会字段输出
ds2.addSelectionField(fieldNum(deliveryLog,quantity),SelectionField::Sum);
//将contractLine的productId,productName,delierylog的 quantity拖放到grid即可
}