以表格的形式显示设备的子元件构成及数量
(最简使用方式:
跳过1
,2
,3
步,直接从第四步开始,以任何一种方式传参数如“12EQU1AND5EQU1
”,并在处理的JSP
页面里得到,实现在JSP
页面里,只需要写几条语句就可以了。不过,再强调:“12EQU1AND5EQU1
”表示该成品编号为12
的产品1
台,成品编号为5
的产品1
台。你可以再加或者只查看一台也可以。还有你的元件组成表一定要似下图表中的数据显示的一样,以“#
”分开同一ID
的不同属性,以“|
”分开不同的ID
。
)
1
、介绍:
在日常生活中,我们可以用一些存在了的东西,构成其它的一些新东西,如我们可以用小零件构成一台机器等等,但是我们在用电脑表述的时候,通常都是以这样的方式来实现。
上面表格中,如:125#2#20表示的是编号为125的子元件在构成该部件的时候需要两个,位置在图纸上为20的地方。用|来分开不同的子元件,这样就可以以这种方式将一台复杂的机器设备模拟出来了。
但是作为一名非计算机人员,没有人会想看到模拟的计算机是由这些东西组成的,他们也不懂,这样也让计算有多少元件变得非常的烦杂。我们做为程序员的,就是为了解决这些问题布存在的,下面我对这个问题的解决方案:
2
、实现图例:
1)、先看下面这张数据表图:
2)、这张是实现流程图:
3)、这样处理后,需要多少元件就以表格的形式显示出来,如下示例图:
4)、调用页面如图所示:
3
、JSP
页面源码
这样点击“查看汇总”后就会传递如下字符串给处理页面:
12EQU1AND5EQU1
解释:表示该成品编号为12
的产品1
台,成品编号为5
的产品1
台。
三个按钮的代码如下:
<input type=button value=全选 onclick=checkAll();>
<input type=button value=取消 onclick=clearAll();>
<input type=button value=查看汇总 onclick=showResult();>
这里复选框的命名规则是:“ch
”加该记录对应的ID
号,文本框的命名规则是:“num
”加上该记录对应的ID
号
实现该三个按钮的
JS
函数是:
///////////CHECKBOX
的全选与取消全选,以及得到选中的CHECKBOX
对应数量及ID///////
//
在处理
JSP
页面中显示结果
function showResult()
{
var str=
''
;
var el=document.getElementsByTagName(
'input'
);
var len = el.length;
var numName;
for
(var i=0;i<len;i++)
{
numName=
'num'
;
if
(el[i].type==
"checkbox"
)
{
if
(el[i].checked)
{
numName+=getId(el[i].name,
'ch'
);
if
(document.getElementById(numName).value)
{
str+=getId(el[i].name,
'ch'
)+
"EQU"
+document.getElementById(numName).value+
"AND"
;
}
}
}
}
str=str.substr(0,str.length-3);
window.open(
'disNeededComponentFromChoosedProductWithNum.jsp?str='
+str);
//alert(str);
}
function getId(str1,str2)
//
取出序号
ID
{
//str1=ch1,str2=ch,result=1
str1=str1.replace(str2,
""
);
return
str1;
}
//
全选
function checkAll()
{
var el = document.getElementsByTagName(
'input'
);
var len = el.length;
for
(var i=0; i<len; i++)
{
if
(el[i].type==
"checkbox"
)
{
el[i].checked =
true
;
}
}
}
//
取消全选
function clearAll()
{
var el = document.getElementsByTagName(
'input'
);
var len = el.length;
for
(var i=0; i<len; i++)
{
if
(el[i].type==
"checkbox"
)
{
el[i].checked =
false
;
}
}
}
4
、在JSP
页面的操作方式如下:
<%
String str=request.getParameter("str").trim();
if
(str!=
null
&& str!=
""
&& !str.equals(
""
))
{
GetComponentDetailListDependByID g=
new
GetComponentDetailListDependByID();
str = c.generateStardardStrFromGetStrByChoosedProduct(str);
System.out.println(c.getResultStrWithTableFormat(str));
}
%>
5
、JAVA
源码如下:
import
java.sql.ResultSet;
import
java.sql.ResultSetMetaData;
import
java.sql.SQLException;
import
java.util.TreeMap;
/**
*
将组成元件的所有子元件(最基本的子元件,没有其它元件构成)的数量取出并放在
HASHMAP
中
*
并最后以表格的形式显示
*/
public
class
GetComponsedComponentByTableFormat_General {
DBMS_Conn conn;
TreeMap
tm
;
public
GetComponsedComponentByTableFormat_General() {
//
请在实际应用中,将该数据库链接补充完整
conn =
new
DBMS_Conn();
//
建立数据库链接
tm
=
new
TreeMap();
//
初使化
TreeMap
}
/****************************
生成标准字符串
****************************/
/**
*
调用步骤:
1,
首先调用该方法,生成标准的字符串
*
@param
str
提交的字符串如:
1EQU4AND2EQU20
*
@return
折分好的标准字符串如:
381#10|183#20|629#30|113#40|147#50
*
(
“#”
前后的分别表示编号及数量,即当前编号对应的数量,
*
“|”
前后表示的是不同编号的设备及数量,这里表示共有五种编号的设备)
*/
public
String generateStardardStrFromGetStrByChoosedProduct(String str) {
try
{
str = str.trim();
}
catch
(Exception e) {
str =
""
;
}
if
(str.equals(
""
))
return
null
;
String resultStr =
""
;
String[] str1 = str.split(
"AND"
);
for
(
int
i = 0; i < str1.
length
; i++) {
String[] str2 = str1[i].split(
"EQU"
);
int
pid;
try
{
pid = Integer.parseInt(str2[0]);
}
catch
(Exception e) {
pid = 0;
}
int
pnum;
try
{
pnum = Integer.parseInt(str2[1]);
}
catch
(Exception e) {
pnum = 0;
}
String pstr = getComponsedID(pid);
pstr = getFormatedStrByMultiplyProductNum(pstr, pnum);
if
(i < (str1.
length
- 1))
pstr +=
"|"
;
resultStr += pstr;
}
return
resultStr;
}
/**
*
*
@param
pstr
组成该成品的字符串如:
381#10|183#20|629#30|113#40|147#50
*
@param
pnum
该成品的数量
*
@return
把各数量进行相应的数量积后,再生成新的标准字符串返回来
*
返加结果字符串如下:
381#50|183#100|629#150|113#200|147#250
*/
private
String getFormatedStrByMultiplyProductNum(String pstr,
int
pnum) {
StringBuffer resultStr =
new
StringBuffer(
""
);
try
{
pstr = pstr.trim();
}
catch
(Exception e) {
pstr =
""
;
}
if
(pstr.equals(
""
)) {
return
null
;
}
String[] pstr1 = pstr.split(
"//|"
);
for
(
int
i = 0; i < pstr1.
length
; i++) {
String[] pstr2 = pstr1[i].split(
"#"
);
String pstr20 = pstr2[0];
int
pstr21;
try
{
pstr21 = Integer.parseInt(pstr2[1]) * pnum;
}
catch
(Exception e) {
pstr21 = 0;
}
resultStr.append(pstr20 +
"#"
);
resultStr.append(pstr21);
if
(i < (pstr1.
length
- 1))
resultStr.append(
"|"
);
}
return
String.valueOf(resultStr);
}
/****************************
生成标准字符串
OK****************************/
/**
*
调用步骤:
2
*
@param
composedStr
组成该成品的元件字符串,如:
12#1
*
最后生成有表格内容的元件清单
*/
public
StringBuffer getResultStrWithTableFormat(String composedStr) {
String resultStr;
pubAllComponetAndNumIntoHashMap(composedStr);
resultStr = getResultStr();
//System.out.println("resultStr:"+resultStr);
String[] resultStr_split = resultStr.split(
","
);
String sql =
"select ID,serialnumber,cname,ename,specification,unit,"
;
sql +=
"weight from components"
;
String sql1 =
""
;
StringBuffer returnStr =
new
StringBuffer(
""
);
returnStr.append(
"<table border=1>"
);
ResultSetMetaData rsmd;
ResultSet rs = conn.executeSQLReturnResult(sql);
int
ColumnCount;
int
componentID = 0;
try
{
rsmd = rs.getMetaData();
ColumnCount = rsmd.getColumnCount();
returnStr.append(
"<tr>"
);
returnStr.append(
"<td colspan="
+ (ColumnCount + 2) +
" align=center>"
);
returnStr.append(
"<font size=6>
配
件
组
成
元
件
明
细
表
</font>"
);
returnStr.append(
"</td>"
);
returnStr.append(
"</tr>"
);
//
取得列名,列名的顺序下标是从
1
开始的
returnStr.append(
"<tr>"
);
for
(
int
j = 1; j <= ColumnCount; j++) {
returnStr.append(
"<td align=left> "
);
returnStr.append(conn.replaceEnglishHeadWithChinese(rsmd.getColumnName(j)));
returnStr.append(
"</td>"
);
}
returnStr.append(
"<td>"
);
returnStr.append(
"
数量
"
);
returnStr.append(
"</td>"
);
returnStr.append(
"<td>"
);
returnStr.append(
"</td>"
);
returnStr.append(
"</tr>"
);
for
(
int
i = 0; i < resultStr_split.
length
; i++) {
String[] resultStr_split_IDValue =
resultStr_split[i].split(
"="
);
sql1 = sql;
sql1 +=
" where ID="
+ resultStr_split_IDValue[0];
//System.out.println("sql:"+sql1);
rs = conn.executeSQLReturnResult(sql1);
if
(rs.next()) {
returnStr.append(
"<tr>"
);
for
(
int
j = 1; j <= ColumnCount; j++) {
if
(j == 1) {
{
returnStr.append(
"<td align=left> "
);
returnStr.append(rs.getInt(j));
returnStr.append(
"</td>"
);
componentID = rs.getInt(j);
}
}
else
{
returnStr.append(
"<td align=left> "
);
returnStr.append(rs.getString(j));
returnStr.append(
"</td>"
);
}
}
returnStr.append(
"<td>"
);
try
{
returnStr.append(Integer.parseInt(resultStr_split_IDValue[1]));
}
catch
(Exception e) {
returnStr.append(0);
}
returnStr.append(
"</td>"
);
returnStr.append(
"<td>"
);
returnStr.append(
"<a href=componentView.do?id="
+
componentID +
" target=_blank><font color=green>
查看
</font></a>"
);
returnStr.append(
"</td>"
);
returnStr.append(
"</tr>"
);
}
}
returnStr.append(
"</table>"
);
}
catch
(SQLException e) {
e.printStackTrace();
}
conn.closeConnection();
return
returnStr;
}
/********************
以下方法为功能性方法,为上面的步骤二服务
********************/
/**
*
*
@param
id
元件
ID
*
@return
根据元件的
ID
返回组成元件的序列集合,如
1#2|3#6|5#12,
返回
null
表示没有子元件
*/
private
String getComponsedID(
int
id) {
String sql =
"select composedBy from components where composedBy"
;
sql +=
" is not null and composedBy<>'' and id="
+ id;
String componsedID =
null
;
ResultSet rs = conn.executeSQLReturnResult(sql);
try
{
if
(rs.next()) {
componsedID = rs.getString(1);
}
}
catch
(SQLException e) {
e.printStackTrace();
}
return
componsedID;
}
/**
*
*
@param
id
元件
ID
*
@param
idNum
该元件数量
*
result
将对应
ID
的值放到
TreeMap
中
*/
private
void
pubComponetAndNumIntoHashMap(
int
id,
int
idNum) {
if
(
tm
.containsKey(id)) {
//
如果存在
idNum += Integer.parseInt(
tm
.get(id).toString());
//
取值
}
//System.out.println(id+" "+idNum);
tm
.put(id, idNum);
//
赋值
}
/**
*
*
@param
id
元件
ID
*
@param
check
是否需要检测当前当前
ID
的组成字符串是否为空
*
@param
generatedIDNum
通过条件生成的对应
ID
的数量
*
result
将所有元件的
ID
及数量都放到
TreeMap
中
*
注:这里要采用递归的方法
*/
private
void
pubAllComponetAndNumIntoHashMap(
int
id,
boolean
check,
int
generatedIDNum) {
String componsedIDs = getComponsedID(id);
//System.out.println("componsedIDs:"+componsedIDs);
if
(check ==
true
) {
if
(componsedIDs ==
null
)
return
;
}
String[] IDAndNum = componsedIDs.split(
"//|"
);
for
(
int
i = 0; i < IDAndNum.
length
; i++) {
String[] IDNum = IDAndNum[i].split(
"#"
);
int
thisID;
try
{
thisID = Integer.parseInt(IDNum[0]);
}
catch
(Exception e) {
thisID = 0;
}
int
thisIDNum;
try
{
thisIDNum = Integer.parseInt(IDNum[1]) * generatedIDNum;
}
catch
(Exception e) {
thisIDNum = 0;
}
if
(getComponsedID(thisID) !=
null
) {
//
是否有子元件
pubAllComponetAndNumIntoHashMap(thisID,
false
, thisIDNum);
}
else
{
//
没有就把该子元件加入
HashMap
pubComponetAndNumIntoHashMap(thisID, thisIDNum);
}
}
}
/**
*
*
@param
str
由选择的产品,生成的标准字符串,如:
*
11#2|15#1|27#1|29#1|31#2|35#1|37#1|61#1|67#1
*
"#"
前面的表示元件
ID
号,后面的表示该元件的数量
*
result
将所有元件的
ID
及数量都放到
HashMap
中
*
注:这里要采用递归的方法
*/
private
void
pubAllComponetAndNumIntoHashMap(String str) {
String componsedIDs = str;
String[] IDAndNum = componsedIDs.split(
"//|"
);
//
第一次折分
for
(
int
i = 0; i < IDAndNum.
length
; i++) {
String[] IDNum = IDAndNum[i].split(
"#"
);
//
对第二次折分
/*******
取出对应的
ID
及对
ID
对应的数量,加了
TRY
CATCH
以免转换异常
*******/
int
thisID;
try
{
thisID = Integer.parseInt(IDNum[0]);
//
元件
ID
号
}
catch
(Exception e) {
thisID = 0;
}
int
thisIDNum;
try
{
thisIDNum = Integer.parseInt(IDNum[1]);
//
对应
ID
的数量
}
catch
(Exception e) {
thisIDNum = 0;
}
/*******
取出对应的
ID
及对
ID
对应的数量,加了
TRY
CATCH
以免转换异常
OK*******/
if
(getComponsedID(thisID) !=
null
) {
//
是否有子元件
pubAllComponetAndNumIntoHashMap(thisID,
true
, thisIDNum);
}
else
{
//
没有就把该子元件加入
HashMap
pubComponetAndNumIntoHashMap(thisID, thisIDNum);
}
}
}
/**
*
*
@return
将
TreeMap
中的数据,以字符串的形式返回,返回字符串如下:
*
11=2,15=1,27=1,29=1,31=2,35=1,37=1,61=1,67=1,69=1
*
"="
前面的表示,元件
ID
号,后面的表示该元件的数量
*/
private
String getResultStr() {
return
tm
.toString().replace(
"}"
,
""
).replace(
"{"
,
""
).replace(
" "
,
""
);
}
/*******************
以下方法为功能性方法,为上面的步骤二服务
OK*******************/
}
}