發表人 |
內容 |
|
E3系統核心功能已經過客戶的使用多年,
已經很穩定, 歡迎有興趣做行業別實作產品
的Java人加入.
可能你有行業別知識跟經驗, 又不想重頭
開發一套新的產品, 用一般市面的Java EE
架構, 又顯的太過龐大, 可以和我們一起研
究如何實作你們自己的行業產品.
有對E3任何技術問題, 都可以在這個論壇中
做發問.
|
 |
|
加入的按鍵會在編輯畫面的上面, 主要用於加入
一般的工作按鍵, 來輔助編輯作業.
我們還是以 E3/SDK示範項目 "郵遞區號編輯" 做
程式加入解說. 這裡會加入二個按鍵 "列印發票",
"發票編輯".
src/com/dasam/e3010001/client/edit/CmzZipCode.java
在程式的import區要加入:
import com.dasam.java.XButton;
看下面程式碼, 在 doWorkInit() 中加入按鍵的layout,
同時設定要執行的 function 名稱.
public void doWorkInit(HashMap map) throws Exception {
super.doWorkDefault(map,this);
this.moveRecord("init", XLet.getString(map.get("#link_edit_initValue")));
//加入功能按鍵,
XButton btnOutInvoice = this.getButton("printInvoice"," 列印發票 ", "exePrintInvoice",null, "view");//"view"表示在查詢狀態才enable
xlay.setLocationAdd(btnOutInvoice, xlay.left+xlay.getTipLabelWidth(), 5);
XButton btnInvoiceEdit = this.getButton("linkInvoiceEdit"," 發票編輯 ", "doLinkInvoiceEdit",null, "view");
xlay.addComH(btnOutInvoice,btnInvoiceEdit, "3c","");//距 列印發票 鍵,3個字寬
//..............中間程式省略
}
//==========================================================================
//列印發票
public void exePrintInvoice() throws Exception {
//加入功能程式
}
//==========================================================================
//發票編輯
public void doLinkInvoiceEdit() throws Exception {
//加入功能程式
}
|
 |
|
單表單編輯, 或雙表單編輯, 的型板有一個
工具列的標準功能, "新增匯入", 可以匯入
excel的資料到新增資料中, 操作請看E3的
操作手冊.
標準匯入資料是以字串為主, 如果資料較複製
或是要先做調整再匯入時, 可以設定一個中間
的調整function, 來做資料加工程式. 尤其是
出貨單, 進貨單..等, 的雙表單匯入, 很難用標
準模式匯入, 都要依客戶的需求做匯入.
我們以 E3/SDK示範項目 "郵遞區號編輯" 做
加入匯入功能, 先看以下的程式碼.
A. 主選單項目
src/com/dasam/e3010001/client/SystemDataCmz.java, 加入 "newimp" 權限細項
x.add2(rs,1,"D",".郵遞區號編輯","edit.CmzZipCode",1,"edit_1",2,"newimp");
B. 標準匯入功能
src/com/dasam/e3010001/client/edit/CmzZipCode.java
行47~50先做加入 新增匯入 的工具列按鍵, 記得加好, 要先打開群組權限.
行10 是設定那些是參照欄位, 寫入前會先檢查是否有參照筆.
public class CmzZipCode extends XFrameEditI {
public CmzZipCode() throws Exception {
this.isVoidWorkMode=true;
this.isUnvoidWorkMode=true;
this.convLangTables = "cmzZipCode,x";
this.filterList = uiFilter("filter");
this.serviceClassId = "edit.CmzZipCode";
//this.importRefreFields = "deparId"; //匯入時要參照欄位,
//this.adjustImportData = new com.dasam.work.XMethod(this,"exeAdjustImportData",null);
}
//==========================================================================
public void doWorkInit(HashMap map) throws Exception {
super.doWorkDefault(map,this);
this.moveRecord("init", XLet.getString(map.get("#link_edit_initValue")));
//editor layout
//"主碼"
XEText eId = new XEText(tbl("id"),10,this,"id");
xlay.add(eId,0,0);
eId.setFindRecord(this);
//資料視窗
XButton2 btnView = XTool.getViewButton("CmzZipCodeView",eId,this,"id", xwbar.getButton("first"));
xlay.addComH(eId,btnView,1,0);
editMap.put(btnView,"view");
//"名稱"
XEText eName = new XEText(tbl("name"),20,this,"name");
xlay.add(eName,0,0);
//"備註"
XEText eMemo = new XEText(tbl("memo"),20,this,"memo");
xlay.add(eMemo,0,0);
this.addEditStateLabel("v",0,0,0);
this.viewPack();
setWorkObjectValue(DATA_RS);
setWorkObjectEditStatus("view");
}
//==========================================================================
//加入"匯入"的按鍵
public HashMap getWorkBarMap() throws Exception {
if (!this.isPassCtrl("newimp")) return super.getWorkBarMap();//無新增匯入權限,
return XTool.getImportWorkBarMap(super.getWorkBarMap());//加入 '匯入',
}
//==========================================================================
//excel匯入調整,
/*public void exeAdjustImportData(boolean isData, XRowSet rs, org.apache.poi.hssf.usermodel.HSSFRow row) throws Exception {
if (isData){
//id, excel第1欄
Object id = XExport.getCellValue(row.getCell(row.getFirstCellNum()));
rs.setObject("id",id);
//name, excel第2欄
Object name = XExport.getCellValue(row.getCell((short)(row.getFirstCellNum()+1)));
rs.setObject("name",name);
}
}*/
}
C. 匯入功能加工
以上面的程式碼, 把行11及 行54~63的備註拿掉,
就可以自行設計 exeAdjustImportData() 中的程式
碼, 做匯入前的資料加工了.
|
 |
