NCV5公式技术红皮书Word下载.docx
- 文档编号:1509600
- 上传时间:2023-04-30
- 格式:DOCX
- 页数:38
- 大小:28.93KB
NCV5公式技术红皮书Word下载.docx
《NCV5公式技术红皮书Word下载.docx》由会员分享,可在线阅读,更多相关《NCV5公式技术红皮书Word下载.docx(38页珍藏版)》请在冰点文库上搜索。
col1->
var1+var2
其中var1,var2均为自定义变量,可以为String型,也可以为任意类型
6.公式除了支持String,Number型数据运算,还支持自定义类型
combine(vo1,vo2)
其中vo1,vo2可为自定义的数据类型,具体用法参考后面的说明
7.支持操作符(+,-,*,/,>
=,==)重载(通过实现相应的接口)
iif((car1>
car2)||(factory1<
=factory2),"
其中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.支持自定义函数.具体应用可参考后面的详细说明(第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();
2.公式的基本使用方法
使用公式解析器的基本步骤如下:
2.1创建公式执行器
如果在客户端使用公式解析:
FormulaParseFatherf=newnc.ui.pub.formulaparse.FormulaParse();
如果在服务端使用公式解析:
FormulaParseFatherf=newnc.bs.pub.formulaparse.FormulaParse();
如果不知道当前的代码会在哪一端运行,可以用下面的方法进行判断:
if(RuntimeEnv.getInstance().isRunningInServer()){
parse=newnc.bs.pub.formulaparse.FormulaParse();
}else{
parse=newnc.ui.pub.formulaparse.FormulaParse();
}
2.2设置公式执行器环境
(自定义变量及自定义函数可参考后续章节描述)
这里可以给公式执行器添加自定义变量,例如:
UFDoublevar1=newUFDouble(5.368);
f.addVariable(var1);
或者添加自定义函数,例如:
类YourFunction是一个定义的函数类(关于如何自定义函数,请参考自定义函数一节),在公式中函数取名为"
yourfun"
则可以这样添加你的自定义函数:
f.addFunction("
newYourFunction);
2.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);
2.4对公式进行语法检查
在设置完公式之后,直接调用执行器的check()方法便可以进行公式检查:
boolisok=f.check();
如果返回结果为false,那么说明公式存在语法错误,调用getError()可以获得具体的错误信息:
Stringerrmsg=f.getErrorMsg();
下面是一段具体应用的代码:
FormulaParseFatherf=newnc.ui.pub.formulaparse.FormulaParse();
Stringformula="
getChineseCurrency(cchmny,34)"
booleanisok=f.check();
if(!
isok)
System.out.println(f.getError());
return;
另外,如果还没有设置公式,仅仅是想校验公式的正确性,则可以直接通过
checkExpress(Stringformula)
或者:
checkExpressArray(formulas)
来检查公式,例如:
boolisok=f.checkExpress(formulas);
//单行公式
boolisok=f.checkExpressArray(formulas);
//多行公式
注意:
如果是多行公式,那么只要有一个公式写法是错误的,那么检查结果就会是false。
2.5提取公式变量
在单据模板和打印模板的应用中,公式中的变量并不是已知的,需要从公式中分析得到,取得公式中的变量之后,再把相应的值赋给变量。
新版公式解析器
中提取公式中变量的接口和老版是一致的:
VarryVO[]varrys=f.getVarryArray();
下面是单据模板里取公式变量的典型代码:
//设置表达式
formulas=filterUsedFormulas(bfc,formulas);
if(formulas==null)
returnnull;
//获得变量名
finalVarryVO[]varrys=f.getVarryArray();
2.6给公式变量赋值
下面是一段给公式变量赋值的代码:
//下列代码假设varrys不会为null
for(inti=0;
i<
varrys.length;
i++)
String[]varries=varrys[i].getVarry();
//提取公式变量非必须步骤
if(varries!
=null)
for(intj=0;
j<
varries.length;
j++)
//从外部环境取得变量的值
ObjectvarryValue=getVarryValue(varries[j]);
//传递给公式
f.addVariable(varries[i],varryValue);
2.7取得公式的值
根据公式具体的应用场景,取值有多种形式,如下所示:
单行公式返回单个值:
Objectres=f.getValueAsObject();
单行公式返回一列值:
Object[]res=f.getValueO();
多行公式返回多列值:
Object[][]res=f.getValueOArray();
单行公式返回单个字符串
Stringres=f.getValue();
单行公式返回一列字符串:
String[]res=f.getValueS();
多行公式返回多列字符串
String[][]res=f.getValueOArray();
3.数值型计算结果小数位的控制
当利用公式解析器进行数值型的运算时,可以对输出结果的小数位进行控制。
公式解析器中提供了以下几个接口:
publicvoidsetScale(intscale);
设置返回精度,截位默认为四舍五入。
对Double,UFDouble型返回结果有效。
publicvoidsetScale(intscale,introundingup);
设置返回精度及截位规则,对Double,UFDouble型返回结果有效。
publicvoidsetScale(Stringvarname,intscale);
针对具体的变量设置返回精度,截位默认为四舍五入。
publicvoidsetScale(Stringvarname,intscale,introundingup);
针对具体的变量设置返回精度及截位规则,对所有数值型返回结果有效。
如果不做任何设置,那么输出结果与UFDouble的默认精度一致,为8位小数。
下面是一个具体的示例:
cchmny*cchmny*cchmny"
a*cchmny"
a*b*cchmny"
Mapmap=newHashMap();
Listv2=newArrayList();
v2.add(newUFDouble(1.99999));
//rowvalue
v2.add(newUFDouble(2.9999));
v2.add(newUFDouble(3.99999));
v2.add(newUFDouble(1.999994));
map.put("
cchmny"
v2);
f.setScale("
a"
5);
b"
6);
assertEquals("
应该相等!
"
7.99988"
res[0][0].toString());
10
15.999680"
res[1][0].toString());
//默认精度为8
255.98976018"
res[2][0].toString());
4.自定义变量的使用
公式支持自定义变量,只要相关的操作允许的话,自定义变量可以是任何类型的,下面的代码说明了如何加入一个名为var1,UFDouble型的变量:
round(var1,3)"
f.addVariable("
var1"
newUFDouble(3.56893));
除了可以加入简单类型的变量,还可以加入ArrayList3,用户自定义对象4等等,下面的代码演示了如何加入一个ArrayList型的变量:
Listlist1=newArrayList();
list1.add(newUFDouble(56.2354));
list1.add(newUFDouble(23.2343));
list1);
另外还可以批量的加入多个变量,公式解析器提供两个接口如下:
setDataSArray(Hashtable[]);
//老版接口要求,不推荐使用
setDataSArray(Map);
需要注意的是,由于老版接口setDataSArray(Hashtable[])所有的参数均通过字符串传入,所以在以此方式传入参数时,存在真假字符串之分,真字符串形如:
v1[0]="
\"
SHVO0000000000000005\"
v1[1]="
v1[2]="
即在字符串的两端加上双引号”,表示传入的参数为String类型,如果两端不加这个符号,则表示传入的为数值型,公式解析器会将其转换为数值型处理,例如:
623.23"
5263.12"
5242.01"
而如果通过addVariable(name,Value)或者以setDataSArray(Map)方式传入参数时,参数的类型取决于实际传入的类型,公式解析器不会做任何转换:
-),请注意下面两段代码的差别。
老版公式接口,判断真假字符串:
f.setExpress("
var1+var2"
);
v2.add("
100"
200"
Hashtablemap=newHashtable();
var2"
Hashtable[]maps=newHashtable[1];
maps[0]=map;
f.setDataSArray(maps);
//将会转为数值
f.setScale
(2);
Shouldequal:
200.00"
res[0].toString());
新版增加的接口,传什么就是什么,完全按Object方式传递参数:
//当作字符串
100100"
公式中的变量取名不可与内置自定义变量名(可参考附录内置变量列表)相同,也不得与内置的函数名(可参考附录内置公式列表)相同。
如果和内置变量相同,公式解析可能会得到不正确的结果;
如果变量和内置函数名相同,则会报公式解析错误。
5.如何从公式中提取变量
单据模板和打印模板的公式解析要求可以解析识别公式中的列变量,以便从模板中取得相应的值赋给这些列变量。
比如对下面的公式:
viewcode->
getColValue(hyca_viewobj,viewcode,
pk_viewobj,pk_viewobj)"
viewchinaname->
getColValue(hyca_viewobj,viewchinaname,
pk_viewobj1,pk_viewobj1)"
summny->
cchmny*25/5+cchmny"
得到的varrys的信息如下:
varrys[0]:
formulaName:
viewcode;
varry[1]:
pk_viewobj
varrys[1]:
viewchinaname;
varry[1]:
pk_viewobj1
varrys[2]:
summny;
cchmny
其中VarryVO的定义如下:
publicclassVarryVO
StringformulaName=null;
//公式名:
等号左边
String[]varry=null;
//变量,等号右边的变量
利用varrys的信息就可以从模板中取得相应列变量的值,并将公式返回的值赋给每行公式左边列名所对应的列。
下面是提取变量的另一个例子,演示了从复杂的函数中提取列变量:
hyca_viewobj*cvn(hyca_viewobj,viewcode,
pk_viewobj,pk_viewobj)
+viewcode*cvs(hyca_viewobj,viewcode,
pk_viewobj,pk_viewobj1)"
getColNmV(hyca_viewobj,viewchinaname,
pk_viewobj,pk_viewobj2)"
2,varrys.length);
4,(varrys[0].getVarry()).length);
6.空值””,NULL值及Zero值的处理
在公式解析中,请注意区分以下三个概念:
空值:
指长度为0的字符串,"
NULL值:
指没有分配任何空间的Object,类似JAVA语言里的NULL
Zero值:
指Double(0)
公式执行器有一个共有函数setNullAsZero(booleanvalue),用于设置在运算过程中是否需要将NULL值作为Zero值来进行运算。
默认状态下,公式执行器设置setNullAsZero(false)。
请看下面的例子:
Stringformula[]=newString[]{
val1/val2"
val1*val2"
val1"
null);
val2"
newDouble(56));
f.setExpressArray(formula);
//设置为true
String[][]res=f.getValueSArray();
//val1当做Double(0)计算,得出a=0
0.00000000"
res[0][0]);
//val1当做Double(0)计算,得出b=0
res[1][0]);
如果上例中setNullAsZero(false),因为null值无法参与运算,那么得到的结果为空。
对于setNullAsZero函数,需要注意的是,NULL值当作Zero值来处理仅仅是指在运算过程中,不适用于返回值为NULL时的处理,例如:
Stringformula[]="
//val1当做Double(0)计算,但结果res为空值.
如果上例中,想要返回0,则可以这么改写公式:
toNumber(val1)"
Stringres=f.getValue
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- NCV5 公式 技术 红皮书