需求: 1,新增时自动带出明细数据
2,自动计算汇总节点的数据
解决:
相关图片:
注意事项:
1,此列中要用到全局缓存,所以在打开和关闭这个张据时要清理一下缓存,又因打开单据时要自动加载数据,所以要定义几个自己的子操作,再分别替换该单据所用到的New,Cancel,ViewAddNew
<BillMetaUIOpt Key="Cancel_RemoveCachedData" Caption="取消" Icon="Cancel" ShortCuts="Alt+C" ObjectCondition="TableType()="Bill"" PreCondition="Not(ReadOnly())" SubOptKeys="bCancel;EditBill-R;CancelBillChange;DoEvaluateFormula(ERAF_RemoveCachedData({CacheData}));ShowBill;UIClose" SubOptDataIdxes="0;0;0;0;1;2" NeedRowCheck="False"/>
<BillMetaUIOpt Key="ViewAddNew_RemoveCachedData_RunFieldButtonClickTrigger" Caption="新增" Icon="AddNew" ShortCuts="Alt+N" ObjectCondition="TableType()="View"" SubOptKeys="NewBill;DoEvaluateFormula(ERAF_RemoveCachedData({CacheData}));ShowBill;EditBill;RunFieldButtonClickTrigger(zidongdaichushu)" SubOptDataIdxes="0;0;1;1;1"/>
<BillMetaUIOpt Key="New_RemoveCachedData_RunFieldButtonClickTrigger" Caption="新增" Icon="AddNew" ShortCuts="Alt+N" ObjectCondition="TableType()="Bill"" PreCondition="ReadOnly()" SubOptKeys="UpdateView;NewBill;DoEvaluateFormula(ERAF_RemoveCachedData({CacheData}));ShowBill;EditBill;RunFieldButtonClickTrigger(zidongdaichushu)" SubOptDataIdxes="0;0;0;0;0;0"/>
2, TrigDtl 列一定要是无数据源列
3, 计算汇总行的原理
ERAF_SetValueInCachedData({CacheData},kemuid,Value(kemuid),jine,Value(jine)) 刷新缓存的数据
ERAF_GLInitSetParentNoShown({kemuid},ActiveRow(),False) 将缓存的数据刷新到界面
用ERAF_GLInitSetParentNoShown这个公式重新显示一下该行的数据,因为TrigDtl 是无数据源列,此时得到值,所以会触发他的Trigger,从而计算汇总行的值
配置文件下载:指标录入配置文件下载
参考文档:
1.7.6明细节点输入时自动计算汇总节点值
在有的项目中表单的明细数据是有层次关系的,比如在总帐里面的初始余额输入界面,如下图所示
在这个界面中只要输入明细科目的值,汇总科目的值会自动计算的。
又或者在预算系统里面的填报类单据中,也有类似功能,如下图所示:白色的是明细节点,淡蓝色的是汇总
节点,输入明细节点的单位填报之后,汇总的数据就自动计算出来了。在该项目中明细节点其实不是输入的,是通过后面的费用明细汇总得到的,在此我们就简单一点,就认为是通过手工输入得到的。
下面就简单讲解一下这种类型的表单在MAP平台中的配置方法。
首先需要配置这么一张单据,在单据新增时默认能把这些项目明细自动填到单据里,这些项目明细的数据可以预先在字典中设置好,如图所示:
这些数据是有层次关系的,在我们字典数据表中我们可以看到,汇总节点的NodeType=1,明细节点的NodeType=0,这个大家需要了解下,因为下面设置时需要用到NodeType。
那怎么样在单据新增时将这些数据填到单据上呢?那我们先手工加个按钮”取数”,在手工点按钮时将数据
能带出来,这一步做好了之后,再在新增的时候实现该功能。然后用FillData公式进行取数,然后批量赋值,例如:FillData(0,FirstDataRow(),xiangmu:nodetype:TLeft,{select id,nodetype,TLeft from cp_shujujihe where BillType=}&VAlue(BillTypeID)&{ order by Tleft},True)。这个里面有个Where条件,大家可以根据项目需要自己设定,或者就不要加,因为本例中是根据费用类型做多张单据的。需要注意的是:在这种类型的单据中需要加两个字段,NodeType(节点类型),TLeft(字典建树的字段),这两个字段也同样要取过来,图例中这两个字段被隐藏了。FillData公式设置好之后然后测试一下效果,新增单据后点击下取数,看一下表格中有否数据出来,如果没有出来,跟踪一下日志语句看看,是否SQL语句些错了。
上面做好之后,然后我们将该功能加入到新增按钮中,在单据新增时我们就需要把项目数据填到明细表格中。
那么我们找到原来的新增按钮的界面操作,包括序时簿的新增操作,因为序时簿上和单据都有新增操作,我们把原来的拷贝一份,就以序时簿的新增为例,本来叫 <BillMetaUIOpt Key="ViewAddNew" Caption="新增" Icon="AddNew" ShortCuts="Alt+N" ObjectCondition="TableType()="View"" SubOptKeys="NewBill;ShowBill;EditBill" SubOptDataIdxes="0;1;1"/>,那我们重新拷贝一份,改名为ViewAddNewTrig,然后对这个操作再加工一下,<BillMetaUIOpt Key="ViewAddNewTrig" Caption="新增" Icon="AddNew" ShortCuts="Alt+N" ObjectCondition="TableType()="View"" SubOptKeys="NewBill;ShowBill;EditBill;RunFieldButtonClickTrigger(Trig)" SubOptDataIdxes="0;0;1;1"/>,我主要加了个RunFieldButtonClickTrigger(Trig)这个操作,后面的参数Trig时那个按钮的Key,加这个目的就是我们在点新增按钮时,最后再触发一下那个Trig按钮。然后我们把对应序时簿中ViewAddNew替换为ViewAddNewTrig,这样新增时带出项目明细功能就实现了。
下面我们再讲下输入明细时怎么自动计算汇总节点的值。首先我们在明细表格中加个无数据源数值类字段TrigDtl,这个字段其实没有业务意义,用来作为一个桥梁,处理新增单据或者打开已经存在单据时,维护数据对象里面的值。
图上的二级金额和差异金额两个字段请大家不要关注,因为该例中,还有其他的一些复杂功能。然后我们在取TrigDtl字段中加上如下公式danweitianbao=IF(Value(xiangmu)<=0,0,ERAF_GetValueFromCachedData(danweitianbao,{CacheData},IF(GetBillNewStatus(),{select id as xiangmu,TLeft,NodeType,0 as danweitianbao from cp_shujujihe where BillType=}&VAlue(BilltYPEid),{Select xiangmu,tleft,NodeType,danweitianbao from SCM_gongyongjingfei12 where billid=}&value(ID)),IF(Value(NodeType)=0,{xiangmu=}&Value(xiangmu),{NodeType=0 and TLeft>}&GetProp(xiangmu,TLeft)& { And TLeft<} &GetProp(xiangmu,TRight)))),设置该字段的默认值公式IF(Value(xiangmu)>0,RunTriggers(TrigDtl),0),然后我们在取数按钮中再增加公式:SetData(0,FirstDataRow(),GetRowCount(0)+1,TrigDtl,1,True)。下面我们简单介绍一下这些公式的含义,大家了解之后可以在自己做的时候能知道怎么修改这些公式。Danweitianbao=IF(…这段内容主要讲ERAF_GetValueFromCachedData公式,这个公式主要是根据SQL语句构造一个数据对象的缓冲。第一个参数是字段名,第二个参数是缓冲的Key,可以随便命名,如果你要建立多个缓冲,不要重复即可,第三个参数是SQL语句,我这个地方SQL语句分两种情况,新增时是到cp_shujujihe这个字典表中取数,打开存在的单据时是到当前单据表里去取数,注意过滤条件Where BillID=}&Value(ID),我们单据中有默认的系统字段ID,是指当前单据的BillID。第4个参数是Filter过滤条件,意思就是我们怎么样到缓冲中取到我们所需要的数据,或者说怎么取定位,类似于SQL语句的Where条件一样,样例中给出的根据NodeType来判断,如果是明细节点直接找到当前记录,如果汇总节点,那需要找到这个节点的所有的子孙,这个Filter的设置大家只要参照样例即可。
我们之所以加了个TrigDtl字段来维护当前数据对象的缓冲的目的是:在新增时,通过点击取数按钮执行SetData公式,然后SetData触发了TrigDtl的字段联动,这样在新增单据时就构造出这份缓冲,只不过里面的值都是0,然后通过输入明细节点而改变缓冲中的值。然后在打开已经存在的单据时,我们也利用了TrigDtl字段,因为这个字段是无数据源字段,所以每次单据打开时都会触发一下默认值里面的公式RunTriggers(TrigDtl),通过这个就可以维护已经存在的单据数据的缓冲,这个时候可能那些单位填报的值和新增时不一样了,已经不是0了,因为这个单据里面明细数据已经修改过了。其实我在TrigDtl后面还加了公式IF(Value(NodeType)=1,SetRowBackColor(ActiveGrid(),ActiveRow(),{A0,C3,DA}),True),这个是设置行颜色的,如果是汇总行,设置为一个很明显的颜色,其实这个地方大家也可以根据自己的其他需求加一些公式,比如汇总行不可编辑,只要SetEnable一下即可。
上面都配置好了之后,需要在单位填报字段上设置一个公式,来处理,在输入明细数据的时候去改变缓冲和计算汇总的值。那我们需要设置如下两个公式: ERAF_SetValueInCachedData({CacheData},xiangmu,Value(xiangmu),danweitianbao,Value(danweitianbao))和ERAF_GLInitSetParentNoShown({xiangmu},ActiveRow(),False),先讲下ERAF_SetValueInCachedData公式,这个公式是设置缓冲数据集中的数据,就是需要改变并维护缓冲里面的数据。第一个参数是缓冲的Key,第二个参数是条件字段名,也就是项目,第三个参数是条件字段值,第4个参数是更新字段名,第5个参数是更新字段值。第3个和第4个参数可以同时更新多个字段,本例中只有一个是danweitianbao,如果有多个,需要用逗号隔开,该参数上加个引号,我们会当成字符串解析。ERAF_GLInitSetParentNoShown这个公式是用来刷新一下汇总节点的值,其实执行过ERAF_SetValueInCachedData之后,缓冲中的汇总节点的值已经对了,然后我们再用ERAF_GLInitSetParentNoShown刷新一下界面,第一个参数是具体条件字段,本例中指项目,第二个参数指当前条件字段所在行,那我们用ActiveRow()来表示,因为我们只有知道了当前行,才能找到这一行的所有祖先,第三个参数指是否将当前行设置为未显示,大家设置成默认值False即可。
通过上面的配置,基本上可以实现该功能了。其中还有几个地方需要注意一下,可能大家在配置的过程中会碰到。我们构造的缓冲是一个全局的缓冲,不光光在当前表单对象中可以访问,在其它表单对象中也可以访问,所以,有一种情况,比如我们修改了一些值后,当前缓冲其实已经改变掉了,如果我们这个时候取消保存,那么这个时候我们也是需要重置一下缓冲的,所以我们需要在如下几个地方处理一下:
新增时,我这个是序时簿新增,同样单据新增大家也要处理一下
<BillMetaUIOpt Key="ViewAddNewTrig" Caption="新增" Icon="AddNew" ShortCuts="Alt+N" ObjectCondition="TableType()="View"" SubOptKeys="NewBill;DoEvaluateFormula(ERAF_RemoveCachedData({CacheData}));ShowBill;EditBill;RunFieldButtonClickTrigger(trig)" SubOptDataIdxes="0;0;1;1;1"/>,我们每次新增都删除一下该缓冲,然后Trig按钮来重新构造。
取消时
<BillMetaUIOpt Key="Cancel" Caption="取消" Icon="Cancel" ShortCuts="Alt+C" ObjectCondition="TableType()="Bill"" PreCondition="Not(ReadOnly())" SubOptKeys="bCancel;EditBill-R;CancelBillChange;DoEvaluateFormula(ERAF_RemoveCachedData({CacheData}));ShowBill;UIClose" SubOptDataIdxes="0;0;0;0;1;2" NeedRowCheck="False"/>
到此为止该功能就讲的差不多了,该功能的配置稍许有点复杂,大家在配置的时候先要理解各个公式的含义,先配简单的,再配复杂的,多尝试应该能实现。