|
資料速查是一個類似excel的格式查詢畫面,
直接點二下資料筆, 可以連結到編輯畫面, 我
們用SDK的示範項目 "郵遞區號資料", 來做說明.
A. 主選單項目
src/com/dasam/e3010001/client/SystemDataCmz.java, 新加入行2
x.add2(rs,1,"E",".會員郵寄標籤","rpt.CmzMemberMailLabel",1,"report_3",3,null);
x.add2(rs,1,"F",".郵遞區號速查","edit.CmzZipCodeList",1,"list_1",0,"field_cfg",1);//加這行
x.addLine(rs,1);
B. 設定條件欄位
resource/com/dasam/e3010001/client/res/lang/cmz_ui.ppt
# edit.CmzZipCodeList
edit.CmzZipCodeList.filter = [@edit.CmzZipCode.filter]
C. Client程式
src/com/dasam/e3010001/client/edit/CmzZipCodeList.java
public CmzZipCodeList() throws Exception {
//frame設定
this.convLangTables = "cmzZipCode,x";
this.filterList = uiFilter("filter");
this.serviceClassId = "edit.CmzZipCodeList";
//this.setPageRecord(15);
this.fieldStyle = "{id=wd:10c;ha:c}{name=wd:15c}{memo=wd:15c}{creater=wd:10c}{createTime=wd:15c;ha:c}{updater=wd:10c}{updateTime=wd:15c;ha:c}";
this.defaultFieldList = "id,name,memo,creater,createTime,updater,updateTime";
this.fieldList = com.dasam.client.gui.XDlgFieldCfg.getFieldList(getClassFileName(), fieldStyle, defaultFieldList);
this.linkEditClassId = "edit.CmzZipCode";
this.isReturnNullClear = true;
}
//==========================================================================
//重載,起始
public void doWorkInit(HashMap map) throws Exception {
map.put("xwbar.icon.width","30"); //加大icon
super.doWorkDefault(map,this);
this.viewPack();
}
//==========================================================================
//資料顯示前加工,
public void doAdjustReturnRs(XRowSet rs) throws Exception {
rs.getField("creater").setLangName("建檔人");//欄名
//rs.printData(); //debug
}
}
D. Server程式
src/com/dasam/e3010001/server/edit/CmzZipCodeList.java
public class CmzZipCodeList extends XServiceListI {
//==========================================================================
public HashMap doWorkInit(HashMap map) throws Exception {
setXUserInformationObject(map, true); //建立user
setLastUpdateTime(map); //設定查詢筆數參數
setPageRecord(map); //頁筆數
this.viewTableName = "cmzZipCode";
//查詢時用到的參數設定
if (filterString==null) filterString = XLet.getString(map.get("filter"));
this.viewSelect = "select a.* from cmzZipCode a ";
this.viewIdField = "id";
HashMap ret = defaultFunctions(map);
return ret;
}
}
|
 |
