在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中,以此来记录零件的层级。