博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Axapta]带参数的RunbaseReport最佳实践
阅读量:7168 次
发布时间:2019-06-29

本文共 4854 字,大约阅读时间需要 16 分钟。

AX中RunbaseReport类用来运行一个报表,它可以定义一些参数,在弹出对话框的时候设置这些参数,以列出工单为例,先看看不考虑从其他form点击纪录带入参数的时候如何实现这个报表。下图是所用到的几个对象:

菜单项TestProdReport指向类TestProdReport,下面是类TestProdReport的代码:

class TestProdReport extends RunbaseReport{    NoYesId     showOnlyOpen;    DialogField dfShowOnlyOpen;    #define.CurrentVersion(0)    #localmacro.CurrentList        showOnlyOpen    #endmacro}static void main(Args args){    TestProdReport prodReport = new TestProdReport();    ;    if (prodReport.prompt())        prodReport.run();}public identifiername lastValueElementName(){    return reportStr(TestProdReport);}public NoYes parmShowOnlyOpen(NoYes _showOnlyOpen = showOnlyOpen){    showOnlyOpen = _showOnlyOpen;    return showOnlyOpen;}public Object dialog(DialogRunbase dialog, boolean forceOnClient){    DialogRunbase   ret;    ;    ret = super(dialog, forceOnClient);    dfshowOnlyOpen = ret.addFieldValue(typeid(NoYesId),showOnlyOpen,"Show only open orders");    return ret;}public boolean getFromDialog(){    boolean ret;    ret = super();    showOnlyOpen = dfShowOnlyOpen.value();    return ret;}public container pack(){    return [#CurrentVersion, #CurrentList] + [super()];}public boolean unpack(container packedClass){    container       base;    boolean         ret;    Integer         version    = RunBase::getVersion(packedClass);    boolean         dummy;    switch (version)    {        case #CurrentVersion:            [version, #CurrentList, base] = packedClass;            ret = super(base);            break;        default:            ret = false;    }    return ret;}

报表TestProdReport的代码:

public class ReportRun extends ObjectRun{    TestProdReport  testProdReport;}public void init(){    ;    testProdReport = this.args().caller();    super();}public boolean send(Common _cursor, int _level=1, boolean _triggerOffBody=TRUE, boolean _newPageBeforeBody=FALSE){    boolean     ret;    ProdTable   _prodTable;    ;    if(_cursor.TableId==tablenum(ProdTable))    {        _prodTable = _cursor;        if(testProdReport.parmShowOnlyOpen() && _prodTable.ProdStatus==ProdStatus::Completed)            return true;    }    ret = super(_cursor, _level, _triggerOffBody, _newPageBeforeBody);    return ret;}

这里我们是在报表的Send函数判断工单状态根据条件过滤掉已关闭的工单,这不是最好的办法,因为Query仍会查询出所有的工单纪录,在一定程度上影响性能,更好的办法是重载fetch方法,在fetch方法中获取报表的query,在query中根据条件加入对ProdStatus的过滤条件,再由Query创建QueryRun,运行QueryRun获取ProdTable纪录Send,这里就不再演示了。

现在的问题是如果把TestProdReport菜单项添加到ProdTable form中,在ProdTable form上点击这个菜单只显示当前ProdTable纪录到报表该如何来做呢?

首先在TestProdReport类定义中添加变量来纪录form中的当前纪录:

ProdTable   prodTable;

添加parmXXX函数来传入这条ProdTable纪录:

public ProdTable parmProdTable(ProdTable _prodTable = prodTable){    ;    prodTable = _prodTable;    return prodTable;}

添加函数initFromArgs来从传入的Args初始化这条纪录:

private void initFromArgs(Args args){    ;    if ( args && args.dataset())    {        switch(args.dataset())        {            case(tablenum(ProdTable)) :                this.parmProdTable(args.record());                break;            default:         }        this.makeReportRun(); //创建ReportRun对象        this.initQueryRun();  //初始化Report的QueryRun,必须是手工调用,正常运行报表是不会调用这个函数的,它调用后面的initQuery    }}

 

 

添加initQuery函数来初始化Query,initQuery函数会被initQueryRun()调用,在这里我们根据传入的ProdTable纪录根据主键工单号ProdId来过滤:

public Query initQuery(){    QueryBuildDataSource    queryBuildDataSource;    QueryBuildRange         queryBuildRange;    Query                   query;    ;    query = super();    queryBuildDataSource = query.dataSourceTable(tablenum(ProdTable));    if (!queryBuildDataSource)        queryBuildDataSource = query.addDataSource(Tablenum(ProdTable));    queryBuildRange = queryBuildDataSource.findRange(fieldnum(ProdTable, ProdId));    if (!queryBuildRange)        queryBuildRange = queryBuildDataSource.addRange(fieldnum(ProdTable, ProdId));    if (prodTable)        queryBuildRange.value(prodTable.ProdId);//根据工单号来筛选    return query;}

最后修改main函数,调用initFromArgs来初始化就可以了:

static void main(Args args){    TestProdReport prodReport = new TestProdReport();    ;    prodReport.getLast();    prodReport.initFromArgs(args);    if (prodReport.prompt())        prodReport.run();}

注意这里在调用initFromArgs函数之前调用了一次getLast(),如果不在这里调用一次getLast(),后面的prompt()会在内部调用一次getLast(),把上一次pack的query读入,显示出来的对话框中看到的是上一次的内容,也就把initFromArgs()创建的Query的给覆盖了,所以这里先调用一次getLast(),prompt()会看到这个函数已经调用过了就不再调用了,所以这行是必须的。当前纪录的工单号相应的会出现在对话框中的过滤选项内:

 

以上就是如何在报表中根据form的当前纪录来过滤的实现办法。这里还要说一个runbaseReport的initParmDefault()函数,它是在第一次运行报表时会被调用,一旦有pack/unpack成功之后就不会在调用,在这里可以针对报表的第一次运行做一些初始化的工作,针对我们的这个报表是不需要的。

再把我们的这个例子扩展开,如果说在ProdTable form中选中了多条纪录,要在报表上打印出这多条纪录又该怎么办呢?

我们调用传入纪录的isFormDataSource()来判断是否来自于form的DataSource,如果是则使用common.Datasource()方法获得formDataSource,再使用formDatasource.getFirst(true)、formDatasource.getNext()轮询获取选中纪录的主键,然后设置到Query的Range中就可以了。基本结构是一样的,这里就不再演示了,下面的链接可以下载这个演示的project,从AXAPTA 3.0系统导出:

 

 

 

 

 

转载于:https://www.cnblogs.com/duanshuiliu/archive/2012/07/11/2586051.html

你可能感兴趣的文章
销傲中国式销售过程管理系统功能概述
查看>>
IDEA 学习笔记之 Java项目开发深入学习(1)
查看>>
重建二叉树 (剑指offer第六题)
查看>>
爬虫基础 pyquery 详解
查看>>
QT creator+OpenCV2.4.2+MinGW 在windows下开发环境配置
查看>>
Allegro PCB Design GXL (legacy) 设置十字大光标
查看>>
数据结构--图的定义和存储结构
查看>>
[C#参考]委托机制
查看>>
linux常用命令
查看>>
自然杂志上的影评
查看>>
SQL Server 存储过程
查看>>
Appium自动化测试1 - 安装部署
查看>>
广州.NET微软技术俱乐部微信群各位技术大牛的blog
查看>>
《Redis设计与实现》之第九章:数据库
查看>>
10月10日学习内容整理:socketserver模块,ftp作业讲解
查看>>
P1352 没有上司的舞会
查看>>
Bzoj 1648: [Usaco2006 Dec]Cow Picnic 奶牛野餐 深搜,bitset
查看>>
关于《淘宝技术这十年》
查看>>
c#事件机制
查看>>
冒泡排序
查看>>