|
一般在做網站訂單時, 常會有收件人的姓名, 電話, 行動,
收貨地址, 跟一般進銷存的出貨單不太一樣.
這裡用重載出貨單程式的方式加入這些欄位, 分成以下
的步驟來實作.
A. 主選單項目
src/com/dasam/e3010001/client/SystemDataCmz.java
x.setExtendId(data, new String[]{
"edit.OutStk", //加入出單重載
"edit.Item",
"edit.Member",
}, "_2");
B. 建立資料庫
resource/cmz.sql
加好後再用維護指令執行 database.update.cmz
alter table `outStk` add `recName` varchar(50) not null default ''; --收件人
alter table `outStk` add `recTel` varchar(50) not null default ''; --收件人電話
alter table `outStk` add `recMobile` varchar(50) not null default ''; --收件人行動電話
alter table `outStk` add `recAddr` varchar(100) not null default ''; --收件人地址
C. 資料庫欄名中文對照
resource/com/dasam/e3010001/client/res/lang/cmz_table.ppt
加入以下欄名對照.
#出貨單-----------------
outStk.recName = 收件人
outStk.recTel = 電話
outStk.recMobile = 手機
outStk.recAddr = 收貨地
D. Client出貨單編輯重載
src/com/dasam/e3010001/client/edit/OutStk_2.java
public class OutStk_2 extends OutStk {
public OutStk_2() throws Exception {
if (isOutStk){
//加入搜尋條件,可以省略
this.filterList += ";收件人,a.recName,1;收件地址,a.recAddr,1";
}
}
//==========================================================================
//overload客制化,
public void doAdjustLayout(com.dasam.java.XTabbedPane xtab) throws Exception {
if (!isOutStk) return; //退貨單不加
//整個往下移欄位,
xlay.moveY(this,"1.2h","memo,creater,createTime,updater,updateTime,subtotal_sum,discount,"
+"tax,recable,disct,cancelNo,cancelOk,subtotalCost_sum,accDate,itemQty_sum,"
+this.DETAIL_ITEM);
xlay.innerHeight += xlay.CHAR_HEIGHT*1.2;
//"收件人"
XEText recName = new XEText(tbl("recName"),8,this,"recName");
xlay.addV(getXEdit("hrId"),recName,0,0);
//"收件人電話"
XEText recTel = new XEText(tbl("recTel"),10,this,"recTel");
xlay.addH(recName,recTel,"-1c","0");
//"收件人行動電話"
XEText recMobile = new XEText(tbl("recMobile"),10,this,"recMobile");
xlay.addH(recTel,recMobile,"-1c","0");
//"收件人地址"
XEText recAddr = new XEText(tbl("recAddr"),25,this,"recAddr");
xlay.addH(recMobile,recAddr,"-1c","0");
//編輯順序
this.insertFocusList("outOrderId","recName,recTel,recMobile,recAddr");
}
}
|
 |
