NCV60公式技术红皮书.docx

上传人:b****2 文档编号:1245643 上传时间:2023-04-30 格式:DOCX 页数:47 大小:33.77KB
下载 相关 举报
NCV60公式技术红皮书.docx_第1页
第1页 / 共47页
NCV60公式技术红皮书.docx_第2页
第2页 / 共47页
NCV60公式技术红皮书.docx_第3页
第3页 / 共47页
NCV60公式技术红皮书.docx_第4页
第4页 / 共47页
NCV60公式技术红皮书.docx_第5页
第5页 / 共47页
NCV60公式技术红皮书.docx_第6页
第6页 / 共47页
NCV60公式技术红皮书.docx_第7页
第7页 / 共47页
NCV60公式技术红皮书.docx_第8页
第8页 / 共47页
NCV60公式技术红皮书.docx_第9页
第9页 / 共47页
NCV60公式技术红皮书.docx_第10页
第10页 / 共47页
NCV60公式技术红皮书.docx_第11页
第11页 / 共47页
NCV60公式技术红皮书.docx_第12页
第12页 / 共47页
NCV60公式技术红皮书.docx_第13页
第13页 / 共47页
NCV60公式技术红皮书.docx_第14页
第14页 / 共47页
NCV60公式技术红皮书.docx_第15页
第15页 / 共47页
NCV60公式技术红皮书.docx_第16页
第16页 / 共47页
NCV60公式技术红皮书.docx_第17页
第17页 / 共47页
NCV60公式技术红皮书.docx_第18页
第18页 / 共47页
NCV60公式技术红皮书.docx_第19页
第19页 / 共47页
NCV60公式技术红皮书.docx_第20页
第20页 / 共47页
亲,该文档总共47页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

NCV60公式技术红皮书.docx

《NCV60公式技术红皮书.docx》由会员分享,可在线阅读,更多相关《NCV60公式技术红皮书.docx(47页珍藏版)》请在冰点文库上搜索。

NCV60公式技术红皮书.docx

NCV60公式技术红皮书

公式解析器使用指南

第一章新版公式使用手册2

1.1公式主要功能2

1.2公式的基本使用方法3

1.3数值型计算结果小数位的控制6

1.4自定义变量的使用7

1.5如何从公式中提取变量9

1.6空值””,NULL值及Zero值的处理10

1.7如何进行列操作11

1.8利用定义函数扩展公式功能12

1.9外接函数的使用13

1.10(5.02new)配置装载自定义函数13

1.11运算符重载14

1.12公式简单调试15

1.13公式使用最佳实践17

附录:

公式解析器内置公式列表21

3.1数学运算函数21

3.2条件判断函数24

3.3数据库查询函数25

3.4字符串相关函数27

3.5日期函数28

3.6类型转换函数28

3.7货币金额函数29

3.8多语言翻译函数31

3.9其他函数31

3.105.02新增函数31

3.11V5.5新增函数32

第一章新版公式使用手册

1.1公式主要功能

1.支持一般的算术运算+,-,*,/,ˆ,%

例如:

sin(1.35)*a/b+cos(3.4)/c

其中a,b,c均为变量

2.支持对数值型计算结果小数位的控制

3.支持逻辑运算符&&(兼容老版&),||(兼容老版|),!

例如:

iif((a&b)||(c&&d),"right","wrong")

其中a,b,c,d均为变量

4.支持比较运算符>,>=,<,<=,==,!

=等,支持null值的处理。

例如:

iif((a>b&&a!

=null)||(c<=d),"right","wrong")

其中a,b,c,d均为变量

5.支持自定义变量,变量可按Object和String两种方式传入

例如:

col1->var1+var2

其中var1,var2均为自定义变量,可以为String型,也可以为任意类型

6.公式除了支持String,Number型数据运算,还支持自定义类型

例如:

combine(vo1,vo2)

其中vo1,vo2可为自定义的数据类型,具体用法参考后面的说明

7.支持操作符(+,-,*,/,>,>=,<,<=,==)重载(通过实现相应的接口)

例如:

iif((car1>car2)||(factory1<=factory2),"right","wrong")

其中car1,car2,factory1,factory2的运算符通过实现相应的接口进行重载。

8.可以在数值型一维数组之间进行加减乘除运算(数组长度必须相等),即支持列操作.

例如var1=[1,2,3,4];var2=[2,3,4,5];可对var1,var2进行各种运算。

9.系统函数支持,NC常用函数支持

例如:

sin,cos,ceil,floor,toChinese,getChineseCurrency(),iif()

等等,详细支持的函数请参见附录。

10.支持外接用户函数.(可以是一个java的方法)

