[Logo]  E3系統 開發.操作.問題 討論區 
[Search] 搜尋主題 [Recent Topics] 最新主題 [Hottest Topics] 熱門主題 [Members] 會員列表 [Groups] E3首頁
[Register] 會員註冊 [Login] 會員登入
新增 雙表單編輯程式  XML
討論區首頁 » Java程式分析與設計
發表人 內容
e3Admin

[Avatar]

註冊時間: 2011-06-09 18:31:13
文章: 73
離線

雙表單編輯是指做MySQL二個資料表以上的編輯工作,
一般都是一對多的關係, 就是會有一筆表頭對應多筆明
細的情況, 例如: 進貨單, 出貨單, 報價單..等.

這裡用比較簡單的雙表單 "產品組合單建立" 做範本
請先看SDK的示範專案. 要先了解 單表單編輯 再研
究雙表單, 會較容易理解.


A. 主選單項目
src/com/dasam/e3010001/client/SystemDataCmz.java
x.add2(rs,1,"A",".產品組合單建立","edit.CmzBomItem",1,"edit_2",2,null);


B. 建立資料庫
resource/cmz.sql
--** BOM筆狀態
insert ignore bjn_tableState values('cmzBomItem',0,0,0,''); --bom結構

--** BOM結構
create table if not exists `cmzBomItem` (
	`id` varchar(30) not null default '', --商品主碼
	`memo` varchar(250) not null default '', --備註
	`swDel` tinyint unsigned not null default 0, --作廢, 1=yes,

	`creater` varchar(20) not null default '', --建立人員
	`createTime` datetime not null default '0-0-0', --建立時間
	`updater` varchar(20) not null default '', --修改人員
	`updateTime` datetime not null default '0-0-0', --修改時間

	primary key (id)
) type=InnoDB ;

--** 結構明細
create table if not exists `cmzBomItemDetail` (
	`rela` varchar (30) not null default '', --相關欄,
	`no` smallint unsigned not null default 0, --序號,
	`itemId` varchar (30) not null default '', --商品主碼
	`qty` decimal(9,4) not null default 0, --組合數量

	primary key (rela,no),
	index `ix_itemId` (itemId)
) type=InnoDB;


C. Client程式
src/com/dasam/e3010001/client/edit/CmzBomItem.java
public class CmzBomItem extends XFrameEditII {

    public CmzBomItem() throws Exception {
        this.convLangTables = "cmzBomItem,x";
        this.filterList = null;
        this.serviceClassId = "edit.CmzBomItem";
        this.itemReferId = "simpleItem";
        this.idField = "id";
        this.editFirstFieldName = null;
        this.editObjectDisable = null;
        this.displayInsertMsg = null;
        this.isCloseTimeWorkMode = false;
        this.isVoidWorkMode = false;
	}

    //==========================================================================
    public void doWorkInit(HashMap map) throws Exception {
		map.put("xwbar.icon.width","32"); //icon size
        super.doWorkDefault(map,this);

        this.moveRecord("init", XLet.getString(map.get("#link_edit_initValue")));

        //layout editor
        XEText eId = new XEText(tbl("id"),15,this,"id");
        xlay.add(eId,0,0);
        eId.setFindRecord(this);
        this.doReference(eId, "cmzBomItem","item_name,name,item_unit,unit");
        //視窗
        XButton2 btnView = XTool.getViewButton("CmzBomItemView",eId,this,"id", xwbar.getButton("first"));
        xlay.addComH(eId,btnView,1,0);
        editMap.put(btnView,"view");
        //商品視窗,
        XButton2 btnItemView = XTool.getViewButton("ItemView",eId,editMap,"id,id,item_name,name,item_unit,unit");
        xlay.addComH(btnView,btnItemView,5,0);
        editMap.put(btnItemView, "new,newas");

        //品名
        XEText eItemName = XEText.createLabelText(null,25,this,"item_name",0,0);
        xlay.addComV(eId,eItemName,0,0);
        //單位
        XEText eItemUnit = XEText.createLabelText(null,6,this,"item_unit",0,0);
        xlay.addComH(eItemName,eItemUnit,5,0);

        //detail
        XEGrid eDetail = getDetailGrid(DETAIL_ITEM);
        xlay.add(eDetail,0,0,0,5);
        //"備註"
        XEText eMemo = new XEText(tbl("memo"),40,this,"memo");
        xlay.add(eMemo,0,0);


        this.addEditStateLabel("v",0,0,0);

        this.viewPack();
        setWorkObjectValue(DATA_RS);
        setWorkObjectEditStatus("view");

    }