|
這裡用重載商品編輯的方式來做修改,
我們以SDK示範項目做修改, 直接改
src/com/dasam/e3010001/client/edit/Item_2.java
setResize(true) 時, setImageSize(250,250) 才有作用.
如果不設 setImageSize, 會以編輯框大小為主.
public void doAdjustLayout(XTabbedPane xtab) throws Exception {
if (xtab==null){
//修改圖片2設定
XEImage eImg2 = (XEImage)this.getXEdit("isImg2");
eImg2.setLimitDataLen(1000*1000); //最大1M,
eImg2.setResize(false);//不縮圖,原尺寸,
//eImg2.setImageSize(250,250);//縮為250x250,
return;
}
this.addWorkXPage(xtab,"bom"," 組合 ");
//..... 以下程式省略
|
 |
|
這裡再標準程式中, 直接加入一種新的出貨簽單,
這裡會在原來的出貨簽單程式, 用重載的方式做
加入程式. 我們加入到SDK的示範專案.
直接下載文章後的附檔.
A. 主選單項目
src/com/dasam/e3010001/client/SystemDataCmz.java
x.setExtendId(data, new String[]{
"rpt.OutStkSign", //加入這一行,重載原程式設定
"edit.Item",
"edit.Member",
}, "_2");
B. Client程式
src/com/dasam/e3010001/client/rpt/OutStkSign_2.java
會在畫面多出一個樣式選項: 標準樣式, 客制樣式.
public class OutStkSign_2 extends OutStkSign {
public OutStkSign_2() throws Exception {
this.reportFormats = new String[]{"標準樣式","","客制樣式","_2"};
this.serviceClassId = "rpt.OutStkSign_2";
}
//==========================================================================
//<重載>
public void doWorkInit(HashMap map) throws Exception {
super.doWorkInit(map);
getXEdit("reportFormats").setStatic(true);
}
//==========================================================================
public void doMakeReportExtParam() throws Exception {
super.doMakeReportExtParam();
if (isOutStk){//改變子報表名稱,只有出貨單,
String fmt = getXEdit("reportFormats").getValue().toString();
addReportExtParam("#subreport", "sys.OutStkDetail2"+fmt); //subreport檔名,
}
}
//==========================================================================
//報表資料加工,
public void doAdjustReportRs(XProgressWork xpw, XRowSet rs, HashMap rptParam) throws Exception {
super.doAdjustReportRs(xpw, rs, rptParam);
//2009.10.20改為只有在客制樣式時.
if (this.getReportFormatEditor().getSelectedIndex()==0) return;
rs.getField("tsDate").setLen(100);
for (rs.beforeFirst(); rs.next();){
XRowSet d = rs.getRs("detail_item");
//明細自動補足7的倍數.
int ar = d.getRowCount() % 7;
if (ar>0){ ar=7-ar; for(int i=0; i<ar; i++) d.insertRow(); }
//加入明細備註
d.insertField(new XField("cmzMemo",XField.TYPE_STRING,100));
String[] m = XLet.getStringArray(rs.getString("memo"),12);
for (int i=0; i><m.length; i++) if (d.setRowIndex(i)) d.setString("cmzMemo",m[i]);
//加入判斷是否結束欄位
d.insertField(new XField("isEnding",XField.TYPE_STRING,5));
d.last();
d.setString("isEnding","1");//不為null表示為ending,
//日期字串轉換
String[] dt = rs.getString("tsDate").split("[-]");
rs.setString("tsDate", dt[0]+" 年 "+dt[1]+" 月 "+dt[2]+" 日");
}
//表尾條文轉為字串,
com.dasam.work.XArrayReport xa = (com.dasam.work.XArrayReport)rptParam.get("ending");
rptParam.put("ending",xa.getDataString());
//加入logo圖形
byte[] logo = com.dasam.work.XFio.readData(XSystem.getSysResource(XSystem.getResourceName("res/logo/logo.jpg")).openStream());
rptParam.put("logo_img", logo);
}
}
C. Server程式
src/com/dasam/e3010001/server/rpt/OutStkSign_2.java
加入select欄位.
public class OutStkSign_2 extends OutStkSign {
public OutStkSign_2(){
this.adjustMainField = ",d.unitTitle 'cust_unitTitle'";
this.adjustDetailField = ",b.specif 'itemSpec'";
}
}
D. copy公司logo圖片
放到
resource/com/dasam/e3010001/client/res/logo/logo.jpg
E. 編譯報表format檔
resource/com/dasam/e3010001/client/rpt/fmt/sub/OutStkDetail2_2.xml
開啟ireport後, 按[File] / [Open], 讀取xml後, 再按 [Build] / [Compile]
表頭的公司資料要改成你們公司的名稱跟地址.
|
 |
|
在E3/SDK中, 分為client,server用的class, 分類大致如下:
Client端用class:
com.dasam.client.*
com.dasam.work.*
com.dasam.java.*
com.dasam.bjnet.client.*
com.dasam.e3010001.client.*
Server端用class:
com.dasam.server.*
com.dasam.work.*
com.dasam.db.*
com.dasam.bjnet.server.*
com.dasam.e3010001.server.*
所以套件會用在網路執行時, 要特別注意package的引用.
Client編輯畫面的架構:
client的編輯元件為com.dasam.client.edit.*
會以XEdit介面實作. 每個操作畫面的editor
再用XEditCollection 集合在一起.
|
 |
|
雙表單編輯是指做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 {
}
}
|
 |