例如:

公式combine("nihao","hao")中,combine是一个自定义函数,

可以指定绑定到一个JAVA类的具体方法,可参考后面的例子。

11.支持自定义函数.具体应用可参考后面的详细说明(第17页第1.8节)

有时候公式解析器内部的函数并不能完全满足用户的要求,

此时用户可添加自定义函数。

例如:

hello("saysomething",person),hello为一个自定义函数,

动态注册到公式解析器中。

12.支持客户端公式和服务端公式.

以满足前台及后台调用,主要体现在数据库查询的方式上有一定的差别。

13.支持多行公式批量运算,且保持变量的传递性.

例如:

a->col1+col2;

b->a+col1*col3;

c->a+b;

14.支持一个线程内多个公式执行器实例交替运行的情况,但不支持多个线程内同一公式执行器实例交替运行。

所以如果程序中起多线程的话,建议每个线程单独创建自己的公式解析器示例。

例如下面的代码是可行的:

FormulaParseFatherf=newFormulaParse();

f.setExpress(formula);

f.setNullAsZero(true);

FormulaParseFatherf1=

newFormulaParse();f1.setNullAsZero(false);

f.setDataSArray(map);

String[]res=f.getValueS();

15.支持单表查询类公式的自动SQL合并,极大提高查询效率(V56版本)。

1.2公式的基本使用方法

使用公式解析器的基本步骤如下:

1.创建公式执行器

如果在客户端使用公式解析:

FormulaParseFatherf=new;

如果在服务端使用公式解析:

FormulaParseFatherf=new;

如果不知道当前的代码会在哪一端运行,可以用下面的方法进行判断:

if(RuntimeEnv.getInstance().isRunningInServer()){

parse=new;

}else{

parse=new;

}

如果在客户端执行公式,但是又不希望使用前台缓存(注:

在前台通过公式查询跨公司大数据档案时会严重影响LFU算法效果,导致前台缓存数据量急剧增加,影响缓存的稳定性,此种场景下不建议在前台执行公式,所以NC报表类执行公式要求不走前台缓存),可以使用:

FormulaParseFatherf=new;

2.设置公式执行器环境(自定义变量及自定义函数可参考后续章节描述)

这里可以给公式执行器添加自定义变量,例如:

UFDoublevar1=newUFDouble(5.368);

f.addVariable(var1);

或者添加自定义函数,例如:

类YourFunction是一个定义的函数类(关于如何自

定义函数,请参考自定义函数一节),在公式中函数取名为"yourfun",则可以这样

添加你的自定义函数:

f.addFunction("yourfun",newYourFunction);

3.设置公式的值

设置公式执行器环境非必须步骤

对于单行公式:

Stringfomula="sin(30)*2-56/78";

f.setExpress(fomula);

对于多行公式:

String[]formulas=newString[]

{

"viewmny1->viewnum*viewprice-rate*0.23",

"viewmny2->viewnum*viewprice-rate*0.24"

};

f.setExpressArray(formulas);

4.对公式进行语法检查

在设置完公式之后,直接调用执行器的check()方法便可以进行公式检查:

boolisok=f.check();

如果返回结果为false,那么说明公式存在语法错误,调用getError()

可以获得具体的错误信息:

Stringerrmsg=f.getErrorMsg();

下面是一段具体应用的代码:

FormulaParseFatherf=new;

Stringformula="a->getChineseCurrency(cchmny,34)";

booleanisok=f.check();if(!

isok)

{

;

return;

}

另外,如果还没有设置公式,仅仅是想校验公式的正确性,则可以直接通过

checkExpress(Stringformula)

或者:

checkExpressArray(formulas)

来检查公式,例如:

boolisok=f.checkExpress(formulas);//单行公式

boolisok=f.checkExpressArray(formulas);//多行公式

注意:

如果是多行公式,那么只要有一个公式写法是错误的,那么检查结果就会

是false。

5.提取公式变量

在单据模板和打印模板的应用中,公式中的变量并不是已知的,需要从公式中

分析得到,取得公式中的变量之后,再把相应的值赋给变量。

新版公式解析器

中提取公式中变量的接口和老版是一致的:

VarryVO[]varrys=f.getVarryArray();

下面是单据模板里取公式变量的典型代码:

//设置表达式

formulas=filterUsedFormulas(bfc,formulas);

if(formulas==null)

returnnull;

f.setExpressArray(formulas);

//获得变量名

finalVarryVO[]varrys=f.getVarryArray();

6.给公式变量赋值

下面是一段给公式变量赋值的代码:

//下列代码假设varrys不会为null

VarryVO[]varrys=f.getVarryArray();

