1. 程式人生 > >EAS BOS 開發問題集錦

EAS BOS 開發問題集錦

閱讀原文 EAS BOS 開發問題集錦 寧波-呆呆

1:二次開發後,EAS的執行機制
2:UI類常用方法說明
3:如何讓表頭的欄位在單據提交後還能進行修改?
4:如何修改F7欄位所關聯的基礎檔案
5:如何給F7控制元件設定過濾條件
6:如何通過IObjectPK pk獲取實體物件
7:如何通過實體物件的id獲取實體物件
8:BOTP自定義公式解決方案
9:在自定我Java類中,引用系統日誌的方法
10:EAS-BOS專案路徑變更的方法
11:部署時提示版本不一致的解決辦法
12:如何獲取當前使用者
13:如何增加F7介面上的過濾條件
14:訪問應用伺服器[server1,127.0.0.1:6888]時,使用者名稱[admin]認證失敗!
15:如何獲得BOSType
16:如何新增第3方jar包
17:bos登陸客戶端顯示沒有許可
18:手動新增合計行
1. 程式碼方式處理
2. bim設計處理
19:bos儲存後自動退出
20:遮蔽分錄雙擊排序功能
21:獲取單元格顯示的值
22:合併這兩個EntityViewInfo
23:指定F7對欄位排序
24:標準產品如何擴充套件類以便重寫方法
25:如何讓編輯介面一開啟就是最大化
26:去掉匯出Excel右鍵選單
27:設定是否在調入列表介面之前先出過濾框
28:隱藏EditUI上面板上的新增行刪除行的按鈕
29:特殊資料授權開發
30:多頁籤切換事件
31:通過實體獲取表名
32:table空白行也儲存
33:組織切換(app下程式碼處理)
34:禁用分錄按鈕(新增,刪除,插入)
35:系統的組織隔離
36:獲取記賬委託組織
37:F7多選並儲存資料
38:通過人員獲取職位
39:通過使用者獲取對應組織是否有對應名稱許可權
40:在有分錄的單據ListUI中,點選“關聯生成”後,可不可以實現選中一條記錄就生成包含所有分錄的目標單據?
41:用業務建模工具新定義的單據如何跟許可權管理整合起來?
42:單據和基礎資料是如何做組織隔離的及其他
43:指定單據業務屬性(即主業務組織)有什麼意義?體現在哪裡?
44:知道一個OrgUnitInfo,如何獲取此info下面的子OrgUnitInfo?
45:在程式中給F7增加過濾引數,發現有組織隔離的F7,比如養戶檔案,得到F7的Filter後增加一個FilterItemInfo條件,除錯的時候沒有看到我加的條件,只看到了框架做的組織隔離的條件?(適用於序時簿的過濾)
45:做過組織隔離的F7進行再過濾在實現類建構函式裡新增如下程式碼(適用於編輯介面)
46:getCurrentFIUnit()和getCurrentOrgUnit()之間的區別?
47:如何在BIM中新增圖片
48:獲取當前視窗的工作狀態(新增、修改或檢視)
49:在listui 中,有個小數字段,我在EDITUI中錄入0時,儲存後在LISTUI中顯示為空,而不是0,請問怎麼讓他顯示出來?
50:我想讓一個EditUI的分錄不能新增行,已經把新增行的按鈕什麼的都去掉了,但在分錄的最後一列按回車,table還是會自動新增一行。請問怎麼遮蔽掉?
51:多分錄單據如何重新整理editData?
52:如果我想通過程式碼取物料中的“多計量單位”的記錄,請問怎麼實現?
53:oracle 外來鍵查詢語句
54:單據經過審批以後,需要把稽核人寫到單據裡,應該怎麼做
55:請問分錄是如何過濾的
56: 通過編號更新EAS使用者密碼
57:分錄新增預設值
58:獲取當前線上使用者數
59:根據職員獲取職位和職稱
60:KDTable 表示式應用工具類
61:客戶F7 物料F7 左樹右表
62:EAS BOS 服務端直接呼叫BOTP
63:進度條(沒有百分比)
64:手動儲存botp關係
65: F7專用選擇介面的設定
66:手工傳送訊息
67:EAS KDTABLE 虛模式分頁
68:KDSpinner控制元件選擇
69:KDTable常用程式碼
70:採購入庫單BOTP生成應付單控制是否反寫成本
71:報表新增合計行和每行合計
72:bean根據編碼規則獲取編號
73:F7多選擇儲存
74:如何通過程式碼將query資料進行查詢資料
75:手動重新整理EditUI
76:EAS系統日誌及說明
77:在分錄上新增按鈕
78:在APP下呼叫儲存過程
79:刪除已釋出流程指令碼
80:二次開發的目錄在子系統樹中沒有正確顯示
81:EAS查詢大資料量中斷問題

1:二次開發後,EAS的執行機制

(以下說明只適合於BOS6.1以後版本)

BOS檢視目錄說明:MMEAS:EAS解決方案目錄

metadata:二次開發元資料存放目錄

basemetas:標準產品元資料存放目錄

在BOS開發平臺中,當在basemetas目錄下雙擊某一個元資料檔案時,BOS會自動幫我們生成該元資料的一份拷貝到metadata目錄下,二次開發如果需要修改元資料,就到metadata目錄下修改。 EAS在執行時,會優先載入metadata目錄下的元資料。(注:若刪除metadata目錄下修改過的元資料,EAS會自動載入basemetas目錄下標準產品的元資料,因此在開發過程中,如果metadata目錄下的元資料檔案改亂了,可大膽將其刪除)。

Java檢視目錄說明: 在BOS檢視對元資料進行釋出後,BOS平臺會在Java檢視生成相應的.java檔案。此時,開發者可以通修改相關的java檔案進行二次開發的工作。注意:二次開發所做的修改,要儘量避免與產品打補丁產生衝突。

2:UI類常用方法說明

方法:onLoad()
說明:UI第一次載入時呼叫,通常用於單據第一次初始化時對單據進行相關屬性的操作,注意,當在UI介面開啟後,再點 “新增按鈕”,此時是不執行此方法的。

方法:actionAddNew_actionPerformed(ActionEvent arg0)
說明:點選單據上的“新增”按鈕時觸發的事件。

方法:verifyInput(ActionEvent e)
說明:驗證輸入內容

方法:applyDefaultValue(IObjectValue iobjectvalue)
說明:對錶頭的欄位設定預設值時,重寫此方法

方法:getSelectors()
說明:

方法:*_dataChanged(DataChangeEvent e)
說明:單據上某一欄位的值改變時,觸發此方法

