uap63公式應(yīng)用關(guān)鍵技術(shù)說(shuō)明_第1頁(yè)
uap63公式應(yīng)用關(guān)鍵技術(shù)說(shuō)明_第2頁(yè)
uap63公式應(yīng)用關(guān)鍵技術(shù)說(shuō)明_第3頁(yè)
uap63公式應(yīng)用關(guān)鍵技術(shù)說(shuō)明_第4頁(yè)
uap63公式應(yīng)用關(guān)鍵技術(shù)說(shuō)明_第5頁(yè)
已閱讀5頁(yè),還剩35頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第一章新版公式使用手冊(cè)31.1公式主要功能31.2公式的基本使用 . 51.3數(shù)值型計(jì)算結(jié)果小數(shù)位的 . 81.4 自定義變量的使用91.5 如何從公式中提取變量121.6 空值”,NULL 值及 Zero 值的處理131.7 如何進(jìn)行列操作151.8 利用定義函數(shù)擴(kuò)展公式功能151.9 外接函數(shù)的使用161.10 (5.02 new) 配置裝載自定義函數(shù)171.11 運(yùn)算符重載181.12 公式簡(jiǎn)單調(diào)試201.13 公式使用最佳實(shí)踐21第二章構(gòu)造開(kāi)發(fā)環(huán)境252.1 數(shù) 算函數(shù)252.2 條件 函數(shù)302.3 數(shù)據(jù)庫(kù) 函數(shù)322.4 字符串相關(guān)函數(shù)342.5 日期函數(shù)352.6 類(lèi)型轉(zhuǎn)換函數(shù)3

2、52.7 貨幣金額函數(shù)362.8 多語(yǔ)言翻譯函數(shù)392.9 其他函數(shù)392.105.02 新增函數(shù)402.11V5.5 新增函數(shù)41UAP 技術(shù)系列第 2 / 42 頁(yè)第一章 新版公式使用手冊(cè)UAP 技術(shù)系列第 6 / 42 頁(yè)本章內(nèi)容概要:l 簡(jiǎn)介1.1 公式主要功能1. 支持的算術(shù)運(yùn)算+,-,*,/,% 例如: sin(1.35)*a/b + cos(3.4)/c 其中 a,b,c 均為變量2. 支持對(duì)數(shù)值型計(jì)算結(jié)果小數(shù)位的 3. 支持邏輯運(yùn)算符&&(兼容老版&),|(兼容老版|),! 例如: iif(a&b)|(c&&d),"ri

3、ght","wrong")其中 a,b,c,d 均為變量4. 支持比較運(yùn)算符>,>=,<,<=,=,!=等,支持 null 值的處理。例如: iif(a>b && a != null)|(c<=d),"right","wrong")其中 a,b,c,d 均為變量5. 支持自定義變量,變量可按 Object 和 String 兩種方式傳入例如: col1->var1+var2其中 var1,var2 均為自定義變量,可以為 String 型,也可以為任意類(lèi)型6. 公式除

4、了支持 String,Number 型數(shù)據(jù)運(yùn)算,還支持自定義類(lèi)型例如: combine(vo1,vo2)其中 vo1,vo2 可為自定義的數(shù)據(jù)類(lèi)型,具體用法參考后面的說(shuō)明7. 支持操作符(+,-,*,/,>,>=,<,<=,=)重載(通過(guò)實(shí)現(xiàn)相應(yīng)的接口)例如: iif(car1>car2)|(factory1<=factory2),"right","wrong")其中 car1,car2,factory1,factory2 的運(yùn)算符通過(guò)實(shí)現(xiàn)相應(yīng)的接口進(jìn)行重載。8. 可以在數(shù)值型一維數(shù)組之間進(jìn)行加減乘除運(yùn)算(數(shù)組長(zhǎng)度必須

5、相等),即支持列操作. 例如 var1 = 1,2,3,4; var2 = 2,3,4,5; 可對(duì) var1,var2 進(jìn)行各種運(yùn)算。9. 系統(tǒng)函數(shù)支持,NC 常用函數(shù)支持例如:sin,cos,ceil,floor,to,getCurrency(),iif()等等,詳細(xì)支持的函數(shù)請(qǐng)參見(jiàn)附錄。10. 支持外接用戶(hù)函數(shù).(可以是一個(gè) java 的)例如:公式 combine("nihao","hao")中,combine 是一個(gè)自定義函數(shù), 可以指定綁定到一個(gè) JAVA 類(lèi)的具體,可參考后面的例子。11. 支持自定義函數(shù).具體應(yīng)用可參考后面的詳細(xì)說(shuō)明(第 1

6、7 頁(yè)第 1.8 節(jié)) 有時(shí)候公式 器內(nèi)部的函數(shù)并不能完全滿(mǎn)足用戶(hù)的要求,此時(shí)用戶(hù)可添加自定義函數(shù)。例如:hello("say something",),hello 為一個(gè)自定義函數(shù), 動(dòng)態(tài) 到公式 器中。12. 支持客戶(hù)端公式和服務(wù)端公式.以滿(mǎn)足前臺(tái)及 調(diào)用,主要體現(xiàn)在數(shù)據(jù)庫(kù) 的 有一定的差別。13. 支持多行公式批量運(yùn)算,且保持變量的傳遞性. 例如:a- >col1+col2;b- >a+col1*col3; c->a+b;14. 支持一個(gè)線(xiàn)程內(nèi)多個(gè)公式執(zhí)行器實(shí)例交替運(yùn)行的情況,但不支持多個(gè)線(xiàn)程內(nèi)同一公式執(zhí)行器實(shí)例交替運(yùn)行。所以如果程序中起多線(xiàn)程的話(huà),

