合并报表-业务规则-规则脚本编写
1 简介
1.1 功能介绍
本篇内容将从业务规则脚本编写的角度对业务规则的应用进行完整的说明。
1.2 系统路径
【企业绩效云】→【合并报表】→【系统配置】→【业务规则】→ 【新增】
公共库规则编辑界面如下:
常用规则编辑界面如下:
2 主要内容
2.1 关键概念理解
2.1.1上下文维度
Context,即上下文,在规则中使用缩写ctx,可以获取规则执行时的情景(Scenario)、财年(Year)、期间(Period)、组织(Entity)、币别(Currency)和过程(Process)这六个维度成员,即调试规则时弹出的维度选择窗口中的维度成员。
规则必须在上下文确定的维度范围内执行,这样可以排除不同组织之间、不同年月之间及不同过程之间计算的相互影响。
上下文需要先在公共库中定义,才可以在常用规则中使用,上下文定义函数如下:
2.1.2 合并流程中的规则执行
无折算智能合并流程图:
需折算智能合并流程图:
在执行智能合并的时候,规则会按照如下过程成员的顺序依次执行分配在过程上的业务规则: EIRpt -> ERAdj -> IRpt -> RAdj -> ADJ -> CADJ -> EJE -> CCADJ -> DADJ -> DEJE -> CSTE -> EIRpt。
对应的组织为(C表示下级公司,P_C表示父_子结构,P表示合并节点): C → C → C→ C → P_C → P_C → P_C→ P_C → P → P → P → P。
对应的币别为,(EC表示下级公司本位币,PC表示合并节点本位币): EC → EC → PC → PC→ PC → PC → PC → PC → PC → PC → PC → PC。
2.2 维度相关函数
base()
获取指定维度成员下的所有末级成员,特殊IC维度会按当前上下文情景财年期间返回生效的base成员
示例:entList = E["0000G"].base() //获取0000G的末级组织成员
children()
获取指定维度成员的直接下级成员,特殊IC维度会按当前上下文情景财年期间返回生效的children成员
示例:entList = E["0000G"].children() //获取0000G的直接下级组织成员
descendant()
获取指定维度成员的所有下级成员,特殊IC维度会按当前上下文情景财年期间返回生效的descendant成员
示例:entList = E["0000G"].descendant() //获取0000G的所有下级组织成员
getVirtualEntity()
获取指定组织的虚拟组织编码,即“父_子”形式;一般用于获取上下文当前组织的虚拟组织编码
示例:vEntCode = ctx.E.getVirtualEntity() //获取当前组织的虚拟组织编码
hasMember()
判断指定维度是否包含指定成员
示例:hasMem = E.hasMember("1234") //判断编码"1234"是否是组织维度里的成员编码
hierarchy()
获取指定维度成员的所有下级成员对象(含自己)
示例:entList = E["0000G"].hierarchy() //获取0000G的所有下级组织成员(含自己)
in()
指定维度的枚举成员范围,作为参数用于scope()函数
示例:let sc = scope( A.in("R1006","R1007") ) //指定科目范围为"R1006","R1007"
isBase()
判断指定维度成员是否是末级成员,或者,是否是指定维度成员的末级成员,特殊IC维度会按当前上下文情景财年期间生效成员判断isBase
示例:let isBaseEnt = ctx.E.isBase() //判断某一组织成员是否是末级成员
isBaseEnt = E.isBase("0000","0000G") //判断编码为0000的组织成员是否是0000G的末级成员
isChild()
判断指定维度成员是否是指定维度成员的直接下级成员,特殊IC维度会按当前上下文情景财年期间生效成员判断isChild
示例:isChildEnt = E.isChild("0000","0000G") //判断编码hild为0000的组织成员是否是0000G的直接下级成员
isDescendant()
判断指定维度成员是否是指定维度成员的下级成员,特殊IC维度会按当前上下文情景财年期间生效成员判断isDescendant
示例:isDescendantEnt = E.isDescendant("0000","0000G") //判断编码hild为0000的组织成员是否是0000G的下级成员
isHierarchy()
判断指定维度成员是否是指定维度成员的下级成员(含自己),特殊IC维度会按当前上下文情景财年期间生效成员判断isHierarchy
示例:isHierarchyEnt = E.isHierarchy("0000","0000G") //判断编码hild为0000的组织成员是否是0000G的下级(含自己)成员
isValidBase()
仅组织维度可用,判断指定组织成员是否是指定组织成员的有效末级成员,有效的定义为参与合并
示例:isValidBaseEnt = E.isValidBase("0011","0011G") //判断编码为0011的组织成员是否是0011G的有效明细成员
isValidChild()
仅组织维度可用,判断指定组织成员是否是指定组织成员的有效直接下级成员,有效的定义为参与合并
示例:isValidChildEnt = E.isValidChild("0011","0011G") //判断编码为0011的组织成员是否是0011G的有效子级成员
isValidDescendant()
仅组织维度可用,判断指定组织成员是否是指定组织成员的有效下级成员,有效的定义为参与合并
示例:isValidDescendantEnt = E.isValidDescendant("0011","0011G") //判断编码为0011的组织成员是否是0011G的有效下级成员
lastPeriod()
获取指定期间的上一期间
示例:let p = ctx.P.lastPeriod() //获取当前期间的上一期间
lastYear()
获取指定财年的上一年
示例:let f = ctx.FY.lastYear() //获取当前财年的上一财年
parent()
获取指定维度成员的父级成员对象,特殊IC维度会按当前上下文情景财年期间生效成员判断parent
示例:let ctxParentEnt = ctx.E.parent() //获取当前组织的直接父级组织
validBase()
仅组织维度可用,获取指定组织成员的所有有效末级成员对象,有效的定义为参与合并
示例:let vBaseEnts = E["0000G"].validBase() //获取0000G合并节点下的所有有效末级组织成员
validChildren()
仅组织维度可用,获取指定组织成员的所有有效直接下级成员对象,有效的定义为参与合并
示例:let vChildEnts = E["0000G"].validChildren() //获取0000G合并节点下的所有有效下级组织成员
validDescendant()
仅组织维度可用,获取指定组织成员的所有有效下级成员对象,有效的定义为参与合并
示例:isValidDescendantEnt = E.isValidDescendant("0011","0011G") //判断编码为0011的组织成员是否是0011G的有效下级成员
2.3 维度成员属性
所有维度成员的属性,均可通过“成员对象”加”.”加“属性编码”的方式获取到其属性值;
所有的属性值编码可以通过“成员对象”加“.” 加“property(属性).number”的方式获取到;
所有的属性值名称可以通过“成员对象”加“.” 加“property(属性).name”的方式获取到;
共有属性
(1) number,成员编码;
(2) longNumber,成员长编码;
(3) storageType,成员存储类型,LABEL-标签、STORAGE-存储、UNSHARE-不共享、SHARE-共享、DYNAMIC-动态计算;
(4) aggOprt,成员聚合算法,加(+)、减(-)、乘(*)、除(/)、忽略(~);
(5) 自定义属性。
私有属性
(1) 组织维度成员私有属性
isDependant,是否独立法人公司,是为true,否为false;
controlOrg,控股组织编码;
EC,本位币别,返回实际的币种缩写,例如“CNY”,“USD”等;
PC,母公司币别,返回实际的币种缩写,例如“CNY”,“USD”等;
isIC,按当前上下文情景财年期间IC维度生效成员判断isIC,是为true,否为false。
(2) 科目维度成员私有属性
accountType,科目类型,1-资产、2-负债、3-权益、10-损益、7-现⾦流量、8-汇率类、9-非财务类、11-其他、12-不分类型、15-收入、16-成本、17-费⽤、50-财务类、51-统计类;
dcDirect,借贷方向,0-⽆,1-借加贷减,2-借减贷加;
dataType,科目数据类型,0-默认、1-货币、2-数值、3-文本、4-⽇期、5-比例、6-枚举;
exchangeRate,折算汇率,1-期末汇率、2-平均汇率,3-⾃定义汇率、4汇率为1、0-不折算、5-历史汇率;
isCon,是否合并,是为true,否为false;
isElim,是否抵消,是为true,否为false;
isPlCarry,是否损益结转,是为true,否为false;
isCalc,是否计算科目,是为true,否为false。
2.4 数据操作函数
ABS()
在计算时取绝对值,在run或runs函数中使用
示例:runs(" v('') = ABS( v('') ) ")
esp()
获取指定投资单位与被投资单位,在指定的情景、财年、期间的各种持股比例
示例:let own = esp(2,2,"0000","0001") //获取组织0000对组织0001的直接持股比例
getCellSet()
获取指定维度成员范围的所有数据集及对应的维度成员组合,维度成员组合中仅包含未唯一指定的维度
示例:let sc = scope();
let cs = getCellSet(sc);
getConAttr()
获取合并架构设置信息里的字段值
示例:
let ctxConMethod = getConAttr("CM") //在当前情景、财年、期间下,获取当前组织及父级组织的合并方法
let ctxConActiveStatus = getConAttr("AS") //在当前情景、财年、期间下,获取当前组织是否向父级组织合并的标识
let ctxConUD1 = getConAttr("UD1") //在当前情景、财年、期间下,获取当前组织及父级组织的自定义字段1的值
let conMethod = getConAttr("CM","S@Actual,FY@FY2020,P@M_M06") //在指定情景、财年、期间下,获取当前组织及父级组织的合并方法
conMethod = getConAttr("CM","E@1001G_1001,S@Actual,FY@FY2020,P@M_M09") //在指定情景、财年、期间下,获取指定的组织及父级组织的合并方法
getRate()
获取指定原币、目标币、汇率方案、汇率类型的汇率
示例:let r = getRate("HKD","CNY","ClosingRate", "RatePreset") //获取通用折算汇率下,由港币向人民币折算的期末汇率
round()
在计算时指定小数精度,会四舍五入,在run或runs函数中使用。
示例:runs("v('') = round(v(''),2)") //指定该V函数的小数精度为小数点后2位
Journal()
调整分录对象构造函数,只能在调整的过程规则脚本里使用,非调整过程使用会提示错误;规则生成的分录默认都是不平衡分录,且不可人工操作。
示例:
let JL = new Journal(ctx) // 声明Journal对象,该对象包含open(),insert()和submit()方法
JL.clear(ctx) // 打回并删除属于当前上下文维度范围的规则生成的历史分录
JL.open("JL_TEST","测试分录","ICA","","123") // 创建分录头
JL.insert(100,"A@R1006",-1,"分录测试") // 插入分录行记录
JL.submit() // 提交分录到数据库
run()
并行执行计算语句
示例:run( scope(),
"v('') = v('')" );
runs()
串行执行计算语句
示例:runs( scope(),
"v('') = v('')" );
save()
向一个确定的维度成员组合上写入一个数据
示例:save("A@R1006,CT@EndingBalance,AT@EntityInput",-1) //向指定维度组合写入“-1”
v()
从一个确定的维度成员组合上获取一个数据;或者作为run、runs函数里的计算表达式
示例:let dData = v("A@,……" ,0);
2.5 功能性函数
debug()
输出指定的字符串,仅调试生效
示例:debug("Test") // 在调试输出窗口输出Test
getRuntimeScope()
获取规则执行时的维度范围
示例:debug(formatString(getRuntimeScope())) //在调试输出窗口输出规则执行时的维度范围
formatString()
将对象转换为字符串,可以作为debug、log或throw函数的参数输出
示例:debug(formatString(getRuntimeScope())) // 在调试输出窗口输出规则执行时的维度范围
fix()…endFix()
如果在一段连续的规则脚本范围内,有相同的维度范围,那么可以在这一段规则的前后分别加上fix(scope())和endFix(),并在scope()中指定好相同的维度范围,那么这一段规则可以缺省scope()中定义了范围的维度
示例:
let sc = scope(A.in("R1006"));
fix(sc);
{ debug(formatString(getRuntimeScope())); }
endFix();
// 输出当前的背景维度成员
getCache()
将指定的内容放入缓存,在后续使用的时候直接访问而不需要再次从库中获取,常用来缓存维度成员对象
log()
指定输出字符串,在调试及智能合并时均会输出,其中智能合并会打印在智能合并的日志中
示例:log("ok") //输出ok字符
scope()
维度成员范围指定函数,常作为参数用于scope()、run()、runs()、getCellSet()、fix()及getRuntimeScope()函数;在指定维度成员范围时,可使用in()、base()、children()、descendant()和hierarchy()函数
示例:runs( scope(),"v('') = v('')" ) //在指定范围内执行V公式赋值
throw()
中断规则执行,并输出自定义的字符串
示例:throw("Break") //中断规则执行并输出Break
3 规则编写规范
3.1 命名规范
常量命名
常量命名全部使用大写字母,多个单词以英文下划线分隔;
变量命名
变量命名方式使用小驼峰格式,即除第一个单词之外,其他单词首字母大写;
特别的,与上下文维度相关的变量可以使用类似常量命名的格式,以示区分,但需要遵循以下格式:
(1)当获取上下文维度成员对象时,命名格式为CTX_维度全码;
(2)当获取上下文维度成员属性时,命名格式为CTX_维度编码_属性编码或属性编码缩写;
函数命名
函数命名方式使用小驼峰格式,即除第一个单词之外,其他单词首字母大写,且第一个单词固定为ctx,表示自定义函数,如function ctxGetEntList() {};
命名含义
(1)常量及变量一般使用具有实际涵义的名词或名词缩写词组;
(2)特别的对于boolean类型的变量或常量,以be动词后加名词或名词缩写的形式命名,如isBaseEnt,canBeElimed等;
(3)函数命名均以动宾短语结构命名,如function ctxGetAccList() {};
3.2 符号规范
缩进(强制)
缩进为两个空格,禁止使用制表符作为缩进字符;可设置编辑器选项。
分号(强制)
每一个完整的语句必须以分号结尾。
引号(强制)
字符串均用双引号包裹,当字符串内部必须有引号时,则在字符串内部使用单引号包裹,如let s = "I say 'Hi'.";。
禁止使用中文符号或特殊字符(强制)
3.3 语句规范
声明语句
(1) 常量用关键字const声明,必须在公共库规则内声明,且声明时必须赋值;
(2)变量用关键字let声明,禁止使用var声明变量,且变量在使用前必需先声明;
(3)函数必须在公共库规则内声明。
表达式
(1)操作符与操作数之间须用空格隔开;常用的操作符包括+、-、*、/、%、=、==、!=、&&、||、?、: 等;
(2)当用!做逻辑取反时,应将!后的逻辑表达式用括号括起来;
(3) 在使用一般格式的for循环时,必须指定循环变量的边界,且循环变量必须有向边界靠拢的赋值表达式;
(4)在v函数中,维度编码与成员编码用"@"连接;
(5)使用runs,尽量少用run
变更记录
产品版本 | 更新内容 | 更新日期 |
V6.0.1 | 优化若干规则函数功能及性能 | 2023年10月28日 |
V6.0.14 | 1、优化了业务规则获取自定义属性功能,可以按业务需求获取维度成员自定属性的编码、名称 2、增加了业务规则层级函数适配往来组织版本化的功能,适用于获取有效的IC成员情形以及组织成员isIC属性判断 | 2024年06月 |
合并报表-业务规则-规则脚本编写
本文2024-09-22 23:11:53发表“云星瀚知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-xinghan-131504.html