    //==========================================================================
    //新筆,資料起始,"new","newas"
    public void setNewRecordData(String workId) throws Exception {
        if (workId.equals("newas")){
            getXEdit(idField).setValue("");
        }
    }

    //==========================================================================
    //相關欄位參照驗証檢查,主要針對"save_edit","save_new","save_newas"
    public boolean isValidateData(String workId) throws Exception{
        if (XLet.isFindId("save_edit,save_new,save_newas",workId)){
            //參照驗証,
            if (!isValidateText("x2,cmzBomItem","id,e,r")) return false;
            //grid驗証,
            if (!((XEGrid)getXEdit(DETAIL_ITEM)).isCheckValidCount("itemId")) return false;
            if (!((XEGrid)getXEdit(DETAIL_ITEM)).isCheckReference("itemId")) return false;
            //檢查子商品內是否有父商品,(只檢查第一階,多階檢查在server端)
            XRowSet rs = ((XEGrid)getXEdit(DETAIL_ITEM)).getGridRowSet("itemId");
            if (rs.isFindRow("itemId", getXEdit("id").getValue().toString().trim())){
                xmsg.err("組合子產品中包含了主產品!","");
                return false;
            }
        }
        return true;
    }

    //======================================================================
    //明細grid,
    public XEGrid getDetailGrid(String fieldName) throws Exception {
        //取得rs表結構,
        XRowSet rs = new XRowSet((HashMap)mainRs.getObject(DETAIL_ITEM));
        //column
        XEGridColumn[] cols = new XEGridColumn[]{
            new XEGridColumn(tbl("itemId"), new XEText(rs.getField("itemId")),14,0),//"品 碼"
            new XEGridColumn(tbl2("itemName"), null, rs.getField("itemName"),24,0), //"品 名"
            new XEGridColumn(tbl("qty"), new XEText(rs.getField("qty")),8,0),//"數量"
            new XEGridColumn(tbl("unit"), null, rs.getField("itemUnit"),6,0), //"單位"
        };
        //建立grid
        XEGrid g = new XEGrid("", cols, 10, 300, this, fieldName);
        g.setReturnFields("#itemId,qty");
        g.getColumn("itemId").setViewButton(XTool.getViewButton("ItemView",this,"exeDetailItemView",new Object[]{g,""}));
		((XEText)g.getColumn("itemId").editor).setLinkEditClassId("edit.Item");
        ((XEText)g.getColumn("qty").editor).setMinEditValue(new Integer(1));
		//開始建構grid
        g.makeWorking();

        g.addChangeValueAction(this,"exeDetailChangeValue",null);
        g.setLinkEditClassId("itemId;edit.Item");
		return g;
    }

    //==========================================================================
    //設定一筆資料,
    //isId : 是否設定主碼,
    //ixData : 目前編輯的row index
    public void setDetailItemData(XEGrid g, XRowSet rs, int ixData, boolean isId) throws Exception {
		if (isId) g.getColumn("itemId").setValue(ixData, rs==null? "" : rs.getString("id"));
        if (ixData==g.getDataIndex()) g.getColumn("itemId").editor.setReference(rs!=null); //要設定editor,否則setValue()時會重設setReference(),
        g.getColumn("itemId").setReference(ixData, rs!=null); //若有檢查要設定參照成功,
        g.getColumn("itemName").setValue(ixData, rs==null? "" : rs.getString("name"));
        g.getColumn("qty").setValue(ixData, rs==null? "" : "1");
        g.getColumn("itemUnit").setValue(ixData, rs==null? "" : rs.getString("unit"));
    }


}



D. Server程式
src/com/dasam/e3010001/server/edit/CmzBomItem.java
public class CmzBomItem extends XServiceEditII {

    private static final String editDetailTableName = "cmzBomItemDetail";