方法:storeFields()
說明:

方法:actionRec_actionPerformed(ActionEvent e)
說明:

方法:applyDefaultValue(IObjectValue iobjectvalue)
說明:

方法:public void verifyInput(ActionEvent actionevent)
說明:驗證

3:如何讓表頭的欄位在單據提交後還能進行修改?

一般情況下,單據提交後,是不允許修改的。但是也存在一些特殊的情況,需要在工作流中,對單據中的某些欄位進行修改,此時,一般是通過在自定義的UI擴充套件類中,重寫onLoad()方法,然後在方法中呼叫控制元件的setEnabled()、setEditable()、setReadOnly()方法(這三個方法不一定需要全部呼叫,根據具體情況而定),如下程式碼:

@Override
public void onLoad() throws Exception {
super.onLoad();
//單據未生成憑證之前,”收款型別”為可編輯、“往來戶”也可編輯
boolean hasFV = this.editData.isFiVouchered();
if(!hasFV){
//收款型別
f7RecBillType.setEnabled(true);
f7RecBillType.setEditable(true);
f7RecBillType.setReadOnly(false);
//往來戶
prmtPayer.setEnabled(true);
prmtPayer.setEditable(true);
prmtPayer.setReadOnly(false);
}
}
4:如何修改F7欄位所關聯的基礎檔案

在一般情況下,在BIM檢視對單據新增F7欄位時,就可以關聯到想要的基礎檔案或其它檢視。但是,當需要關聯一些不存在業務單元(即*.bizunit檔案)的基礎檔案時(如:自定義核算專案)。此時就只能通過以下步驟來處理:

在BIM里加一個F7欄位,關聯物料或其他可以選到的基礎資料。儲存後先別釋出
切換到BOS透檢視,打到對應的.relation檔案,修改supplierEntity,原來是指定物料的實體,改成自定義核算專案的實體
開啟XXXEditUI.ui,修改F7欄位的queryInfo,原來是指向物料的query,改成自定義核算專案的query
5:如何給F7控制元件設定過濾條件

當需要對F7控制元件所打個檢視中的內容進行過濾時,可對F7控制元件設定過濾條件,使用方法如下:

EntityViewInfo evi = new EntityViewInfo(); //建立實體檢視
FilterInfo f = new FilterInfo();//建立過濾物件
FilterItemInfo filter1 = new FilterItemInfo("number", "SHFL001", CompareType.GREATER);//建立第一個過濾條件,第一個引數:所查詢的實體的屬性,第二個引數:屬性的目標值,第三個引數:比較符
FilterItemInfo filter2=  new FilterItemInfo("age", "20", CompareType.GREATER);//建立第二個過濾條件
f.getFilterItems().add(filter1);//將過濾條件新增到過濾物件中
f.getFilterItems().add(filter2);
f.setMaskString("#0 or #1");//設定兩個過濾條件之間的關係
evi.setFilter(f);//設定實體檢視的過濾器
f7.setEntityViewInfo(evi);//將實體檢視繫結到F7控制元件
f7 .getQueryAgent().resetRuntimeEntityView();

6:如何通過IObjectPK pk獲取實體物件

IObjectPK是一個表示實體物件id的物件,在日常開發工作中,經常需要通過它來獲取實體物件。以下是通過IObjectPK獲取實體物件程式碼的模版:

I*Info i*Info = *Factory.getLocalInstance(ctx);
*Info info = i*Info.get*Info(pk);
//以下示例,通過IObjectPK獲取成本物件實體:CostObjectInfo
ICostObject iCostInfo = CostObjectFactory.getLocalInstance(ctx);
CostObjectInfo coi = iCostInfo.getCostObjectInfo(pk);
7:如何通過實體物件的id獲取實體物件

//如下程式碼,通過應收單的id號,獲取應收單表體實體

String entityID =”dsfarlewkrjewrojafad”;
//BOSUuid uid = BOSUuid.create(entityID);
IObjectPK opk = new ObjectUuidPK(entityID);
OtherBillentryInfo obi = OtherBillentryFactory.getRemoteInstance().getOtherBillentryInfo(opk);
8:BOTP自定義公式解決方案

注意:只適用於EASBOS530或以上版本

一、業務場景: 執行時BOTP的公式平臺提供的函式較少,如果要實現比較複雜的邏輯,譬如通過物料編碼從其他單據取出對應數量,執行時的公式平臺就顯得捉襟見肘了。對於客戶開發的單據,可以通過寫程式碼實現。但是對於標準產品的單據,如果反編譯程式碼,則升級時相當麻煩。而自定義公式方案正是為了解決此難題而生。它可以通過寫程式碼在BOTP公式平臺掛上自定義的公式,公式內容由程式設計師自由決定,而不會受升級影響。

二、原理:(業務人員只需重點關注步驟3、4、5)

1.在BOS自定義一個類,實現com.kingdee.bos.service.formula.api.IFormulaFunctions介面。(該類必須位於com.kingdee.bos.service.formula.api此包下,因為要引用此包裡的非公共類) 類的定義參考如下:

package com.kingdee.bos.service.formula.api;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import com.kingdee.bos.kscript.KScriptException;
/**
* BOTP自定義公式demo
* @author Yang Yihao. Just call me House.
* @date since 2007-9-6
* @Email: [email protected]
*/
public class CustomBTPFunctionDemo implements IFormulaFunctions
{
//用於存放公式的變數
private static Vector funcInfos;

static
{
    //載入類時定義自定義公式
    funcInfos = new Vector();
    //FuncInfo()的第一個引數是公式名,第二個引數是公式所在的分類(可隨便取名),第三個引數是公式的描述資訊(在BOTP公式平臺顯示)
    funcInfos.add(new FuncInfo("helloLiuXun", "HelloWorld", "Wish the 

Telecom project would complete soon.”));
}
/**
* 執行時BOTP公式平臺載入自定義公式時,就是從該返回值裡取公式的名稱的
* @author Yang Yihao. Just call me House.
* @date since 2007-9-6
* @Email: [email protected]
* @return 所有自定義公式的名稱
*/
public String[] getAllFuncNames()
{
String as[] = new String[funcInfos.size()];
for(int i = 0; i < funcInfos.size(); i++)
as[i] = ((FuncInfo)funcInfos.get(i)).funcName;
return as;
}
/**
* 執行時BOTP公式平臺載入自定義公式時,就是從該返回值裡取公式的分類的(看運
行時的介面就很好理解)
* @author Yang Yihao. Just call me House.
* @date since 2007-9-6
* @Email: [email protected]
* @param s
* @return
*/
public String getFuncCategory(String s)
{
if(s == null)
return null;
for(int i = 0; i < funcInfos.size(); i++)
if(s.equals(((FuncInfo)funcInfos.get(i)).funcName))
return ((FuncInfo)funcInfos.get(i)).funcCategory;
return null;
}
/**
* 獲取公式的描述
* @author Yang Yihao. Just call me House.
* @date since 2007-9-6
* @Email: [email protected]
* @param s
* @return
*/
public String getFuncDesc(String s) {
if(s == null)
return null;
for(int i = 0; i < funcInfos.size(); i++)
if(s.equals(((FuncInfo)funcInfos.get(i)).funcName))
return ((FuncInfo)funcInfos.get(i)).funcDesc;
return null;
}
public boolean existFunction(String s)
{
if(s == null)
return false;
for(int i = 0; i < funcInfos.size(); i++)
if(s.equals(((FuncInfo)funcInfos.get(i)).funcName))
return true;
return false;
}
/**
* 執行公式時呼叫此方法,公式的具體邏輯就寫在這裡
* @author Yang Yihao. Just call me House.
* @date since 2007-9-6
* @Email: [email protected]
* @param func 公式名稱
* @param paramList 公式的引數
* @return 公式結果
* @throws KScriptException
*/
public Object evalFunction(String func, List paramList) throws
KScriptException
{
//判斷使用者是選了哪個公式
if(func != null && func.equals(“helloLiuXun”))
{
//這裡可以寫滿足各式各樣需求的程式碼
if(paramList != null && paramList.size() > 0)
{
StringBuffer sb = new StringBuffer(10);
for(Iterator iter = paramList.iterator(); iter.hasNext();)
{
sb.append(iter.next()).append(“,”);
}
return sb.toString();
}
else
return “Congratulations”;
}
return “TheEnd”;
}
}

2.在BOTP目標單據的實體(entity)上加上擴充套件屬性“billFormulaClass”,屬性值設為第1步建立的類的全名(含包名)。如下圖:

(注意:此 擴充套件屬性 要在 表頭實體 的 基礎資訊 頁籤中新增,表體實體是不存在billFormulaClass這個擴充套件屬性的)

3.執行時,在BOTP規則設定的“公式平臺”->“公式元素”->“函式”頁籤裡可以看到自定義的函式

helloLiuXun()就是自定義公式。

4.設定BOTP公式的格式如下:

引數用半形雙引號括起來,可以傳多引數,引數間用半形逗號隔開。 5.恭喜,令人興奮的結果完全滿足你個性化的需求!

9:在自定我Java類中,引用系統日誌的方法

import org.apache.log4j.Logger;

// 獲取寫日誌的物件
private static Logger logger = Logger.getLogger(“com.kingdee.eas.custom.gz.bd.app.BizTypeGZControllerBean”);
//寫日誌
logger.info(e.getMessage());

10:EAS-BOS專案路徑變更的方法

拷貝工作區的時候,會出現目錄變更,在釋出專案是,會出現啟動ear失敗情況,如下錯誤:

