zoukankan      html  css  js  c++  java
  • [AX]AX3中使用LedgerBalanceSum计算科目余额期间发生额

    在Axapta3中计算科目余额以及期间发生额经常要用到LedgerBalanceSum开头的一些类,比如计算本位币金额用到的类LedgerBalanceSum_CurrentMST,这些类的继承关系为:

    LedgerBalance->LedgerBalanceSum->LedgerBalanceSum_Current->LedgerBalanceSum_CurrentMST。下面以LedgerBalanceSum_CurrentMST为例来分析大致的计算过程。

    LedgerBalance是一个虚类,定义一些基本的成员变量,比如fromdate、todate、debit、credit的计算等。LedgerBalanceSum从LedgerBalance扩展,定义了三个最主要的方法:

    • balance(LedgerAccount accountNum, companyId     company   = '') - 计算余额发生额的主要方法,由它返回需要计算的金额,根据传入科目的类型来分别调用SumBalance()或者SumTransact(),如果科目类型为 LedgerAccountType::sum即Total类型则调用SumBalance(),如果科目为LedgerAccountType::AccountLiable及其以下的类型(包括Liability、Assert、Balance、Cost、Revenue、Profit&Loss)则调用SubTransact()计算。
    • sumBalance(LedgerAccount accountNum, companyId     company) - 如前所说,这个函数用来计算Total类型的科目余额发生额,首先从LedgerTableInterval查找这个Total科目所包含的子科目段,再从所有科目段中取出所有子科目,对这些子科目一一调用balance()计算其余额发生额并汇总,函数的返回值为汇总额。
    • sumTransact(LedgerAccount accountNum,companyId     company) - 用于计算交易类型的科目,在LedgerBalanceSum类中是个空的虚函数。

    LedgerBalanceSum_Current从LedgerBalanceSum扩展,添加函数initPeriod()用来初始化fromdate、todate、opening、closing等成员变量;添加 q_AddDebCredCriteria(QueryBuildDataSource qB)对传入的QueryBuildDataSource增加针对LedgerTrans表的crediting字段的过滤;添加q_AddDimCriteria(QueryBuildDataSource qB)对传入的QueryBuildDataSource增加针对LedgerTrans表的dimension字段的过滤;添加 q_AddOperationsTax(QueryBuildDataSource qB)对传入的QueryBuildDataSource增加针对LedgerTrans表的operationsTax字段的过滤,实际上这三个q_开头的函数在后续的计算中并没有用到。添加空的虚函数buildQuery()用于后续扩展类构建Query。

    我们真正用来计算科目余额发生额的类是LedgerBalanceSum_CurrentMST,从LedgerBalanceSum_Current扩展,重载基类的buildQuery()和 sumTransact()两个函数:

    • void buildQuery() — 用于构建Query和QueryRun,如果包含期间opening,从LedgerBalancesDim视图创建Query q_BalanceOpening,对它添加LedgerBalancesDim字段transDate值为fromdate的过滤,添加periodCode字段值为PeriodCode::Opening的过滤,以及dimension字段的过滤,然后从q_BalanceOpening创建QueryRun保存到qR_BalanceOpening;如果还包含Regular(Normal)或者Closing的期间,则从LedgerBalancesDim视图创建Query q_BalanceRegular,对它添加LedgerBalancesDim字段transDate值为fromdate到todate的过滤,添加periodCode字段值为PeriodCode::Regular或者/以及PeriodCode::Closing的过滤,以及dimension字段的过滤,然后从q_BalanceRegular创建QueryRun保存到qR_BalanceRegular。
    • real sumTransact(LedgerAccount    accountNum, companyId        company) - 如果qR_BalanceOpening不是null,对其添加accountNum字段值为要计算的科目代码的过滤,随后对这个QueryRun循环取出ledgerBalancesDim记录,对所有ledgerBalancesDim记录调用balance()并汇总;同样如果qR_BalanceRegular不是null,对其添加accountNum字段值为要计算的科目代码的过滤,随后对这个QueryRun循环取出ledgerBalancesDim记录,对所有ledgerBalancesDim记录调用balance()并汇总。两个Query的汇总结果合并为返回值。

    有必要来看看视图LedgerBalancesDim,它是对表LedgerBalancesDimTrans根据字段AccountNum、TransDate、PeriodCode、Dimension、SystemGeneratedUltimo对DebitMST,CreditMST等字段的汇总,表LedgerBalancesDimTrans的记录是在过账LedgerTrans时自动生成或更新,目的就是建立对AccountNum、TransDate、PeriodCode、Dimension、SystemGeneratedUltimo这些字段对总账交易汇总索引,方便后续直接汇总计算,而不需要再从原始LedgerTrans汇总以加快计算速度。

    梳理一下LedgerBalanceSum_CurrentMST的计算,简单的讲,首先根据总账科目的类型,如果是Total类型的科目,则计算其下子科目的balance汇总,如果是交易类型的科目,根据是否包含opening、normal期间分别创建对LedgerBalancesDim视图相应期间类型的汇总查询相应的字段为balance。

    看一下LedgerBalanceSum_CurrentMST的构造函数,它的参数繁多:

    void new(TransDate          _fromDate,//起始日期
             TransDate          _toDate,//终止日期
             DimensionCriteria  _dimCriteria  = dimensionCriteriaDefault,//交易Dimension
             NoYes              _regular      = NoYes::Yes,//是否包含Normal期间
             NoYes              _opening      = NoYes::No,//是否包含Opening期间
             NoYes              _closing      = NoYes::Yes, //是否包含Closing期间
             OperationsTax      _operationsTax = OperationsTax::Current,//税金类型
             DebCredProposal    _debCredSpec  = DebCredProposal::None,//如何计算credit/debit,None为包含两者合计
             NoYes              _cache        = NoYes::No,//是否使用cache,后续调用balance不再重新计算,而是从cache取值
             NoYes              _sumAccounts  = NoYes::No,//没有使用
             NoYes              _closingBySystem = NoYes::No) //是否包含系统关账,影响SystemGeneratedUltimo的过滤

    如果要计算一个科目在某个日期的余额,可以这样来用:

        DimensionCriteria           dimensionCriteriaEmpty;
        LedgerBalanceSum_CurrentMST banlanceMST;
        FromDate                    fromDate=datenull();
        ToDate                      toDate=str2date('2013-1-14',321);
        ;
        banlanceMST=new LedgerBalanceSum_CurrentMST(fromDate,
            toDate,
            dimensionCriteriaEmpty,
            NoYes::Yes,
            NoYes::Yes,
            NoYes::Yes);
    
        print banlanceMST.balance('123201000000');

    如果是要计算科目在某个日期的当期余额(财务期间的开始日期到当前日期):

        DimensionCriteria           dimensionCriteriaEmpty;
        LedgerBalanceSum_CurrentMST banlanceMST;
        ToDate                      toDate=str2date('2013-1-14',321);
        FromDate                    fromDate= LedgerPeriod::findOpeningDate(todate);
        
        ;
        banlanceMST=new LedgerBalanceSum_CurrentMST(fromDate,
            toDate,
            dimensionCriteriaEmpty,
            NoYes::Yes,
            NoYes::Yes,
            NoYes::Yes);
    
        print banlanceMST.balance('123201000000');

    如果是计算科目在某段日期类的发生额:

        DimensionCriteria           dimensionCriteriaEmpty;
        LedgerBalanceSum_CurrentMST banlanceMST;
        ToDate                      toDate=str2date('2013-1-14',321);
        FromDate                    fromDate=EndMth(PrevMth(todate))+1;
        
        ;
        banlanceMST=new LedgerBalanceSum_CurrentMST(fromDate,
            toDate,
            dimensionCriteriaEmpty,
            NoYes::Yes,
            NoYes::No,
            NoYes::No);
    
        print banlanceMST.balance('123201000000');

    另一个用得比较多的balance计算类是LedgerBalanceSum_CurrentCur,也是从LedgerBalanceSum_Current扩展而来,计算的是总账交易原币金额的余额发生额,所不同的是在buildQuery中从LedgerTrans表创建Query,对LedgerTrans表的AmountMST或者AmountCUR根据TransDate、PeriodCode、CurrencyCode、AccountNum汇总查询,相应的sumTransact()从LedgerTrans汇总的结果得到Balance,其构造函数和LedgerBalanceSum_CurrentMST类似:

    void new(CurrencyCode       _currencyCode,//币种
             NoYes              _conversion, //是否转化为本位币
             TransDate          _fromDate,//起始日期
             TransDate          _toDate,//终止日期
             DimensionCriteria _dimCriteria  = dimensionCriteriaDefault,//交易Dimension
             NoYes              _regular      = NoYes::Yes,//是否包含Normal期间
             NoYes              _opening      = NoYes::No,//是否包含Opening期间
             NoYes              _closing      = NoYes::Yes, //是否包含Closing期间
             OperationsTax      _dS           = OperationsTax::Current,//税金类型
             DebCredProposal    _debCredSpec  = DebCredProposal::None,//如何计算credit/debit,None为包含两者合计
             NoYes              _cache        = NoYes::No,//是否使用cache,后续调用balance不再重新计算,而是从cache取值
             NoYes              _sumAccounts  = NoYes::No,//没有使用
             NoYes              _closingBySystem = NoYes::No) //是否包含系统关账,影响SystemGeneratedUltimo的过滤

    它的具体使用方法不再赘述。

    以上分析基于Axapta 版本3.0 SP4。

  • 相关阅读:
    BZOJ2734 [HNOI2012]集合选数
    BZOJ2288:[POJ Challenge]生日礼物
    浅谈堆
    BZOJ1150:[CTSC2007]数据备份
    POJ2442:Sequence
    POJ1442:Black Box
    POJ3784:Running Median
    洛谷【P1090】合并果子&&洛谷【P1334】瑞瑞的木板
    BZOJ1345:[Baltic2007]序列问题
    浅谈栈
  • 原文地址:https://www.cnblogs.com/duanshuiliu/p/2859249.html
Copyright © 2011-2022 走看看