    public CmzBomItem(){
        this.tableStateId = "cmzBomItem";
        this.editTableName = tableStateId;
        this.editIdField = "id";
        this.editSelect="select a.*, b.name 'item_name', b.unit 'item_unit' from cmzBomItem a   left join item b on b.id=a.id ";
        this.editSelectDetail="select a.itemId,a.qty, concat(if(b.swDel=1,'*',''),b.name) as 'itemName', b.unit 'itemUnit' from cmzBomItemDetail a  left join item b on b.id=a.itemId ";
        this.editProperty = "CLS_MAIN,id, CLS_MUSTX,updateTime"; //必要上傳欄位,
        //個別設定
        this.setDeleteWorkMode(true); //用刪除,
        this.isCloseTimeWorkMode = false; //不使用結帳日,
        this.isAutoSortListNo = false; //新增時,不自排單碼
        this.editOrderBy="a.id"; //找資料排序碼,
    }

    //==========================================================================
    public HashMap doWorkInit(HashMap map) throws Exception {
        setXUserInformationObject(map, true); //建立user

        setLastUpdateTime(map);
        if (filterString==null) filterString = XLet.getString(map.get("filter"));

        HashMap ret = defaultFunctions(map);
        return ret;
    }

    //==========================================================================
    //只執行明細,main在XServiceEditII.insertRecord_detail()會處理
    //己有作trans的指令,
    public void insertRecord_detail(HashMap map, XRowSet rs) throws Exception {
        //detail
        XRowSet rs2 = new XRowSet((HashMap)rs.getObject(DETAIL_ITEM));
        String rela = rs.getString("id");
        String[] values = XSql.getValues(null,rs2,null,false,false,false); //讀取所有set組字串,

        for (int i=0; rs2.setRowIndex(i); i++){
			//新增一筆明細
			String fixValues = new StringBuffer("'").append(rela).append("',")//額外加入insert sql
				.append(i+1).toString();
			String insert = new StringBuffer("insert ").append(editDetailTableName).append(" ")
				.append( XSql.toInsert(values[i],"rela,no",fixValues) )
				.append(";").toString();
			xdb().exeSql(insert); //執行新增
        }

        //多階檢查子品中,是否包含子品,
        XRowSet bom = CmzBomLevelList.getBomData(xdb(),rela);
        if (XLet.getInt(bom.max("lvl"))>10) throwWorkException(">組合子產品超過了10個階層!");
        if (bom.isFindRow("itemId",rela)){//子產品中,找到有母品存在,
            int lvl = bom.getInt("lvl");
            String bomPath = rela;
            while(bom.previous()){
                //if (bom.getInt("lvl")<1) break;//為root階層,
                if (bom.getInt("lvl")<lvl){
                    lvl=bom.getInt("lvl");
                    bomPath = bom.getString("itemId")+"\n"+bomPath;//結構路徑
                }
            }
            bomPath = rela+"\n"+bomPath;
            throwWorkException(">組合子產品中包含了主產品! 結構:  \n"+bomPath);
        }
    }

    //==========================================================================
    //更新作業,
    public void updateRecord_detail_old(HashMap map, XRowSet rs) throws Exception {
        String idValue = rs.getString(editIdField);
        deleteRecord_detail(map, idValue); //做回帳,及刪除,
    }

    //--------------------------------------------------------------------------
    //新資料,直接用insert,
    public void updateRecord_detail_new(HashMap map, XRowSet rs) throws Exception {
        insertRecord_detail(map, rs);
    }

    //==========================================================================
    //會先回帳,再刪除,
    public void deleteRecord_detail(HashMap map, String idValue) throws Exception {
        voidRecord_detail(map, idValue);
        //刪除明細
        String sql = new StringBuffer("delete from ").append(editDetailTableName)
            .append(" where rela='").append(idValue).append("';").toString();
        xdb().exeSql(sql);
    }

    //==========================================================================
    //作廢明細筆. 主要是依idValue做明細筆的回帳,
    public void voidRecord_detail(HashMap map, String idValue) throws Exception {
    }


}


修改2次,最後2011-06-25 18:24:20  

輕輕敲醒沈睡的心靈~  企鵝的初章 ^^
 
討論區首頁 » Java程式分析與設計
前往:   

2011 DASAMX GROUP.    Powered by JForum 2.1.9©    建議使用Firefox瀏覽