[apusic.service.J2EEDeployer] 啟動應用 ‘eas.ear’ 失敗。
com.apusic.deploy.runtime.InvalidModuleException: 模組檔案 ‘D:\zgh\Project\gz\eTianxia\workspace\EWorld\runtime\server\deploy\eas.ear’ 不存在。
EAS-BOS專案路徑變更的方法:

  1. 修改: ProjectPath \runtime\server\profiles\server1\config\bosconfig.xml
    `
  2. 修改 ProjectPath \runtime\server\profiles\server1\config\licensefile.xml
    D:\workspace\EWorld\runtime\server\profiles\server1\config\licenses\license
  3. ProjectPath \runtime\server\profiles\server1\config\portalConfig\easWebConfig.xml

  4. 修改 ProjectPath \EWorld\runtime\apusic\config\server.xml



    11:部署時提示版本不一致的解決辦法

從伺服器的目錄:如: D:\Kingdee\eas\server\propertiesCopy檔案eascomponents.xml
到部署機的目錄:
如:E:\workspace\mmeas(具體名稱根據你的專案名而定)

12:如何獲取當前使用者

在UI擴充套件類中,獲取當前使用者可通過工具類SysContext
如:SysContext.getSysContext().getCurrentUserInfo()
在ControlerBean的擴充套件類中,獲取當前使用者可通過工具類ContextUtil
如:ContextUtil.getCurrentUserInfo(ctx)
關於SysContext和ContextUtil這兩個工具類中方法的介紹:
這兩個類是EAS的全域性工具類,用於獲取當前使用者資訊,當前組織單元資訊、客戶端IP、客戶端名字等資訊。SysContext用於客戶端,如UI擴充套件類中;而ContextUtil用於服務端,如ControllerBean擴充套件類中。

13:如何增加F7介面上的過濾條件

找到F7介面所對應的Query後,選擇欄位頁籤,找對應的屬性?擴充套件屬性:增加“是否在通用過濾中顯示”的擴充套件屬性,並將其值設定為true。重新發布。

14:訪問應用伺服器[server1,127.0.0.1:6888]時,使用者名稱[admin]認證失敗!

請檢查部署應用時配置的的使用者名稱及密碼是否能正常登入應用伺服器的管理頁面。

如果不能登入,請首先應用伺服器的管理控制檯建立使用者;
或者重新部署應用,修改部署嚮導配置的使用者名稱/密碼為合法值。
異常堆疊:
com.kingdee.eas.tools.admin.domain.exception.AppServerLoginFailedException: Authentication denied,the user name and/or password is not valid!
at com.kingdee.eas.tools.admin.domain.impl.EASServerServiceImpl.startApplicationServer(EASServerServiceImpl.java:913)
at com.kingdee.eas.tools.admin.domain.impl.EASServerServiceImpl.startApplicationServer(EASServerServiceImpl.java:719)
上述提示的方案好像有點問題,我另找了一個解決辦法:
進入%Apusic_home%\domains\server1\store,將users.db檔案刪除,重啟應用伺服器,即可恢復admin密碼為初始密碼。

15:如何獲得BOSType

開啟*.entity實體檢視。切換到“原始碼”標籤,找到48DA3A71。這就是該實體所對應的BOSType了
或者java程式碼:

BOSObjectType objectType = objectValue.getBOSType();
16:如何新增第3方jar包

1、在專案中切換到 java檢視 選擇專案工程右鍵 >構建路徑>配置構建路徑
2、將jar包分別Copy到以下路徑

用於BOS使用
\workspacewm\wmnew\lib\client\trd
\workspacewm\wmnew\lib\server\trd

部署路徑
/kingdee/eas/server/deploy/fileserver.ear/easWebClient/lib/client/trd /kingdee/eas/server/deploy/fileserver.ear/easWebClient/deploy/client
/kingdee/eas/server/lib/server/trd
/kingdee/eas/server/lib/client/trd

17:bos登陸客戶端顯示沒有許可

原因:bos工具自帶eas license沒有對應模組許可導致。
解決方法:將eas7.0安裝包中自帶eas 的license檔案替換到bos工具如下路徑即可, \bim\eclipse\plugins\com.kingdee.bos.bim_template_6.1.0\templates\licenses PS:license檔名必修改成“license”字樣才可 就把licenses PS:license檔案放到相同路徑。檔名為license

18:手動新增合計行

  1. 程式碼方式處理

//新增合計欄
KDTFootManager footmgr = new KDTFootManager(kdtE2);
footmgr.addFootView();
kdtE2.setFootManager(footmgr);
kdtE2.addFootRow(0);
IRow row = footmgr.getFootRow(0);
row.getCell(0).setValue(“合計:”);

//設定合計欄位(重視父類方法)
protected void setTableToSumField() {
setTableToSumField(kdtE1, new String[] { “ContractAmount” });
super.setTableToSumField();
}

完整程式碼

IRow row = tblMain.addRow();
row.getStyleAttributes().setBackground(new Color(236, 255, 255));
row.getCell(0).setValue(“合 計 欄 :”);
row.getStyleAttributes().setBold(true);
row.getStyleAttributes().setFontColor(Color.RED);

    BigDecimal sum1 = new BigDecimal("0.00"),sum2 = new BigDecimal("0.00");
    BigDecimal sum3 =new BigDecimal("0.00"),sum4=new BigDecimal("0.00");

    for (int i=0;i<tblMain.getRowCount();i++) {
        //合計最後倆欄
        if (tblMain.getCell(i, 1).getValue()!=null && 
                !tblMain.getCell(i, 1).getValue().equals("")) {
            tblMain.getCell(i, 1).setValue(((BigDecimal)tblMain.getCell(i, 1).getValue()).setScale(2));
            sum1 = sum1.add((BigDecimal)tblMain.getCell(i, 1).getValue());
        }

        if (tblMain.getCell(i, 2).getValue()!=null && 
                !tblMain.getCell(i, 2).getValue().equals("")) {
            tblMain.getCell(i, 2).setValue(((BigDecimal)tblMain.getCell(i, 2).getValue()).setScale(2));
            sum2 = sum2.add((BigDecimal)tblMain.getCell(i, 2).getValue());
        }
    }
    row.getCell(1).setValue(sum1.setScale(2));
    row.getCell(2).setValue(sum2.setScale(2));
  1. bim設計處理

ListUI所繫結的Query欄位頁籤設定兩個擴充套件屬性

是否統計欄位:true
統計欄位按主鍵進行統計:設定為主鍵欄位名,比如(id,entrys.id),如果不設定的話,統計的時候會按分錄行統計,對非分錄行統計出來的結果會不正確。

在ListUI.java中重寫isFootVisible方法,將返回值設定為true。
@Override
protected boolean isFootVisible() {
// TODO Auto-generated method stub
return true;
}
19:bos儲存後自動退出

我猜到可能是JVM記憶體的問題,於是找到exlipse.ini,修改為:
Eclipse.ini 路徑:D:\kingdee\EASStudio\bos\BOSModular\platform\eclipse
-vmargs
-Xms128M
-Xmx512M
-XX:PermSize=64M
-XX:MaxPermSize=128M

20:遮蔽分錄雙擊排序功能

this.kdtEntrys.removeKDTMouseListener(this.kdtEntrys.getSortMange());//所有列
tblMain.getColumn(i).setSortable(false); //單個
21:獲取單元格顯示的值

detailTable.getCellDisplayText(cell);
22:合併這兩個EntityViewInfo

EntityViewInfo view1 = new EntityViewInfo();
EntityViewInfo view2 = new EntityViewInfo();
view1.getFilter().mergeFilter(view2.getFilter(), “and”);
23:指定F7對欄位排序

SorterItemCollection sorter = new SorterItemCollection();
SorterItemInfo sortinfo = new SorterItemInfo();
sortinfo.setPropertyName(“屬性名稱”);
sortinfo.setSortType(SortType.DESCEND);
EntityViewInfo entityInfo = new EntityViewInfo();
entityInfo.setSorter(sorter);
my_PromptBox.setEntityViewInfo(entityInfo);
24:標準產品如何擴充套件類以便重寫方法

對於客戶端的UI類,無論是listUI,還是EditUI,都可以在通過追加字尾名CTEx的方式來擴充套件。如要重寫標準產品採購訂單的儲存方法: com.kingdee.eas.scm.sm.pur.client.PurorderEditUI,在實際二次開發中,釋出之後只會生成com.kingdee.eas.scm.sm.pur.client.AbstractPurorderEditUI,如果要重寫儲存的方法,則可以在com.kingdee.eas.scm.sm.pur.client包下新建PurorderEditUICTEx,此類繼承PurorderEditUI類即可,然後在PurorderEditUICTEx重寫儲存方法。
服務端的擴充套件,主要是對bean的擴充套件,有兩種方法
方法1.
1、在bim裡面找到對應的業務單據XXX,開啟“業務單元->功能”,新建一功能,然後釋出。
2、切換到java檢視,可以找到剛才的業務單據的XXXControllerBeanEx。
3、在XXXControllerBeanEx中覆蓋對應的方法即可。
方法2.
新建一擴充套件類如:TestControllerBeanEx,然後在文字開啟實體元資料,增加一擴充套件屬性





注意上面的寫法[com.kingdee.eas.custom.app.Test]中的”Test”是TestControllerBeanEx的controllerBeanEx前面的Test,可以參考該實體檔案的其他的屬性
<rs ….> … </rs>

備註
客戶端的擴充套件針對行業版提供的是PIEx,為了不影響產品的後續維護,針對客戶的客戶端UI擴充套件務必使用字尾CTEx。

25:如何讓編輯介面一開啟就是最大化

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setPreferredSize(screenSize);
26:去掉匯出Excel右鍵選單

public void addCommonMenusToTable(KDTable table) {
super.addCommonMenusToTable(table);
PopupMenuManager mgr = getPopupMenuManager(table);
mgr.removeMenuSection(“export”);
}
27:設定是否在調入列表介面之前先出過濾框

protected boolean initDefaultFilter() {
return true;
}
28:隱藏EditUI上面板上的新增行刪除行的按鈕

this.kdtPaymentInfoEntry_detailPanel.getAddNewLineButton().setVisible(false); this.kdtPaymentInfoEntry_detailPanel.getInsertLineButton().setVisible(false); this.kdtPaymentInfoEntry_detailPanel.getRemoveLinesButton().setVisible(false);
29:特殊資料授權開發

一, 首先需要單據支援特殊資料許可權,具體開發步驟如下:

許可權項繫結實體,。
許可權項的是否支援資料許可權為“是”
在${EAS_HOME}/server/profiles/server*/config/EAS_PermissionConfiguration.xml配置檔案中增加單據實體,新增方式如下:

com.kingdee.eas.fi.gl.app.Voucher
2652E01E

釋出,部署,重啟服務,同步許可權項。
在特殊資料許可權介面找到單據勾選上擁有者有權和主管許可權,此時單據只能由制單人和自己的上級主管檢視。如果要其他人檢視則在指定主管中選擇相應的人員和要檢視的部門
30:多頁籤切換事件

panel_componentShown //事件。當頁籤切換時間。呼叫這方法
this.kDTabbedPane1.setSelectedIndex(0); //指定顯示第一個頁籤
31:通過實體獲取表名

MetaDataLoaderFactory.getRemoteMetaDataLoader().getEntity(info.getId().getType()).getTable();
32:table空白行也儲存

kdtable.getRow(i).setChange(true);
33:組織切換(app下程式碼處理)

OrgSwitchFacadeFactory.getLocalInstance(ctx).orgSwitch(company.getId().toString());
34:禁用分錄按鈕(新增,刪除,插入)

/**
* 禁用分錄按鈕
* @param table
*/
public static void disableHMDEntryButtons(KDTable table) {
if (table.getParent() == null || table.getParent().getParent() == null)
return;
// 隱藏按鈕
Component c = table.getParent().getParent();
if (c instanceof DetailPanel) {
JPanel panel = (JPanel) c;
JPanel controlPanel = null;
// 獲得controlPanel
Component[] components = panel.getComponents();
for (int i = 0; i < components.length; i++) {
Component component = components[i];
if (“controlPanel”.equals(component.getName())) {
controlPanel = (KDPanel) component;
}
}
// 獲得btn
if (controlPanel != null) {
components = controlPanel.getComponents();
for (int j = 0; j < components.length; j++) {
Component component = components[j];
if (component instanceof KDWorkButton) {
KDWorkButton workButton = (KDWorkButton) component;
workButton.setEnabled(false);
}
}
}
}
}

}

final KDTable kddetailTable=getDetailTable();

Container con =kddetailTable.getParent().getParent();

if (con instanceof DetailPanel) {
DetailPanel detail =(DetailPanel)con;

KDWorkButton btnadd= detail.getAddNewLineButton();
35:系統的組織隔離

FilterInfo otherFilter = com.kingdee.eas.framework.FrameWorkUtils.getF7FilterInfoByAuthorizedOrg(com.kingdee.eas.basedata.org.OrgType.getEnum(“Admin”),”OrgUnit.id”,true);
36:獲取記賬委託組織

IOrgUnitRelation iOrgUnitRelation = OrgUnitRelationFactory.getLocalInstance(ctx);
iOrgUnitRelation.getToUnit(storageOrgUnit1.getId().toString(), OrgType.STORAGE_VALUE, OrgType.COMPANY_VALUE);
37:F7多選並儲存資料

設定F7開戶多選功能,F7.setEnabledMultiSelection(true);
除了F7本身欄位以外,再新增兩個文字欄位,F7Name(用於ListUI查詢用),F7ID(用於儲存多選值),F7自身是不儲存資料值的
在F7_dataChanged方法裡把F7多選到的值分別賦值到F7Name,F7ID中,例:
protected void f7_dataChanged(
com.kingdee.bos.ctrl.swing.event.DataChangeEvent e) {
Object[] F7cols = (Object[]) e.getNewValue();
if (null == F7cols) {
txtF7Name.setText(null);
txtF7ID.setText(null);
SysUtil.abort();
}
StringBuilder f7id = new StringBuilder();
StringBuilder f7Name = new StringBuilder();
for (int i = 0; i < F7cols.length; i++) {
OperationTypeInfo info = (OperationTypeInfo) kOperationType[i];
String idString = info.getId().toString();// 業務類別
operationTypeid.append(idString).append(“;”);
operationTypeName.append(info.getNumber()).append(“-“).append(info.getName()).append(“;”);
}
String operationTypeidValue = operationTypeid.toString();
if (!StringUtils.isEmpty(operationTypeidValue)) {
operationTypeidValue = operationTypeidValue.substring(0,
operationTypeidValue.length() - 1);
txtF7ID.setText(operationTypeidValue);
}
String operationTypeNameValue = operationTypeName.toString();
if (!StringUtils.isEmpty(operationTypeNameValue)) {
operationTypeNameValue = operationTypeNameValue.substring(
0, operationTypeNameValue.length() - 1);
txtF7Name.setText(operationTypeNameValue);
}
}
在資料載入的時候,把資料通過ID再解析出來賦值給F7欄位 一定要先super.loadFields,再設計f7欄位為多選功能,否則這裡儲存出來的值是記憶體地址
public void loadFields() {
// 載入
super.loadFields();
f7.setEnabledMultiSelection(true);
String operationTypeID = editData.getOperationTypeID();

    if (!StringUtils.isEmpty(operationTypeID)) {
        String[] operationType = operationTypeID.split(";");
        StringBuilder sbBuilder = new StringBuilder();
        EntityViewInfo evi = new EntityViewInfo(); // 建立實體檢視
        FilterInfo f = new FilterInfo();// 建立過濾物件
        for (int i = 0; i < operationType.length; i++) {
            FilterItemInfo filter1 = new FilterItemInfo("id",
                    operationType[i], CompareType.EQUALS);
            f.getFilterItems().add(filter1);// 將過濾條件新增到過濾物件中
            sbBuilder.append("#").append(i).append(" ").append("or ");
        }
        String maskString = sbBuilder.toString();
        if (!StringUtils.isEmpty(maskString)) {
            maskString = maskString.substring(0, maskString.length() - 3);
            f.setMaskString(maskString);
            evi.setFilter(f);// 設定實體檢視的過濾器
            try {
                IOperationType instance = OperationTypeFactory.getRemoteInstance();
                OperationTypeCollection collection = instance.getOperationTypeCollection(evi);
                int size = collection.size();
                Object[] infoObjects=new Object[size];
                for (int i = 0; i < size; i++) {
                    infoObjects[i]=collection.get(i);
                }
                f7.setData(infoObjects);
            } catch (BOSException e) {
                e.printStackTrace();
            }
        }
    }

38:通過人員獲取職位

PositionInfo getPositionByPerson(Context ctx,PersonInfo info)throws EASBizException, BOSException
{
EntityViewInfo view = new EntityViewInfo();
SelectorItemCollection sic = new SelectorItemCollection();
sic.add(new SelectorItemInfo(“id”));
sic.add(new SelectorItemInfo(“person.id”));
sic.add(new SelectorItemInfo(“person.name”));
sic.add(new SelectorItemInfo(“person.number”));
sic.add(new SelectorItemInfo(“position.id”));
sic.add(new SelectorItemInfo(“position.number”));
sic.add(new SelectorItemInfo(“position.name”));
sic.add(new SelectorItemInfo(“position.job.id”));
sic.add(new SelectorItemInfo(“position.job.number”));
sic.add(new SelectorItemInfo(“position.job.name”));

        view.setSelector(sic);
        FilterInfo filter = new FilterInfo();
        filter.getFilterItems().add(new FilterItemInfo("person.id", info.getId() + ""));
        filter.getFilterItems().add(new FilterItemInfo("isPrimary", new Integer(1)));
        view.setFilter(filter);
        PositionMemberCollection col = PositionMemberFactory.getLocalInstance(ctx).getPositionMemberCollection(view);

        if ((col != null) && (col.size() > 0) && (col.get(0) != null)) {
            return col.get(0).getPosition();
        }

    return null;
}

39:通過使用者獲取對應組織是否有對應名稱許可權

boolean flag=false;
BOSUuid userId=SysContext.getSysContext().getCurrentUserInfo().getId();
BOSUuid orgId=SysContext.getSysContext().getCurrentOrgUnit().getId();
ObjectUuidPK userPK = new ObjectUuidPK(userId);
ObjectUuidPK orgPK = new ObjectUuidPK(orgId);
com.kingdee.eas.base.permission.IPermission perm= null;
//獲取許可權
try {
perm =PermissionFactory.getRemoteInstance();
flag=perm.hasFunctionPermission(userPK, orgPK, “許可權名稱”);
} catch (Exception e1) {
e1.printStackTrace();
}
40:在有分錄的單據ListUI中,點選“關聯生成”後,可不可以實現選中一條記錄就生成包含所有分錄的目標單據?

如果想根據單據頭做botp轉換,需要自己在單據的序時簿程式碼中新增 相關的程式碼設定,程式碼參考:

public void actionCreateTo_actionPerformed(ActionEvent e) throws Exception
{
setDAPTrans(true);
super.actionCreateTo_actionPerformed(e);
setDAPTrans(false);
}
41:用業務建模工具新定義的單據如何跟許可權管理整合起來?

新定義的單據,在沒有做許可權管理之前,是不受許可權控制的。 將新單據跟許可權管理整合起來,大致分為三個步驟:

【工具】>【許可權管理】,在此介面定義單據所在的目錄及給單據設定各種許可權項(檢視、新增、修改、刪除、稽核等)。如果沒有新建某種許可權項,則預設此種許可權項不受控制,是可以在任何情況下 使用的。—–這只是加了許可權項,但是並沒有應用到單據中。
要應用到單據中,必須在主選單管理中給業務單元加上相應的許可權項,然 後釋出,這是設計期要做的工作。
在執行期時,通過administrator登入,在“使用者管理”裡同步許可權項?分配相應的許可權即可
42:單據和基礎資料是如何做組織隔離的及其他

假如BIM中定義了一個主業務組織是採購組織的單據,那麼: 序時簿的過濾:

首先到使用者的組織範圍中查詢使用者有哪些組織的許可權;
再找出使用者的組織範圍中的組織有哪些是採購組織; (例如使用者的組織範圍中可能有A、B、C三個組織,但是A是財務組織,B、C是採購組織,那麼必 須把A給過濾掉);
功能許可權的過濾,看看使用者對當前單據有沒有檢視的許可權
看看篩選出來的B和C這兩個採購組織是不是實體,如果不是採購組織實體,那麼也必須過濾掉; 編輯介面的過濾:
使用者設定了單據的主業務組織是採購組織,則在單據的介面上應該動態加一個F7型別的欄位“採購組 織”
該“採購組織”必須是必錄的、可修改的
該”採購組織”的過濾條件參照序時簿的條件1、2、4
43:指定單據業務屬性(即主業務組織)有什麼意義?體現在哪裡?##

指定當前單據的業務屬性可以控制當前登入使用者的訪問許可權,比如,單據Test的業務屬性為庫存組織,當前登入使用者的組織範圍有采購組織,財務組織,行政組織,由於此使用者沒有庫存組織的許可權,所以訪問不到這個單據。

44:知道一個OrgUnitInfo,如何獲取此info下面的子OrgUnitInfo?##

找OrgUnitInfo的長編碼欄位longNumber,他們是由!隔開的,這裡可以找到所有ou的編碼資訊。

45:在程式中給F7增加過濾引數,發現有組織隔離的F7,比如養戶檔案,得到F7的Filter後增加一個FilterItemInfo條件,除錯的時候沒有看到我加的條件,只看到了框架做的組織隔離的條件?(適用於序時簿的過濾)##

過載方法:

protected FilterInfo getDefaultFilterForQuery()
{
FilterInfo info =super.getDefaultFilterForQuery();
FilterInfo info1 = new FilterInfo();
info.merge(info1,”AND”);
}
45:做過組織隔離的F7進行再過濾在實現類建構函式裡新增如下程式碼(適用於編輯介面)##

EntityViewInfo evInfo = new EntityViewInfo();
FilterInfo filter = new FilterInfo();
filter.getFilterItems.add(“”,”“); // 加使用者的過濾項
evInfo.setFilter(filter);
F7PromptControl.setEntityViewInfo(evInfo);
46:getCurrentFIUnit()和getCurrentOrgUnit()之間的區別?##

如果我當前登入的組織是庫存組織, getCurrentFIUnit()是不是就會找當前組織的上一級財務組織單元?其他的 getCurrentCtrlUnit(), getCurrentAdminUnit(), getCurrentCostUnit()等是否也是這個原理?

getCurrentFIUnit就是取當前財務組織,一般用於財務型別的單據; getCurrentOrgUnit是取當前的業務組織,適用於所有單據; getCurrentFIUnit()是指去當前登入使用者所對應的財務組織; 同理:getCurrentCtrlUnit()、getCurrentAdminUnit()、getCurrentCostUnit()分別指當前使用者所切換組織所對應的CU,行政組織,成本組織。

47:如何在BIM中新增圖片##

在業務單元定義介面增加一個標籤型別欄位,如為:TestImage,則對應的標籤控制元件名為:lblTestImage,再如業務單元名為:TestBill,則在TestBillEditUI.java中的的建構函式中的Super()語句下新增

public TestBillEditUI() throws Exception
{
super();
this.lblTestImage.setIcon(new javax.swing.ImageIcon(“E:\Images\testimage.jpg”));
}
下面為完整Demo

public class SingleEnrollEditUI extends AbstractSingleEnrollEditUI {
private static final long serialVersionUID = 1525974852523168246L;

private static final Logger logger = CoreUIObject
.getLogger(SingleEnrollEditUI.class);
PhotoPanel pPanel = new PhotoPanel();
private boolean existPhoto;

    /**

* output class constructor
*/
public SingleBillEditUI() throws Exception {
super();
pPanel = new PhotoPanel();
existPhoto = false;
isSave = false;
}

    // 儲存照片

private void storePhotoFile() throws Exception {
if ((pPanel.getSelectFile() != null && pPanel.getSelectImageBytes() != null)
|| pPanel.getSelectImage() != null) {
editData.setImageData(pPanel.getSelectImageBytes());
} else if (existPhoto) {
if (pPanel.getSelectImage() != null) {
editData.setImageData(pPanel.getSelectImageBytes());
} else {
editData.setImageData(null);
}
}
}

public void loadFields() {
super.loadFields();
pPanel.setOprtStat(getOprtState());
try {
this.loadImage();// 載入圖片
} catch (Exception e) {
e.printStackTrace();
}
}

// 初始化圖片顯示區
private void initPhotoPanel() {
pPanel.setOprtStat(“ADD”);
pPanel.setBounds(627, 117, 169, 150);
photoPanel.add(pPanel);
}

// 在非新增狀態下載入已經儲存的圖片
public void loadImage() throws IOException, BOSException {
ISingleBill irentVehicle = SingleBillFactory.getRemoteInstance();
SingleBillInfo rentVehicleInfo = null;
try {
rentVehicleInfo = irentVehicle
.getSingleBillInfo(“select imageData where id =” + “’”
+ this.editData.getId() + “’”);
if (!rentVehicleInfo.isEmpty()) {
if (rentVehicleInfo.getImageData() != null) {
byte[] byteArray = rentVehicleInfo.getImageData();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
byteArray);
BufferedImage bufferedImage = ImageIO
.read(byteArrayInputStream);
pPanel.setSelectImage(bufferedImage);
byteArrayInputStream.close();
pPanel.repaint();
}
}
} catch (ObjectNotFoundException e) {
MsgBox.showInfo(“照片不存在”);
SysUtil.abort();
} catch (EASBizException e) {
e.printStackTrace();
}
}

public void onShow() throws Exception {
// ((JFrame) getUIWindow()).setExtendedState(JFrame.MAXIMIZED_BOTH);
photoPanel.setLayout(null);
photoPanel.add(pPanel);
pPanel.setBounds(0, 0, 109, 152);
super.onShow();
}
}

byte[] bys = (byte[]) list.get(44);
BufferedImage image = ImageIO
.read(new ByteArrayInputStream(bys));
pPanel.setSelectImage(image);
pPanel.repaint();
48:獲取當前視窗的工作狀態(新增、修改或檢視)##

getOprtState().equals(OprtState.ADDNEW);
49:在listui 中,有個小數字段,我在EDITUI中錄入0時,儲存後在LISTUI中顯示為空,而不是0,請問怎麼讓他顯示出來?##

請過載listui裡的getQueryExecutor()方法,然後在語句“super.getQueryExecutor();”後面加上exec.option().isAutoIgnoreZero = false; 用來設定0不轉換為空。

protected IQueryExecutor getQueryExecutor(IMetaDataPK queryPK, EntityViewInfo viewInfo) {
IQueryExecutor executor= super.getQueryExecutor(queryPK, viewInfo);
executor.option().isAutoIgnoreZero=false;
return executor;
}
50:我想讓一個EditUI的分錄不能新增行,已經把新增行的按鈕什麼的都去掉了,但在分錄的最後一列按回車,table還是會自動新增一行。請問怎麼遮蔽掉?##

你在遮蔽“新增分錄”那個按鈕的同時, 呼叫遮蔽table的自動新增行語句disableAutoAddLine();使之不能自動新增行

51:多分錄單據如何重新整理editData?##

呼叫loadData();

52:如果我想通過程式碼取物料中的“多計量單位”的記錄,請問怎麼實現?##

String materialID = “”;//物料ID
EntityViewInfo view = new EntityViewInfo();
FilterInfo filter = new FilterInfo();
filter.getFilterItems().add(new FilterItemInfo(“material.id”,materialID));
view.setFilter(filter);
MultiMeasureUnitCollection units = MultiMeasureUnitFactory.getRemoteInstance().getCollection(view);
53:oracle 外來鍵查詢語句##

只需要把紅色的文字換成相應的要查詢的表名就可以了

select oc.name as “CONSTRAINT_NAME”,
o.name as “TABLE_NAME”,
o1.name as “R_TABLE_NAME”
from sys.con oc,sys.con rc,
sys.obj o,sys.cdef c,
sys.obj o1,sys.cdef c1
where oc.con# = c.con#
and c.obj# = o.obj#
and c.rcon# = rc.con#(+)
and o.owner# = userenv(‘SCHEMAID’)
and c.type# = 4
and rc.con# = c1.con#
and c1.obj# = o1.obj#
and c1.type# = 2
and o1.name = ‘tableName.toUpperCase()’
54:單據經過審批以後,需要把稽核人寫到單據裡,應該怎麼做##

在單據對應的實體里加上方法auditBill(ctx,model),然後在單據生成的對應的controlBean類中在方法auditBill里加上寫稽核人的程式碼,如:

protected void _auditBill(Context ctx, IObjectValue model) throws BOSException {
// TODO 自動生成方法存根
//super._auditBill(ctx, model);
PurReqInfo purReqInfo = null ;
// 進行值物件轉化
purReqInfo = (PurReqInfo)model;
// 獲取當前日期
Date currentDate = new Date();
// 獲取使用者資訊
UserInfo currentUser = (UserInfo) ctx.get(SysContextConstant.USERINFO);
// 設定稽核人
purReqInfo.setAuditor(currentUser);
// 設定單據狀態
// purReqInfo.setState(PurOrderType.Excute);
// purReqInfo.setBizDate(currentDate);

// 更新單據
try {
update(ctx, new ObjectUuidPK(purReqInfo.getId()),purReqInfo);
} catch (EASBizException e) {
// TODO 自動生成 catch 塊
e.printStackTrace();
} catch (BOSException e) {
// TODO 自動生成 catch 塊
e.printStackTrace();
}

}
55:請問分錄是如何過濾的##

分錄的過濾,需要在過濾語句前設定它的分錄型別和名字, 格式如下:

filter.setEntryType(EntryFilterType.NORMAL);
filter.setEntryName(“xxx”)
ps:xxx是分錄的名字

56: 通過編號更新EAS使用者密碼##

protected String _updatePassword(Context ctx, String number, String oldPwd,
String newPwd) throws BOSException {
IUser instance = UserFactory.getLocalInstance(ctx);
UserCollection collection = instance.getUserCollection(“where number=’”+number+”’”);
if (collection.size()>0) {
UserInfo userInfo = collection.get(0);
try {
String strOldPwd = CryptoTean.encrypt(userInfo.getNumber(), oldPwd);
String strNewPwd = CryptoTean.encrypt(userInfo.getNumber(), newPwd);
IObjectPK iObjectPK = new ObjectUuidPK(userInfo.getId().toString());
instance.updatePass(iObjectPK, strOldPwd, strNewPwd);
return “0000|update password is Success.”;

} catch (CryptException e) {
e.printStackTrace();
return “0003|”+e.toString();
} catch (EASBizException e) {
e.printStackTrace();
return “0001|”+e.toString();
}
}else
{
return “9999|number not found user info.”;
}
}
57:分錄新增預設值##

protected IObjectValue createNewDetailData(KDTable table) {
BizContractPayPlanEntryInfo info = new BizContractPayPlanEntryInfo();
info.setAmount(BigDecimal.ZERO);
return info;
}
58:獲取當前線上使用者數##

本文介紹的是在FacadeControllerBean也就是服務端獲取的方法,GUI層面獲取的方法在UserMonitorUI.class裡已有程式碼,請自行檢視;

UMRegistryCollection regs = null;
try {

ILoginModule loginModule = LoginModuleFactory.getLocalInstance(ctx);
String encodePwd = CryptoTean.encrypt(“EAS使用者名稱”, “密碼”);

    //獲取一個使用者登入的上下文物件
     LoginContext loginContext = new LoginContext("EAS使用者名稱", encodePwd, ctx.getSolution(), ctx.getAIS(), ctx.getLocale());  
     loginContext.put("dbType", "Oracle");  
     loginContext.put("UserAuthPattern", "BaseDB");  

     try  
     {  
         String sessionId = loginModule.login(loginContext);  
         ctx = SessionManager.getInstance().getSession(sessionId).getContext();  
     }  
     catch (BOSLoginException e)  
     {  
         e.printStackTrace();  
         throw new BOSException(e.getMessage());  
     }  

regs = ((UMRegistryCollection) UserMonitorFactory.getLocalInstance(ctx).getCollectionUsingOrgRange(
DataCenterName));
} catch (Exception e1) {
e1.printStackTrace();
}
int total = regs.size(); //這個就是總使用者數了,如果要區分出哪些是GUI哪些是PORTAL的,可自行去UserMonitorUIj裡看相關程式碼 ;
59:根據職員獲取職位和職稱##

PositionInfo getPositionByPerson(Context ctx,PersonInfo info)throws EASBizException, BOSException
{
EntityViewInfo view = new EntityViewInfo();
SelectorItemCollection sic = new SelectorItemCollection();
sic.add(new SelectorItemInfo(“id”));
sic.add(new SelectorItemInfo(“person.id”));
sic.add(new SelectorItemInfo(“person.name”));
sic.add(new SelectorItemInfo(“person.number”));
sic.add(new SelectorItemInfo(“position.id”));
sic.add(new SelectorItemInfo(“position.number”));
sic.add(new SelectorItemInfo(“position.name”));
sic.add(new SelectorItemInfo(“position.job.id”));
sic.add(new SelectorItemInfo(“position.job.number”));
sic.add(new SelectorItemInfo(“position.job.name”));

     view.setSelector(sic);
     FilterInfo filter = new FilterInfo();
     filter.getFilterItems().add(new FilterItemInfo("person.id", info.getId() + ""));
     filter.getFilterItems().add(new FilterItemInfo("isPrimary", new Integer(1)));
     view.setFilter(filter);
     PositionMemberCollection col = PositionMemberFactory.getLocalInstance(ctx).getPositionMemberCollection(view);

     if ((col != null) && (col.size() > 0) && (col.get(0) != null)) {
      return col.get(0).getPosition();
     }

return null;
}
60:KDTable 表示式應用工具類##

/**
* 給單元格新增sum表示式
* @param cell
* @param from
* @param to
*/
public static void setCellSumExpr(ICell cell, int from, int to) {
cell.setExpressions(getSumExpr(from, to));
}

 /**
  * 給單元格新增IF表示式
  * @param cell
  * @param condExpr
  * @param expr1
  * @param expr2
  */
 public static void setCellIFExpr(ICell cell,String condExpr,String expr1,String expr2){
     cell.setExpressions(getIFExpr(condExpr, expr1, expr2));
 }

 /**
  * 給單元格新增Add表示式
  * @param cell
  * @param a
  * @param b
  */
 public static void setCellAddExpr(ICell cell,int a,int b){
     cell.setExpressions(getAddExpr(a, b));
 }

 /**
  * 給單元格新增Add表示式,允許不連續區域求和
  * @param cell
  * @param range
  */
 public static void setCellAddRangeExpr(ICell cell,int[] range){
     cell.setExpressions(getAddRangeExpr(range));
 }

 /**
  * 給單元格新增Substract表示式
  * @param cell
  * @param a
  * @param b
  */
 public static void setCellSubExpr(ICell cell,int a,int b){
     cell.setExpressions(getSubExpr(a, b));
 }

 // return =sum(from:to);
 public static String getSumExpr(int from, int to) {
     StringBuffer buff = new StringBuff