for(inti=0;i

{

String[]varries=varrys[i].getVarry();

//提取公式变量非必须步骤

if(varries!

=null)

{

for(intj=0;j

{

//从外部环境取得变量的值

ObjectvarryValue=getVarryValue(varries[j]);

//传递给公式

f.addVariable(varries[i],varryValue);

}

}

}

7.取得公式的值

根据公式具体的应用场景,取值有多种形式,如下所示:

单行公式返回单个值:

Objectres=f.getValueAsObject();

单行公式返回一列值:

Object[]res=f.getValueO();

多行公式返回多列值:

Object[][]res=f.getValueOArray();

单行公式返回单个字符串

Stringres=f.getValue();

单行公式返回一列字符串:

String[]res=f.getValueS();

多行公式返回多列字符串

String[][]res=f.getValueOArray();

1.3数值型计算结果小数位的控制

当利用公式解析器进行数值型的运算时,可以对输出结果的小数位进行控制。

公式

解析器中提供了以下几个接口:

publicvoidsetScale(intscale);

设置返回精度,截位默认为四舍五入。

对Double,UFDouble型返回结果有效。

publicvoidsetScale(intscale,introundingup);

设置返回精度及截位规则,对Double,UFDouble型返回结果有效。

publicvoidsetScale(Stringvarname,intscale);

针对具体的变量设置返回精度,截位默认为四舍五入。

publicvoidsetScale(Stringvarname,intscale,introundingup);

针对具体的变量设置返回精度及截位规则,对所有数值型返回结果有效。

如果不做任何设置,那么输出结果与UFDouble的默认精度一致,为8位小数。

下面是一个具体的示例:

FormulaParseFatherf=new;

String[]formulas=newString[]

{

"a->cchmny*cchmny*cchmny",

"b->a*cchmny",

"c->a*b*cchmny"

};

f.setExpressArray(formulas);

Mapmap=newHashMap();

Listv2=newArrayList();

v2.add(newUFDouble(1.99999));//rowvalue

v2.add(newUFDouble(2.9999));//rowvalue

v2.add(newUFDouble(3.99999));

v2.add(newUFDouble(1.999994));//rowvalue

map.put("cchmny",v2);

f.setDataSArray(map);

f.setScale("a",5);

f.setScale("b",6);

Object[][]res=f.getValueOArray();

assertEquals("应该相等!

","7.99988",res[0][0].toString());

10

assertEquals("应该相等!

","15.999680",res[1][0].toString());

//默认精度为8

assertEquals("应该相等!

","255.",res[2][0].toString());

1.4自定义变量的使用

公式支持自定义变量,只要相关的操作允许的话,自定义变量可以是任何类型的,下面的代码说明了如何加入一个名为var1,UFDouble型的变量:

FormulaParseFatherf=new;

Stringformula="a->round(var1,3)";

f.addVariable("var1",newUFDouble(3.56893));

除了可以加入简单类型的变量,还可以加入ArrayList3,用户自定义对象4等等,下面的代码演示了如何加入一个ArrayList型的变量:

FormulaParseFatherf=new;

Stringformula="a->round(var1,3)";

Listlist1=newArrayList();

list1.add(newUFDouble(56.2354));

list1.add(newUFDouble(23.2343));

f.addVariable("var1",list1);

另外还可以批量的加入多个变量,公式解析器提供两个接口如下:

setDataSArray(Hashtable[]);//老版接口要求,不推荐使用

setDataSArray(Map);

需要注意的是,由于老版接口setDataSArray(Hashtable[])所有的参数均通过字符串传入,所以在以此方式传入参数时,存在真假字符串之分,真字符串形如:

v1[0]="\"SHVO0000000000000005\"";

v1[1]="\"SHVO0000000000000005\"";

v1[2]="\"SHVO0000000000000005\"";

即在字符串的两端加上双引号”,表示传入的参数为String类型,如果两端不加这个符号,则表示传入的为数值型,公式解析器会将其转换为数值型处理,例如:

v1[0]="623.23";

v1[1]="5263.12";

v1[2]="5242.01";

而如果通过addVariable(name,Value)或者以setDataSArray(Map)方式传入参数时,参数的类型取决于实际传入的类型,公式解析器不会做任何转换:

-),请注意下面两段代码的差别。

老版公式接口,判断真假字符串:

FormulaParseFatherf=new;

f.setExpress("a->var1+var2");

Listv2=newArrayList();

v2.add("100");//rowvalue

v2.add("200");//rowvalue

Hashtablemap=newHashtable();

map.put("var1",v2);

map.put("var2",v2);

Hashtable[]maps=newHashtable[1];

maps[0]=map;

f.setDataSArray(maps);//将会转为数值

f.setScale

(2);

String[]res=f.getValueS();

assertEquals("Shouldequal:

","200.00",res[0].toString());

新版增加的接口,传什么就是什么,完全按Object方式传递参数:

FormulaParseFatherf=new;

f.setExpress("a->var1+var2");

Listv2=newArrayList();

v2.add("100");//rowvalue

v2.add("200");//rowvalue

Mapmap=newHashMap();

map.put("var1",v2);

map.put("var2",v2);

f.setDataSArray(map);//当作字符串

f.setScale

(2);

String[]res=f.getValueS();

assertEquals("Shouldequal:

","100100",res[0].toString());

注意:

公式中的变量取名不可与内置自定义变量名(可参考第25页第2章内置变量列表)相同,也不得与内置的函数名(可参考第26页第3章内置变量列表)相同,如果和内置变量相同,公式解析可能会得到不正确的结果;如果变量和内置函数名相同,则会报公式解析错误。

1.5如何从公式中提取变量

单据模板和打印模板的公式解析要求可以解析识别公式中的列变量,以便从模板中取得相应的值赋给这些列变量。

比如对下面的公式:

String[]formulas=newString[]

{

"viewcode->getColValue(hyca_viewobj,viewcode,

pk_viewobj,pk_viewobj)",

"viewchinaname->getColValue(hyca_viewobj,viewchinaname,

pk_viewobj1,pk_viewobj1)",

"summny->cchmny*25/5+cchmny"

}

FormulaParseFatherf=new;

f.setExpressArray(formulas);

得到的varrys的信息如下:

varrys[0]:

formulaName:

viewcode;varry[1]:

pk_viewobj

varrys[1]:

formulaName:

viewchinaname;varry[1]:

pk_viewobj1

varrys[2]:

formulaName:

summny;varry[1]:

cchmny

其中VarryVO的定义如下:

publicclassVarryVO

{

StringformulaName=null;//公式名:

等号左边

String[]varry=null;//变量,等号右边的变量

}

利用varrys的信息就可以从模板中取得相应列变量的值,并将公式返回的值赋给每行公式左边列名所对应的列。

下面是提取变量的另一个例子,演示了从复杂的函数中提取列变量:

String[]formulas=newString[]

{

"viewcode->hyca_viewobj*cvn(hyca_viewobj,viewcode,

pk_viewobj,pk_viewobj)

+viewcode*cvs(hyca_viewobj,viewcode,

pk_viewobj,pk_viewobj1)",

"viewchinaname->getColNmV(hyca_viewobj,viewchinaname,

pk_viewobj,pk_viewobj2)"

};

FormulaParseFatherf=new;

f.setExpressArray(formulas);

VarryVO[]varrys=f.getVarryArray();

assertEquals("应该相等!

",2,varrys.length);

assertEquals("应该相等!

",4,(varrys[0].getVarry()).length);

1.6空值””,NULL值及Zero值的处理

在公式解析中,请注意区分以下三个概念:

空值:

指长度为0的字符串,""

NULL值:

指没有分配任何空间的Object,类似JAVA语言里的NULL

Zero值:

指Double(0)

公式执行器有一个共有函数setNullAsZero(booleanvalue),用于设置在运算过程中是否需要将NULL值作为Zero值来进行运算。

默认状态下,公式执行器设置setNullAsZero(false)。

请看下面的例子:

Stringformula[]=newString[]{

"a->val1/val2",

"b->val1*val2"

};

FormulaParseFatherf=newFormulaParse();

f.addVariable("val1",null);

f.addVariable("val2",newDouble(56));

f.setExpressArray(formula);

f.setNullAsZero(true);//设置为true

String[][]res=f.getValueSArray();

//val1当做Double(0)计算,得出a=0

assertEquals("应该相等!

","0.00000000",res[0][0]);

//val1当做Double(0)计算,得出b=0

assertEquals("应该相等!

","0.00000000",res[1][0]);

如果上例中setNullAsZero(false),因为null值无法参与运算,那么得到的结果为空。

对于setNullAsZero函数,需要注意的是,NULL值当作Zero值来处理仅仅是指在运算过程中,不适用于返回值为NULL时的处理,例如:

Stringformula[]="a->val1";

FormulaParseFatherf=newFormulaParse();

f.addVariable("val1",null);

f.setExpress(formula);

f.setNullAsZero(true);

Stringres=f.getValue();

//val1当做Double(0)计算,但结果res为空值.

如果上例中,想要返回0,则可以这么改写公式:

Stringformula[]="a->toNumber(val1)";

Formu

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2