|
這裡的單資料是指只要下一句SQL語法就可以產出
所要資料的標準型報表的製作. 例如: 產品列表,
客戶名冊, 廠商名冊..等.
這裡以SDK示範專案 "會員年費單列表" 作範本.
遇同類型的報表設計可以依照流程複製, 再做修改
就可以產生新的報表.
A. 主選單項目
x.add2(rs,2,"B",".會員年費單列表","rpt.CmzMemberYearFeeList",1,"report_1",3,null);
B. Client報表程式
src/com/dasam/e3010001/client/rpt/CmzMemberYearFeeList.java
一開始設計, 報表操作介面, 有那些報表範圍條件, 表尾條文..等
行9, 可以在沒有報表fmt檔時做測試執行
行52, 測試select的資料,到client的實際情況,做第一步除錯
public class CmzMemberYearFeeList extends XFrameReport {
public CmzMemberYearFeeList() throws Exception {
//this.langTableId = "rpt";
this.convLangTables = "cmzMemberYearFee,member,x";
this.serviceClassId = "rpt.CmzMemberYearFeeList";
//this.isViewDebug = true;
}
//==========================================================================
//重載,起始
public void doWorkInit(HashMap map) throws Exception {
super.doWorkDefault(map,this);
//編輯項目
this.addXETextRange("年度",6,"tsYear",DATE_Y,20,true,"time",null);
XLib.memberId(this,true,"會員");
XLib.sw(this,true,"狀態","swState","swState.def","{def=255}{left=2}{right=2}");
setOtherFilterBegin();//----------
XLib.tsDate(this,true,"收款日");
XLib.swDel(this,true);
setOtherFilterEnd();//----------
addEndingAndFormats();
this.viewPack();
this.doWorkBarAction("init");
}
//==========================================================================
//組合報表的條件式文字,
public void doMakeReportExtParam() throws Exception {
this.addReportExtParam("filter1", getFilters("@tsYear, &&, @memberId"));
this.addReportExtParam("filter2", getFilters("@tsDate, &&, swState"));
this.addReportExtParam("filter3", getFilters("&&, swDel"));
}
//==========================================================================
//報表資料加工,
public void doAdjustReportRs(XProgressWork xpw, XRowSet rs, HashMap rptParam) throws Exception {
HashMap state = this.tblMap("swState.def");
//加入主表欄位,
rs.insertField(new XField("state_txt", XField.TYPE_STRING,50));
rs.insertField(new XField("del_txt", XField.TYPE_STRING,50));
for (int i=0; rs.setRowIndex(i); i++){
rs.setObject("state_txt", state.get(rs.getString("swState"))); //狀態,
rs.setString("del_txt", rs.getBoolean("swDel")?"**":""); //作廢文字
}
//rs.printData();
}
}
C. Server報表程式
src/com/dasam/e3010001/server/rpt/CmzMemberYearFeeList.java
主要是由client的操作條件來select資料庫的資料
行62 會依client條件欄,組合SQL的Where子句
public class CmzMemberYearFeeList extends XServiceReport {
//==========================================================================
//make,
public HashMap makeReport(HashMap map) throws Exception {
XRowSet rs = XRowSet.getRowSet(map);
String where = XSql.getWhere(rs,"a.tsYear=@, a.memberId=@, a.recDate:tsDate=@, a.swState==, a.swDel==");
String sql = new StringBuffer()
.append("select a.id, a.tsYear, a.memberId, a.money, a.swState, a.recDate, a.swDel, b.name 'member_name' ")
.append("from cmzMemberYearFee a ")
.append("left join member b on b.id=a.memberId ")
.append(where).toString();
xdb().exeSql(sql);
return this.getReturnMapReport(rs);
}
}
D. 設計報表輸出樣式
resource/com/dasam/e3010001/client/rpt/fmt/CmzMemberYearFeeList.xml
這裡的樣式是用ireport工具來做設計, 原始碼是一個xml檔,
但設計完成可以編譯儲存為fmt檔, E3是整合執行fmt檔.
可以直接執行 C:\dasamx_dev\ireport.bat 再開啟xml檔做編譯.
開啟ireport後, 按[File] / [Open], 讀取xml後, 再按 [Build] / [Compile]
要先看 E3/SDK安裝説明 設好JAVA_SDK_PATH.
|
 |
