发布一个无限级别分类算法

sfply 2004-11-24 02:08:23
由于目前在做库存管理系统,因此不可避免地遇到如“主材-电子材料-二极管-发光二极管”这类无限分类的问题。

由于没有时间去参考前辈们的做法,就自己写了一个,请高人不吝赐教.

数据库Class
ID 自动编号
ClassID 分类编号(必须唯一,建议采用1001-100101-10010101..这种直观的方法编号)
ClassName 分类名称
FatherID 父分类ID,一级分类为0

1、取得数据结构

i = 0
set rs = conn.execute("select * from Class order by ClassID")
if not rs.eof and not rs.bof then
do while not rs.eof and not rs.bof
i = i + 1
MyClassArray = MyClassArray & "|" & rs("ID") & "," & rs("WH_ClassName") & "," & rs("WH_ClassFather") & "," & rs("WH_ID")
rs.movenext
loop
end if
ArrayMyClass = split(MyClassArray,"|")

以上这个SQL将所有分类信息放在一个字符串中,以后就不需要再查询数据库了,因此可以考虑放在Application中,就可以免读数据库了

2、无限追溯父路径
比如,主材-电子材料-二极管-发光二极管
我目前所处在的位置是“发光二极管”,那么怎么把前面的所有父级别类别都显示并能够连接过去呢?

参数是?classid=

Private Function GetClass(id,urlstring) '无限分类列
for i = 0 to ubound(ArrayMyClass)
if ArrayMyClass(i) <> "" then
if split(ArrayMyClass(i),",")(0) = id then
if split(ArrayMyClass(i),",")(2) <> 0 then '这里控制如果追溯到一级分类了就不再调用嵌套调用过程了
GetClass = GetClass(split(ArrayMyClass(i),",")(2),"> <a href=?ClassID="&split(ArrayMyClass(i),",")(0)&">"&split(ArrayMyClass(i),",")(1)&"</a> "&urlstring)
else
GetClass = "> <a href=?ClassID="&split(ArrayMyClass(i),",")(0)&">"&split(ArrayMyClass(i),",")(1)&"</a> "&urlstring
end if
end if
end if
next
End function

response.write GetClass(request("ClassID"),"")
这里request("ClassID")是当前的分类ID,GetClass要两个参数,第一个是当前ID,第二个用于保存历史父路径信息

index.asp?classid=13 得到的执行结果是(HTML形式)
<a href=?ClassID=1>主材</a> > <a href=?ClassID=7>电子材料</a> > <a href=?ClassID=10>二极管</a> > <a href=?ClassID=13>发光二极管</a>

3、增加新分类
使用思想是和上面一样的
得到的形式是结果是这样的(HTML形式)
<select size="1" name="FatherID">
<option value=1>主材[1001]</option>
<option value=7>主材-电子材料[100101]</option>
<option value=10>主材-电子材料-二极管[10010101]</option>
<option value=13>主材-电子材料-二极管-发光二极管[1001010101]</option>
<option value=11>主材-电子材料-三极管[10010102]</option>
<option value=12>主材-电子材料-电阻[10010103]</option>
<option value=8>主材-塑料制品[100102]</option>
<option value=14>主材-塑料制品-塑胶材料[10010201]</option>
<option value=9>主材-金属材料[100103]</option>
<option value=2>辅料[1002]</option>
<option value=3>半成品[1003]</option>
<option value=4>成品[1004]</option>
<option value=5>工具设备[1005]</option>
<option value=6>其他[1006]</option>
</select>

这样排序井然,都得助于分类编号的标准,因为SQL是用分类排序的:)

