在windchill中,BOM管理作爲一種核心的業務功能存在,但是在windchill10.0版本的系統OOTB功能中,BOM無法提取零件的分類屬性,因此一般情況下,都會進行剋制化開發,獲取BOM結構以及零件的層級是導出BOM報表的關鍵代碼。獲取BOM一般通過遞歸進行處理,往往都是傳入頂層的部件,通過深度優先遍歷,即可獲取BOM結構,但是零件的層級,在系統的數據庫中並沒有進行記錄,因此需要我們通過代碼來計算。其實,零件的層級計算可以轉換成遞歸算法的深度,因此實現BOM報表功能的核心代碼就是要實現遞歸,以及計算遞歸深度。
1 先定義一個類,記錄部件,部件的使用關係,部件層級。定義如下:
public class BOMElement {
//index 部件在BOM中的層數
private int index;
//part BOM中的部件
private WTPart part;
//link 部件的link(link 描述當前部件)
private WTPartUsageLink link;
//根節點元素的初始化
public BOMElement(WTPart part){
this.index = 0;
this.part = part;
this.link = null;
}
//所有子節點元素的初始化
public BOMElement(int index,WTPart part,WTPartUsageLink link){
this.index = index;
this.part = part;
this.link = link;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public WTPart getPart() {
return part;
}
public void setPart(WTPart part) {
this.part = part;
}
public WTPartUsageLink getLink() {
return link;
}
public void setLink(WTPartUsageLink link) {
this.link = link;
}
}
2 傳入頂層部件,實現遞歸查詢子部件,並定義變量,記錄遞歸深度:
public List<BOMElement> queryBOM(WTPart part) throws WTException{
BOMElement root = new BOMElement(part);
List<BOMElement> list = new ArrayList<BOMElement>();
ConfigSpec configSpec = WTPartHelper.service.findWTPartConfigSpec();
int index = 0;
list = querySubBOMList(root,configSpec,list,index);
return list;
}
private List<BOMElement> querySubBOMList(BOMElement element,ConfigSpec configSpec,List<BOMElement> list,int index) throws WTException{
list.add(element);
QueryResult qr = WTPartHelper.service.getUsesWTParts(element.getPart(),configSpec);
Vector<Object> vector = qr.getObjectVectorIfc().getVector();
for(int i=0;i<vector.size();i++){
Persistable[] persist = (Persistable[]) vector.get(i);
index++;
BOMElement subElement = new BOMElement(index,(WTPart)persist[1],(WTPartUsageLink)persist[0]);
querySubBOMList(subElement,configSpec,list,index);
index--;
}
return list;
}
3 上面定義中,index變量記錄遞歸深度,在遞歸調用之前,該變量自增1,表示遞歸調用一次,遞歸調用後,該變量自減1,表示遞歸調用減少一次。以此來記錄遞歸調用的次數。並在構造BOMElement中,以此來記錄零件的層級。