7、建議每個(gè)線(xiàn)程單獨(dú)創(chuàng)建 的公式 器示例。例如下面的代碼是可行的:FormulaParseFather f= new FormulaParse(); f.setExpress(formula); f.setNullAsZero(true);FormulaParseFather f1=new FormulaParse(); f1.setNullAsZero(false); f.setDataSArray(map);String res = f.getValueS();15. 支持 類(lèi)公式的自動(dòng) SQL 合并,極大提高效率(V56 版本)。1.2 公式的基本使用使用公式 器的基本步驟如下:1. 創(chuàng)建公

8、式執(zhí)行器如果在客戶(hù)端使用公式 :FormulaParseFather f = new nc.ui.pub.formulaparse.FormulaParse();如果在服務(wù)端使用公式 :FormulaParseFather f = new nc.bs.pub.formulaparse.FormulaParse();如果不知道當(dāng)前的代碼會(huì)在哪一端運(yùn)行,可以用下面的 進(jìn)行 :if (RuntimeEnv.getInstance().isRunningInServer() parse = new nc.bs.pub.formulaparse.FormulaParse(); else parse =

9、new nc.ui.pub.formulaparse.FormulaParse();如果在客戶(hù)端執(zhí)行公式,但是又不希望使用前臺(tái)緩存(注:在前臺(tái)通過(guò)公式 跨公司大數(shù)據(jù) 時(shí)會(huì)嚴(yán)重影響 LFU 算法效果,導(dǎo)致前臺(tái)緩存數(shù)據(jù)量急劇增加,影響緩存的性,此種場(chǎng)景下不建議在前臺(tái)執(zhí)行公式,所以 NC 報(bào)表類(lèi)執(zhí)行公式要求不走前臺(tái)緩存),可以使用:FormulaParseFather f = new nc.ui.pub.formulaparse.FormulaParseRunInServer();2. 設(shè)置公式執(zhí)行器環(huán)境(自定義變量及自定義函數(shù)可參考后續(xù)章節(jié)描述) 這里可以給公式執(zhí)行器添加自定義變量,例如:UFDo

10、uble var1 = new UFDouble(5.368); f.addVariable(var1);或者添加自定義函數(shù),例如:類(lèi) YourFunction 是一個(gè)定義的函數(shù)類(lèi)(關(guān)于如何自定義函數(shù),請(qǐng)參考自定義函 ),在公式中函數(shù)取名為"yourfun",則可以這樣添加你的自定義函數(shù):f.addFunction("yourfun",new YourFunction);3. 設(shè)置公式的值String fomula = "sin(30)*2-56/78" f.setExpress(fomula);設(shè)置公式執(zhí)行器環(huán)境非必須步驟對(duì)于單行公

11、式:對(duì)于多行公式:String formulas = new String"viewmny1->viewnum*viewprice-rate*0.23 ", "viewmny2-> viewnum*viewprice-rate*0.24"f.setExpressArray(formulas);4. 對(duì)公式進(jìn)行語(yǔ)法檢查在設(shè)置完公式之后,直接調(diào)用執(zhí)行器的 check()便可以進(jìn)行公式檢查:bool isok = f.check();如果返回結(jié)果為 false,那么說(shuō)明公式語(yǔ)法錯(cuò)誤,調(diào)用 getError()可以獲得具體的錯(cuò)誤 :String er

12、rmsg = f.getErrorMsg();下面是一段具體應(yīng)用的代碼:FormulaParseFather f= new nc.ui.pub.formulaparse.FormulaParse(); String formula = "a->getCurrency(cchmny,34)"boolean isok= f.check(); if(!isok)System.out.println(f.getError(); return;另外,如果還沒(méi)有設(shè)置公式,僅僅是想校驗(yàn)公式的正確性,則可以直接通過(guò)checkExpress(String formula)或者:chec

13、kExpressArray(formulas)來(lái)檢查公式,例如:bool isok = f. checkExpress (formulas); /單行公式bool isok = f. checkExpressArray(formulas); /多行公式注意:如果是多行公式,那么只要有一個(gè)公式寫(xiě)法是錯(cuò)誤的,那么檢查結(jié)果就會(huì)是 false。5. 提取公式變量在單據(jù)模板和打印模板的應(yīng)用中,公式中的變量并不是已知的,需要從公式中分析得到,取得公式中的變量之后,再把相應(yīng)的值賦給變量。新版公式 器中提取公式中變量的接口和老版是一致的:VarryVO varrys = f.getVarryArray();下

14、面是單據(jù)模板里取公式變量的典型代碼:/設(shè)置表達(dá)式formulas = filterUsedFormulas(bfc, formulas); if (formulas = null)return null;f.setExpressArray(formulas);/獲得變量名final VarryVO varrys = f.getVarryArray();6. 給公式變量賦值下面是一段給公式變量賦值的代碼:/下列代碼假設(shè) varrys為 nullVarryVO varrys = f.getVarryArray();for (int i = 0; i < varrys.length; i+)S

15、tring varries = varrysi.getVarry();/提取公式變量非必須步驟if(varries != null)for (int j = 0; j < varries.length; j+)UAP 技術(shù)系列第 7 / 42 頁(yè)/從外部環(huán)境取得變量的值Object varryValue = getVarryValue(varriesj);/傳遞給公式f.addVariable(varriesi,varryValue);7. 取得公式的值根據(jù)公式具體的應(yīng)用場(chǎng)景,取值有多種形式,如下所示: 單行公式返回單個(gè)值:Object res = f.getValueAsObject(

16、); 單行公式返回一列值:Object res =f.getValueO();多行公式返回多列值:Object res = f.getValueOArray();單行公式返回單個(gè)字符串String res = f.getValue(); 單行公式返回一列字符串: String res =f.getValueS(); 多行公式返回多列字符串Stringres = f.getValueOArray();1.3 數(shù)值型計(jì)算結(jié)果小數(shù)位的 當(dāng)利用公式 器進(jìn)行數(shù)值型的運(yùn)算時(shí),可以對(duì)輸出結(jié)果的小數(shù)位進(jìn)行 。公式器中提供了以下幾個(gè)接口:public void setScale(int scale);設(shè)置返回精

17、度,截位默認(rèn)為四舍五入。對(duì) Double,UFDouble 型返回結(jié)果有效。public void setScale(int scale, int roundingup);設(shè)置返回精度及截位規(guī)則,對(duì) Double,UFDouble 型返回結(jié)果有效。UAP 技術(shù)系列第 41 / 42 頁(yè)public void setScale(String varname, int scale);具體的變量設(shè)置返回精度,截位默認(rèn)為四舍五入。public void setScale(String varname, int scale, int roundingup);具體的變量設(shè)置返回精度及截位規(guī)則,對(duì)所有數(shù)值型

18、返回結(jié)果有效。如果不做任何設(shè)置,那么輸出結(jié)果與 UFDouble 的默認(rèn)精度一致,為 8 位小數(shù)。下面是一個(gè)具體的示例:FormulaParseFather f = new nc.ui.pub.formulaparse.FormulaParse(); String formulas = new String"a->cchmny*cchmny*cchmny", "b->a*cchmny","c->a*b*cchmny"f.setExpressArray(formulas); Map map = new HashMap(

19、); List v2 = new ArrayList();v2.add(new UFDouble(1.99999); /row value v2.add(new UFDouble(2.9999); /row value v2.add(new UFDouble(3.99999);v2.add(new UFDouble(1.999994); /row value map.put("cchmny",v2);f.setDataSArray(map); f.setScale("a",5);f.setScale("b",6);Object res

20、 = f.getValueOArray();assertEquals("應(yīng)該相等!", "7.99988", res00.toString();10assertEquals("應(yīng)該相等!", "15.999680", res10.toString();/默認(rèn)精度為 8assertEquals("應(yīng)該相等!", "255.98976018", res20.toString();1.4 自定義變量的使用公式支持自定義變量,只要相關(guān)的操作 的話(huà),自定義變量可以是任何類(lèi)型的,下面的代

21、碼說(shuō)明了如何加入一個(gè)名為 var1,UFDouble 型的變量:FormulaParseFather f= new nc.ui.pub.formulaparse.FormulaParse(); String formula = "a->round(var1,3)"f.addVariable("var1",new UFDouble(3.56893);FormulaParseFather f= new nc.ui.pub.formulaparse.FormulaParse(); String formula = "a->round(va

22、r1,3)"List list1 = new ArrayList(); list1.add(new UFDouble(56.2354); list1.add(new UFDouble(23.2343); f.addVariable("var1",list1);除了可以加入簡(jiǎn)單類(lèi)型的變量,還可以加入 ArrayList3, 用戶(hù)自定義對(duì)象 4 等等,下面的代碼演示了如何加入一個(gè) ArrayList 型的變量:另外還可以批量的加入多個(gè)變量,公式 器提供兩個(gè)接口如下:setDataSArray(Hashtable); /老版接口要求,不推薦使用setDataSArray

23、(Map);需要注意的是,由于老版接口 setDataSArray(Hashtable)所有的參數(shù)均通過(guò)字符串傳入,所以在以此方式傳入?yún)?shù)時(shí), 真假字符串之分,真字符串形如:v10 = ""SHVO0000000000000005"" v11 = ""SHVO0000000000000005"" v12 = ""SHVO0000000000000005""即在字符串的兩端加上雙引號(hào)”,表示傳入的參數(shù)為 String 類(lèi)型,如果兩端不加這個(gè)符號(hào),則表示傳入的為數(shù)值型, 公式器會(huì)

24、將其轉(zhuǎn)換為數(shù)值型處理,例如:v10 = "623.23"v11 = "5263.12"v12 = "5242.01"而如果通過(guò)addVariable(name,Value)或者以 setDataSArray(Map)方式傳入?yún)?shù)時(shí),參數(shù)的類(lèi)型取決于實(shí)際傳入的類(lèi)型,公式 器 做任何轉(zhuǎn)換:-),請(qǐng)注意下面兩段代碼的差別。老版公式接口, 真假字符串:FormulaParseFather f = new nc.ui.pub.formulaparse.FormulaParse(); f.setExpress("a->var1+v

25、ar2");List v2 = new ArrayList(); v2.add("100"); /row value v2.add("200"); /row value Hashtable map = new Hashtable(); map.put("var1",v2);map.put("var2",v2);Hashtable maps = new Hashtable1; maps0 = map; f.setDataSArray(maps); /將會(huì)轉(zhuǎn)為數(shù)值f.setScale(2);String re

26、s = f.getValueS();assertEquals("Should equal:","200.00",res0.toString();新版增加的接口,傳什么就是什么,完全按 Object 方式傳遞參數(shù):FormulaParseFather f = new nc.ui.pub.formulaparse.FormulaParse(); f.setExpress("a->var1+var2");List v2 = new ArrayList(); v2.add("100"); /row value v2.

27、add("200"); /row value Map map = new HashMap(); map.put("var1",v2);map.put("var2",v2); f.setDataSArray(map); /當(dāng)作字符串f.setScale(2);String res = f.getValueS();assertEquals("Should equal:","100100",res0.toString();注意:公式中的變量取名不可與內(nèi)置自定義變量名(可參考第 25 頁(yè)第 2 章內(nèi)置變

28、量列表)相同,也不得與內(nèi)置的函數(shù)名(可參考第 26 頁(yè)第 3 章內(nèi)置變量列表)相同,如果和內(nèi)置變量相同,公式可能會(huì)得到不正確的結(jié)果;如果變量和內(nèi)置函數(shù)名相同,則會(huì)報(bào)公式 錯(cuò)誤。1.5 如何從公式中提取變量單據(jù)模板和打印模板的公式 要求可以 識(shí)別公式中的列變量,以便從模板中取得相應(yīng)的值賦給這些列變量。比如對(duì)下面的公式:String formulas = new String"viewcode->getColValue(hyca_viewobj,viewcode, pk_viewobj, pk_viewobj) ","viewname->getColVal

29、ue(hyca_viewobj,viewname,pk_viewobj1,pk_viewobj1)","summny->cchmny*25/5+cchmny"FormulaParseFather f = new nc.ui.pub.formulaparse.FormulaParse();f.setExpressArray(formulas);varrys0: formulaName:viewcode;varry1:pk_viewobj varrys1: formulaName:viewname; varry1: pk_viewobj1 varrys2: fo

30、rmulaName:summny; varry1:cchmny得到的 varrys 的如下:其中 VarryVO 的定義如下:public class VarryVOString formulaNall;/ 公式名:等號(hào)左邊String varry=null;/ 變量,等號(hào)右邊的變量利用 varrys 的就可以從模板中取得相應(yīng)列變量的值,并將公式返回的值賦給每行公式左邊列名所對(duì)應(yīng)的列。下面是提取變量的另一個(gè)例子,演示了從復(fù)雜的函數(shù)中提取列變量:String formulas = new String"viewcode->hyca_viewobj*cvn(hyca_viewobj

31、,viewcode, pk_viewobj,pk_viewobj)+ viewcode*cvs(hyca_viewobj,viewcode, pk_viewobj,pk_viewobj1)","viewname->getColNmV(hyca_viewobj,viewname,pk_viewobj,pk_viewobj2)"FormulaParseFather f = new nc.ui.pub.formulaparse.FormulaParse(); f.setExpressArray(formulas);VarryVO varrys = f.getVar

32、ryArray(); assertEquals("應(yīng)該相等!",2, varrys.length);assertEquals("應(yīng)該相等!",4, (varrys0.getVarry().length);1.6 空值”,NULL 值及 Zero 值的處理在公式 中,請(qǐng)注意區(qū)分以下三個(gè)概念: 空值:指長(zhǎng)度為 0 的字符串,""NULL 值:指沒(méi)有分配任何空間的 Object,類(lèi)似 JAVA 語(yǔ)言里的 NULL Zero 值:指 Double(0)公式執(zhí)行器有一個(gè)共有函數(shù) setNullAsZero(boolean value),用于設(shè)置

33、在運(yùn)算過(guò)程中是否需要將 NULL 值作為 Zero 值來(lái)進(jìn)行運(yùn)算。默認(rèn)狀態(tài)下,公式執(zhí)行器設(shè)置 setNullAsZero(false)。請(qǐng)看下面的例子:String formula = new String "a->val1/val2","b->val1*val2"FormulaParseFather f= new FormulaParse(); f.addVariable("val1",null); f.addVariable("val2",new Double(56); f.setExpressAr

34、ray(formula); f.setNullAsZero(true); /設(shè)置為 true String res = f.getValueSArray();/val1 當(dāng)做 Double(0)計(jì)算,得出 a=0assertEquals("應(yīng)該相等!", "0.00000000", res00);/val1 當(dāng)做 Double(0)計(jì)算,得出 b=0assertEquals("應(yīng)該相等!", "0.00000000", res10);如果上例中 setNullAsZero(false),因?yàn)?null 值無(wú)法參與運(yùn)

35、算,那么得到的結(jié)果為空。對(duì)于 setNullAsZero函數(shù),需要注意的是,NULL 值當(dāng)作 Zero 值來(lái)處理僅僅是指在運(yùn)算過(guò)程中,不適用于返回值為 NULL 時(shí)的處理,例如:String formula = "a->val1" FormulaParseFather f= new FormulaParse(); f.addVariable("val1",null); f.setExpress(formula); f.setNullAsZero(true);String res = f.getValue();/val1 當(dāng)做 Double(0)計(jì)算

36、,但結(jié)果 res 為空值.String formula = "a->toNumber(val1)" FormulaParseFather f= new FormulaParse(); f.addVariable("val1",null);f.setExpress(formula); f.setNullAsZero(true); String res = f.getValue();/結(jié)果 res 為 0.00000000.如果上例中,想要返回 0,則可以這么改寫(xiě)公式:當(dāng) NULL 值參與字符串連接時(shí),NULL 值自動(dòng)被當(dāng)作空值處理,setNullAs

37、Zero 此時(shí)對(duì)運(yùn)算結(jié)果無(wú)任何影響,例如:null+"dddd"+null; null+null+"dddd"上述兩個(gè)公式均應(yīng)該返回"dddd"!fkdw->iif(val2=null,"val2 is zero",val2)"fkdw->iif(val2="","val2 is zero",val2)"iif(getColValue(hyca_viewobj, view=null,pk_viewobj,getColValue(hyca_vie

38、wobj, viewname,pk_viewobj,pk_viewobj)name,pk_viewobj,pk_viewobj);需要根據(jù)實(shí)際場(chǎng)景決定,getColValue()等數(shù)據(jù)庫(kù)函數(shù)如果無(wú)法查到值返回的是 null 值。例如:關(guān)于 NULL 值,空值之間區(qū)別另一個(gè)需要注意的地方是在寫(xiě) IIF 函數(shù)時(shí),比較條件到底是 NULL 還是空值,1.7 如何進(jìn)行列操作公式支持列操作,即列之間的+,-,*,/,%,>,<,>=,<=,=等,需要注意的是這里的公式中的列均由 ArrayList表示,如果加入自定義變量時(shí),如果需要加入一列數(shù)據(jù),需以 ArrayList 的形式加

39、入! 列操作的兩個(gè)對(duì)象要求長(zhǎng)度必須相等,實(shí)際上是對(duì)兩個(gè)列的對(duì)應(yīng)元素進(jìn)行操作.例如:1,2,3,4,5 + 3,3,4,5,6 = 4,5,7,9,114,6,8,9,45 /2,3,4,3,9 = 2,2,2,3,5列操作的目的主要是對(duì)模板上各列進(jìn)行操作,以便可以在各列之間進(jìn)行靈活的運(yùn)算。比 三個(gè)列分別為currentMny(本期發(fā)生金額),initMny(期初金額),endMny(期末金額) 那么就可以直接用公式來(lái)計(jì)算期末金額:endMny-> currentMny + initMny下面是完整的代碼示例:FormulaParseFather f = new nc.ui.pub.for

40、mulaparse.FormulaParse(); f.setExpress("a->sum(cchmny,cchmny,2*cchmny)");String v2 = new String3; v20 = "1" /row value v21 = "2" /row value v22 = "3"Map map = new HashMap(); map.put("cchmny",v2); f.setDataSArray(map); String res = f.getValueS();as

41、sertEquals("應(yīng)該相等!", "4.0", res0);assertEquals("應(yīng)該相等!", "8.0", res1);assertEquals("應(yīng)該相等!", "12.0", res2);1.8 利用定義函數(shù)擴(kuò)展公式功能你可以在公式中加入自定義函數(shù),為了這個(gè)目的,需要做兩件事情:1. 從 nc.vo.pub.expression.function.NcInnerFunction 繼承的函數(shù)處理類(lèi)下面的例子說(shuō)明了如何編寫(xiě) 的函數(shù)處理類(lèi):public clas

42、s MyFunction extends NcInnerFunctionpublic MyFunction()numberOfParameters = 0; /函數(shù)參數(shù)的個(gè)數(shù)/函數(shù)具體的運(yùn)算,param 中是具體的參數(shù)public Object function(List param) throws ParseExceptionif (param = null | param.size() != 0) throw new ParseException("錯(cuò)誤:參數(shù)個(gè)數(shù)不對(duì),mon()不需要參數(shù)!");UFDate date = new UFDate();return Str

43、ing.valueOf(date.getMonth();可以看出,主要在于編寫(xiě) function()函數(shù),這個(gè)函數(shù)實(shí)現(xiàn)了具體的功能,即如何對(duì)傳入的參數(shù)進(jìn)行處理。2. 在公式執(zhí)行器中加入自定義函數(shù)直接調(diào)用 addFunction()函數(shù)加入你的函數(shù)類(lèi)即可,funname 即為你定義函數(shù)在公式中的名稱(chēng)。f.addFunction("funname", new yourFunctionClass();完成了上述兩步工作,你就可以直接在你的公式中使用自定義的函數(shù)了!1.9 外接函數(shù)的使用本公式 器支持外接函數(shù) 6,即可以調(diào)用任何一個(gè)類(lèi)中的函數(shù),只要給出公式中函數(shù)名,類(lèi)名,類(lèi)中函數(shù)名

44、,返回參數(shù)類(lèi)型,函數(shù)參數(shù)類(lèi)型等,就可以實(shí)現(xiàn)在公式中調(diào)用外接函數(shù),比如下面的公式就調(diào)用了 nc.vo.pub.expression.test.Customfunction1 類(lèi)的 combineString 函數(shù)。FormulaParseFather f = new nc.ui.pub.formulaparse.FormulaParse(); f.setSelfMethod( "combine", /公式中函數(shù)名"nc.vo.pub.expression.test.Customfunction1", /類(lèi)名"combineString"

45、, /類(lèi)中函數(shù)名ArrayList.class, /返回參數(shù)類(lèi)型new ClassString.class,String.class); /函數(shù)參數(shù)類(lèi)型f.setExpress("a->combine(cchmny," down")");List v2 = new ArrayList(); v2.add("cut"); /row value v2.add("go"); /row value v2.add("step");Map map = new HashMap(); map.put(&q

46、uot;cchmny",v2); f.setDataSArray(map); String res = f.getValueS();assertEquals("Should equal:","cut down",res0);1.10 (5.02 new) 配置裝載自定義函數(shù)UAP 公式模塊已經(jīng)內(nèi)置了許多常用的函數(shù)(參見(jiàn)附錄),但是具體在開(kāi)發(fā)應(yīng)用 時(shí),這些內(nèi)置的公式或許并不能完全滿(mǎn)足需求,公式 模塊預(yù)留了擴(kuò)展機(jī)制,二次開(kāi)發(fā) 可以根據(jù)實(shí)際 或者項(xiàng)目的需要自行添加業(yè)務(wù)函數(shù)。1.8 節(jié)已經(jīng)了如何開(kāi)發(fā)自定義函數(shù)并通過(guò)代碼方式 函數(shù),本小節(jié)主要 如何通過(guò)配

47、置文件的方式 自定義函數(shù),以獲得更 靈活性。如 果 希 望 自 定 義 的 公 式 在 所 有 的 公 式 器 中 都 可 以 使 用 , 則 在NCHOME/resources/formulaconfig/custfunction 目錄下添加任意文件名的 xml 文件(注意:默認(rèn)發(fā)版盤(pán)中此目錄下有一個(gè) default.xml 文件,請(qǐng)不要?jiǎng)h除也不要改名),文件格式形如:<?xml version="1.0" encoding="gb2312"?><formula-array><formula><customTy

48、pe>0</customType><functionName>hzg</functionName><functionClass>nc.vo.function.ivallen</functionClass></formula><formula><customType>0</customType><functionName>hzg2</functionName><functionClass>nc.vo.function.ivallen2</fu

49、nctionClass></formula></formula-array>如果是特定模塊的自定義公式,且公式 器是區(qū)分模塊構(gòu)造的(V502 后 FormulaParseFather 里增加了待模塊號(hào)的構(gòu)造函數(shù)),比如:FormulaParseFather f = new nc.ui.pub.formulaparse.FormulaParse(“modulesid”);則可以在上述目錄下建立名為模塊號(hào)的目錄,然后將 xml 文件放到此明細(xì)目錄中。例如僅 test 模塊可以使用的公式,則 xml 文件要放到/resources/formulaconfig/custf

50、unction/modulesid 目錄下, 并且要注意,該目錄下一定要保證有一個(gè)名為 default.xml 的文件,所以如果只有一個(gè)配置文件,則該文件 名為 default.xml。1.11 運(yùn)算符重載目前公式 器支持下列運(yùn)算符重載: 運(yùn)算符符號(hào)相應(yīng)接口加+ IAddOperator: public Object add(Object obj)減- ISubOperator: Object sub(Object obj)乘* IMulOperator: Object multiply(Object obj)除/ IDivOperator: Object div(Object obj)另外如

51、果用戶(hù)對(duì)象要在公式中進(jìn)行比較運(yùn)算,請(qǐng)直接實(shí)現(xiàn) java.lang.Comparable 接口,下面是一個(gè)操作符重載的示例:public class TestVO implements IAddOperator public String name; public int age;public TestVO(String name, int age) = name; this.age = age;/運(yùn)算符重載public Object add(Object obj) throws ExceptionTestVO param2 = (TestVO)obj; String snam

52、e = name+; int sage = age+param2.age;TestVO res = new TestVO(sname,sage); return res;這樣便可以在公式里對(duì) TestVO 進(jìn)行加法的運(yùn)算:FormulaParseFather f =newnc.ui.pub.formulaparse.FormulaParse(); f.addVariable("v3", new UFDouble(3.0); f.setExpress("a->vo1+vo2");Map map =initVarMap(); f.

53、setDataSArray(map); Object res = f.getValueO();assertEquals("Should equal:", "cch1cch2", (TestVO) res0).name); assertEquals("Should equal:", 48, (TestVO) res0).age);private Map initVarMap()List v1 = new ArrayList();v1.add(new TestVO("cch1", 24); /row value v1.

54、add(new TestVO("hey1", 25); /row value其中 nitVarMap()函數(shù)對(duì) vo1 和 vo2 做了初始化:v1.add(new TestVO("xuc1", 25); List v2 = new ArrayList();v2.add(new TestVO("cch2", 24); /row value v2.add(new TestVO("hey2", 25); /row value v2.add(new TestVO("xuc2", 23);Map map

55、 = new HashMap(); map.put("vo1", v1);map.put("vo2", v2); return map;1.12 公式簡(jiǎn)單調(diào)試公式 器通過(guò) debug 函數(shù),可以實(shí)現(xiàn)簡(jiǎn)單的調(diào)試功能,主要為了幫助分析公式每一步運(yùn)行的情況,確定錯(cuò)誤位置。請(qǐng)看下面 debug 函數(shù)用法示例。比如需要調(diào)試的公式如下:A->cvn(table,selectfield,wherefield,pkvalue); B->ZeroIfNull(A)*C/10;現(xiàn)在發(fā)現(xiàn) B 字段就是沒(méi)有得到值,那么首先就要確認(rèn) A 是否正確的從數(shù)據(jù)庫(kù)到了值。添加

56、調(diào)試語(yǔ)句如下:A->cvn(table,selectfield,wherefield,pkvalue); tempvar->debug("Variable A="+ A);B->ZeroIfNull(A)*C/10;也可以順便輸出 B 的值:A->cvn(table,selectfield,wherefield,pkvalue); tempvar->debug("Variable A="+ A);B->ZeroIfNull(A)*C/10;tempvar->debug("Variable B="

57、;+ B);注意上面的 tempvar 是一個(gè)臨時(shí)變量,請(qǐng)務(wù)必加上且不要和公式變量及模板 KEY 重復(fù),多個(gè)調(diào)試語(yǔ)句可以使用同一個(gè)臨時(shí)變量,主要為了防止模板 。運(yùn)行程序執(zhí)行公式,便會(huì)輸出調(diào)試 形如:公式調(diào)試Variable A=45.23 公式調(diào)試Variable B=這樣就知道錯(cuò)誤大概在什么地方了。1.13 公式使用最佳實(shí)踐公式技術(shù)紅皮書(shū) 1.2 節(jié)提到過(guò)公式的一些基本用法,這里 NC 使用公式各場(chǎng)景常見(jiàn)的效率問(wèn)題,總結(jié)一些如何更高效使用公式的原則,如果發(fā)現(xiàn)目前代碼不符合以下提到的原則,請(qǐng)務(wù)必修改以達(dá)到更 效率。1. 盡可能重用公式 器實(shí)例重新構(gòu)造一個(gè)新的公式 器實(shí)例多少會(huì)耗用一些時(shí)間, 來(lái)

58、講大約需要 200ms 的時(shí)間(根據(jù)具體機(jī)器配置及自定義函數(shù)數(shù)量不等),所以請(qǐng)避免出現(xiàn)下面這類(lèi)代碼:for(.)/在循環(huán)里構(gòu)造公式器實(shí)例FormulaParseFather f = new nc.ui.pub.formulaparse.FormulaParse();function()/頻繁調(diào)用的里反復(fù)構(gòu)造公式器實(shí)例FormulaParseFather f = new nc.ui.pub.formulaparse.FormulaParse();有些代碼沒(méi)有上述列舉的這么明顯,但是也是殊途同歸,最終犯的錯(cuò)誤跟上面提到的一樣,編碼的時(shí)候要多多注意,在保證線(xiàn)程安全的情況下,盡量重復(fù)使用同一個(gè)公式 器

59、實(shí)例。如果在前臺(tái),盡量通過(guò)成員變量重復(fù)使用同一個(gè)公式 器實(shí)例,如果沒(méi)有異步調(diào)用,甚至可以考慮使用靜態(tài)變量保存一個(gè)公式 器實(shí)例。如果在 ,則可以考慮使用 ThLocal 來(lái)保存一個(gè)公式器實(shí)例,做到線(xiàn)程級(jí)共享??梢詤⒖?NCFormulaHelper (Since V56),根據(jù)需要構(gòu)造相應(yīng)的公式器實(shí)例。/* 取得一個(gè)線(xiàn)程安全,但是前臺(tái)不保證線(xiàn)程安全的公式* 全,請(qǐng)調(diào)用:器實(shí)例,前臺(tái)如果需要線(xiàn)程* getThSafeFormulaParser().* return Returns the formulaParser.*/public static FormulaParseFather getFormulaParser()2. 盡可能減少公式 要充分認(rèn)識(shí)到公式 是一個(gè)輔助 ,輔助帶出(計(jì)算出)一些附加數(shù)據(jù)(稱(chēng)之為計(jì)算屬性),不要過(guò)多的依靠公式 ,甚至想通過(guò)公式 取代一部分業(yè)務(wù)代碼,這將會(huì)導(dǎo)致比較嚴(yán)重的效率問(wèn)題。有些 代碼,如果可以通過(guò) 關(guān)聯(lián) 得到相關(guān)數(shù)據(jù),則不推薦在 代碼里通過(guò)公式去 ,感覺(jué)走了很

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論