|
單一表單編輯是指做MySQL一個資料表的編輯工作,
一般都是做參照的基本資料表.
這裡用SDK專案的 "郵遞區號編輯" 功能的分析設計
步驟. 這裡的原碼行號是標示作用, 並非原始檔的行號.
主要是做討論標示用.
所以如果要新增一個單表單的編輯程式, 可以照這些
步驟copy一次, 再修改要編輯的各欄位值.
A. 主選單項目
src/com/dasam/e3010001/client/SystemDataCmz.java
x.add2(rs,1,"D",".郵遞區號編輯","edit.CmzZipCode",1,"edit_1",2,null);
B. 建立資料庫
resource/cmz.sql
要注意, 行2,行4的資料表名稱要同步. 如何執行cmz.sql請看 E3/SDK安裝説明
insert ignore bjn_tableState values('cmzZipCode',0,0,0,'');
create table if not exists `cmzZipCode` (
`id` varchar(10) not null default '',
`name` varchar(50) not null default '', --簡稱
`memo` varchar(100) 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 ;
C. 資料庫欄名中文對照及簡繁設定(3個文檔)
resource/com/dasam/e3010001/client/res/lang/cmz_table.ppt, cmz_ui.ppt, cmz_xclass.ppt
#============ cmz_table.ppt ============
#區碼-----------------
cmzZipCode.id = 區碼 || 区码
cmzZipCode.name = 名稱
#============ cmz_ui.ppt ============
#----------- edit.CmzZipCode ------------
edit.CmzZipCode.filter = a.id,1;a.name,1;[@x.memo,tbl],a.memo,1;[@x.swDel,tbl],a.swDel,2
# edit.CmzZipCodeView
edit.CmzZipCodeView.title = [@XTool.view_button.CmzZipCodeView,cls]
edit.CmzZipCodeView.filter = [@edit.CmzZipCode.filter]
#============ cmz_xclass.ppt ============
XTool.view_button.CmzZipCodeView = 郵遞區號資料視窗 || 邮递区号资料视窗
D. 資料視窗程式
Client: src/com/dasam/e3010001/client/edit/CmzZipCodeView.java
public class CmzZipCodeView extends com.dasam.client.gui.XDlgView {
public CmzZipCodeView() throws Exception {
this.convLangTables = "cmzZipCode";
this.setTitle(ui("title"));
this.filterList = uiFilter("filter");
this.serviceClassId = "edit.CmzZipCodeView";
this.fieldStyle = "{id=wd:80;ha:c}{name=wd:220}";
this.fieldList = "id,name";
}
}
Server: src/com/dasam/e3010001/server/edit/CmzZipCodeView.java
public class CmzZipCodeView extends XServiceListI {
public HashMap doWorkInit(HashMap map) throws Exception {
setXUserInformationObject(map, true); //建立user
setLastUpdateTime(map);
setPageRecord(map); //頁筆數
this.tableStateId = "cmzZipCode";
this.viewTableName = tableStateId;
if (filterString==null) filterString = XLet.getString(map.get("filter"));
this.viewSelect = "select a.id, concat(if(swDel=1,'*',''),name) as 'name', swDel from cmzZipCode a ";
return defaultFunctions(map);
}
}
E. 單表編輯主程式
Client: src/com/dasam/e3010001/client/edit/CmzZipCode.java
public class CmzZipCode extends XFrameEditI {
public CmzZipCode() throws Exception {
this.isVoidWorkMode=true;
this.isUnvoidWorkMode=true;
this.convLangTables = "cmzZipCode,x";
this.filterList = uiFilter("filter");
this.serviceClassId = "edit.CmzZipCode";
}
public void doWorkInit(HashMap map) throws Exception {
super.doWorkDefault(map,this);
this.moveRecord("init", XLet.getString(map.get("#link_edit_initValue")));
//editor layout
//"主碼"
XEText eId = new XEText(tbl("id"),10,this,"id");
xlay.add(eId,0,0);
eId.setFindRecord(this);
//資料視窗
XButton2 btnView = XTool.getViewButton("CmzZipCodeView",eId,this,"id", xwbar.getButton("first"));
xlay.addComH(eId,btnView,1,0);
editMap.put(btnView,"view");
//"名稱"
XEText eName = new XEText(tbl("name"),20,this,"name");
xlay.add(eName,0,0);
//"備註"
XEText eMemo = new XEText(tbl("memo"),20,this,"memo");
xlay.add(eMemo,0,0);
this.addEditStateLabel("v",0,0,0);
this.viewPack();
setWorkObjectValue(DATA_RS);
setWorkObjectEditStatus("view");
}
}
Server: src/com/dasam/e3010001/server/edit/CmzZipCode.java
public class CmzZipCode extends XServiceEditI {
public HashMap doWorkInit(HashMap map) throws Exception {
setXUserInformationObject(map, true); //建立user
setLastUpdateTime(map);
this.tableStateId = "cmzZipCode";
this.editTableName = tableStateId;
this.setDeleteWorkMode(false); //設定使用作廢方式,
this.isUnvoidWorkMode=true; //設定可使用回復作廢方式,
if (filterString==null) filterString = XLet.getString(map.get("filter"));
this.editSelect="select * from cmzZipCode a ";
HashMap ret = defaultFunctions(map);
return ret;
}
}
|
 |
|
其他行業別的問題,
歡迎在這版做討論~
|
 |
|
所有客制套件最先整合的是選單,
把各個要客制的功能先列在選單中,
包含要重載的程式, 也是在選單中
做設定. 請看 SDK中的範例專案的
com.dasam.e3010001.client.SystemDataCmz.java
package com.dasam.e3010001.client;
import com.dasam.work.XRowSet;
import com.dasam.work.XLet;
import com.dasam.client.menu.XMenuAdd;
import com.dasam.client.XSystem;
public class SystemDataCmz {
//--------------------------------------------------------------------------
//data : 原menu資料,要預防原系統的class id名稱,
//insPoint : menu內定統一要加入的點,也可以自己設定,內定:"_window"
public static XRowSet addMenuData(XRowSet data, String insPoint) throws Exception {
XMenuAdd x = new XMenuAdd();
XRowSet rs = x.createRsMenu();//開空menu
//加入menu,名稱前加".",表示不轉語系,
x.add0(rs,"X",".客制","_XX",null);
x.add2(rs,1,"A",".產品組合單建立","edit.CmzBomItem",1,"edit_2",2,null);
x.add2(rs,1,"B",".產品多階展開表","rpt.CmzBomLevelList",1,"report_1",3,null);
x.addLine(rs,1);
x.add2(rs,1,"C",".取得主機時間","cmz_get_server_time",1,null,0,null);
x.addLine(rs,1);
x.add2(rs,1,"D",".郵遞區號編輯","edit.CmzZipCode",1,"edit_1",2,null);
x.add2(rs,1,"E",".會員郵寄標籤","rpt.CmzMemberMailLabel",1,"report_3",3,null);
x.addLine(rs,1);
x.add1(rs,1,"Z",".會員年費管理","_X_Z",null);
x.add2(rs,2,"A",".會員年費單編輯","edit.CmzMemberYearFee",1,"edit_1",2,null);
x.add2(rs,2,"B",".會員年費單列表","rpt.CmzMemberYearFeeList",1,"report_1",3,null);
//將結構加在'視窗'之前
data = com.dasam.client.system.XSystemData.insertMenuData(data, rs, insPoint);
//做原程式extends,
//Item_2 --> Item == 商品加入組合頁簽
//Member_2 --> Member == 會員加入郵遞區號
x.setExtendId(data, new String[]{
"edit.Item",
"edit.Member",
}, "_2");
//刪除原系統menu
//x.delete(data, "edit.OutStk");
return data;
}
//--------------------------------------------------------------------------
//執行授權的序號
public static boolean isAuthorize() throws Exception {
return true;
//return XSystem.isPassSerial("01-001-0104,01-001-0105");
}
}
所以我們在執行這個客制插件時, 在主選單會出現
這裡所增加的部份在 "視窗" 選單的前面. 這支程式
像客制專案的定義區, 定義增加那些程式功能, 或修
改那些程式.
行20是根節點, 在加在選單的根部.
行23,25,28是產生一條選單的線,做分隔.
行29是選單子節點.
行21是實際要加入的選單功能
x.add2(rs,1(x),"A",".產品組合單建立","edit.CmzBomItem",1,"edit_2",2,null);
"x" 的參數是節點的階層, 要設對, 從1開始
"A" 在傳統選單, 有快捷鍵作用
".產品組合單建立" 選單名稱, 單語系一定要以"."做開頭.
"edit.CmzBomItem" 指按下選單後要執行的程式名稱, 實際是 com.dasam.e3010001.client.edit.CmzBomItem.java
"edit_2" 是icon樣式,也可以自行加入
行39~42是重載執行, 主要用於修改原程式用.
行53~69是設定可以執行套件的權限, 以產品序號為識別.
|
 |
|
E3/SDK有一些基本模組程式, 一般都是做
設計的底層, 我們會陸續以實際的程式做
說明.
例如:
單表編輯,
父子表編輯,
查詢視窗,
長時間處理,
報表模組,
...
|
 |
|
這裡的程式設計主要以JavaSE為主,
雖然以SE做程式設計, 但可以在網路
上執行, 因為E3已有HTTP的通訊傳
送模組.
E3中的程式設計, 第一步是先安裝SDK
請看 E3/SDK安裝説明
再看原始碼 SystemDataCmz.java
這是整合選單的程式.
整合好後, 再看實作的程式類型, 單表編輯,
雙表編輯, 報表編輯.. 等, 再copy目前已
有相同的模組, 作修改. 以此類推, 以達成
需求的實踐.
|
 |
|
|
|