过程代码
Private Function GetClassName(id,urlstring) '无限分类树
for i = 0 to ubound(ArrayMyClass)
if ArrayMyClass(i) <> "" then
if split(ArrayMyClass(i),",")(0) = id then
if split(ArrayMyClass(i),",")(2) <> 0 then
GetClassName = GetClassName(split(ArrayMyClass(i),",")(2),trim("-"&split(ArrayMyClass(i),",")(1))&urlstring)
else
GetClassName = trim(split(ArrayMyClass(i),",")(1))&urlstring
end if
end if
end if
next
End function
调用
<select size="1" name="FatherID">
<%
for j = 0 to ubound(ArrayMyClass)
if ArrayMyClass(j) <> "" then response.write "<option value="&split(ArrayMyClass(j),",")(0)&">"&GetClassName(split(ArrayMyClass(j),",")(0),"")&"["&split(ArrayMyClass(j),",")(3)&"]</option>"&vbCrLf
next
%>
</select>
...全文
473 点赞 收藏 17
写回复
17 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
777dragon 2004-11-25
看看:)
回复
prcgolf 2004-11-25
up
回复
sfply 2004-11-24
TO to_be_or_not_to_be(to be)
ClassID 分类编号(必须唯一,建议采用1001-100101-10010101..这种直观的方法编号)
我说了编号是自由的,你怎么编都可以,因为其中使用了自动编号,这个不影响的,只是为了记忆和使用方便而设置的。因为以前我是做会计的,自然就会想到会计科目编号方式:)

TO bozy(无限)
我比较懒,呵呵一般是在程序尾部调用一个过程专门用于释放资源管理数据库连接的:)

TO phckt(泡壶茶)
反向搜索道理也是一样的,只不过结果却不同,因为父分类会有多个子分类。
我的第三点就用到了这个接近的处理,列出所有的存在的路径。
回复
surferc 2004-11-24
楼上 我是找到某一节点下的所有节点id查询得到的,我想楼主差不多也是这样做的。
回复
phckt 2004-11-24
有个问题不太清楚
点击发光二极管可以列出发光二极管相关记录,而点击电子材料时,如何得到二极管,三极管...的所有记录呢?
回复
mrshelly 2004-11-24
ID就自动编号好了。
回复
1001-100101-10010101这样分的话,到了1000次,长度是多少?
回复
jiank 2004-11-24
我也是这样做的,呵呵,接分
回复
是是非非 2004-11-24
学习+接分
回复
alern_zyb 2004-11-24
收藏、学习、帮你顶
回复
古侠 2004-11-24
学习,受教了
回复
surferc 2004-11-24
楼主的方法挺好的,昨天我刚好有同样的问题,起初我设计的和楼主的一样,但我的需求里面还有可能出现一对多的情况所以去数据库版问了一下,得到了改进的答案。原理和楼主的一样都是父路径追溯只不过多了一对多和多对多的关系。虽然一张表也能实现但下面的这种设计更清晰一些。请楼主参考指正。

class分成两张表

tb1----------
类别
id ClassName
1 大类一
2 大类二
3 小类/1
4 小类/2
5 小类/3
6 小类/4
7 小类/5

tb2----
关系
类别id 所属类别id
3 1
3 2
5 3
6 5
7 4

回复
bozy 2004-11-24
做的不錯!
我以前也用過類似的分類方法,倒不是因爲類別層級比較多,而是因爲它的每個級別的下一級都可能是產品,這樣的方法處理起來也比較方便些.
有個小建議:使用完數據庫/記錄集之後,及時關閉掉可能會更好些.
兄弟辛苦了!
回复
yqh1314 2004-11-24
学习学习` 帮你顶
回复
sfply 2004-11-24
这个还没改
MyClassArray = MyClassArray & "|" & rs("ID") & "," & rs("WH_ClassName") & "," & rs("WH_ClassFather") & "," & rs("WH_ID")

应该是

MyClassArray = MyClassArray & "|" & rs("ID") & "," & rs("ClassName") & "," & rs("FatherID") & "," & rs("ClassID")

分类序号|分类名称|父序号|分类编号
回复
lishuai818 2004-11-24
深了 学习
回复
sfply 2004-11-24
这个设计用到的父路径追溯方法是嵌套调用过程

执行效率可能不是太高,但我想应该算是比较简单明了的吧,希望对新人有所帮助

高手就多指点一下,怎么才能够更进一步提高效率吧:)
回复
发帖
ASP
创建于2007-09-28

2.8w+

社区成员

ASP即Active Server Pages,是Microsoft公司开发的服务器端脚本环境。
申请成为版主
帖子事件
创建了帖子
2004-11-24 02:08
社区公告
暂无公告