注册 登录
编程论坛 VB6论坛

如何用递归实现?

yuk_yu 发布于 2014-03-19 12:32, 1790 次点击
我很想学习下递归算法,附件中的结果是正确的,用的是字典,我还是想请大家用递归的方法帮忙解答下!谢谢
数据在excel中,我想改为SQL,用递归方便些。
只有本站会员才能查看附件,请 登录

1.输入A,得到B1,B2,B3和Usage
2.再用B1,B2,B3中Component  Type不为Rawpart的结果为条件查询,B1得到C1,C2;B2得到D1和各自的Usage
3.C1,C2,D1继续用Component  Type不为Rawpart的结果为条件查询,C1结果得到E1和Usage
4. 将一二三每次的到的Component  Type为Prepped和Rawpart分开格式如下
5.这个只有三层,我的正式数据层次不确定,但逻辑都这样。因此用递归写成函数可能较好。
30 回复
#2
owenlu19812014-03-19 13:28
用VB+ACCESS做的,SQL的话思路应该差不多

Dim Conn As New ADODB.Connection, Rs As New ADODB.Recordset, Rs_1 As New ADODB.Recordset
Dim PN As String, Component As String, Component_Type As String, Usage As Integer
Private Sub BOM_Run()
PN = A
Rs.Open "Select * from BOM where Assembly = '" & PN & "'", Conn, 1, 1  ------ BOM为上阶材料和下阶材料的对应关系表
If Not Rs.EOF Then
    Rs.Movefirst
    Do While Not Rs.EOF
        Component = Rs.Fileds("Component")
        Component_Type = Rs.Fileds("Component_Type")
        Usage = Rs.Fileds("Usage")
        Conn.Excute ("Insert into BOM_A Values('" & PN & "','" & Component & "','" & Component_Type & "'," & Usage & ")")  --- BOM_A 为 A料的BOM表
        Rs.MoveNext
    Loop
    Rs.Close
Else
    MsgBox "没有找到材料BOM:" & PN
    Rs.Close
    Exit Sub
End If

Rs_Qty = 1
Do Until Rs_Qty = 0
    Rs.Open "Select * from BOM_A where [Component Type] <> '" & RawPart & "'", Conn, 1, 1
    Rs_Qty = Rs.RecordCount
    If Rs_Qty <> 0 Then
        Rs.Movefirst
        Do While Not Rs.EOF
            PN = Rs.Fileds("Component")
            Rs_1.Open "Select * from BOM where Assembly = '" & PN & "'", Conn, 1, 1  
            If Not Rs_1.EOF Then
                Rs_1.Movefirst
                Do While Not Rs.EOF
                    Component = Rs_1.Fileds("Component")
                    Component_Type = Rs_1.Fileds("Component_Type")
                    Usage = Rs_1.Fileds("Usage")
                    Conn.Excute ("Insert into BOM_A Values('" & PN & "','" & Component & "','" & Component_Type & "'," & Usage & ")")
                    Rs_1.MoveNext
                Loop
                Rs.Close
            Else
                MsgBox "没有找到材料BOM:" & PN
                Rs_1.Close
                Exit Sub
            End If
            Rs.MoveNext
        Loop
        Rs.Close
    Else
        Rs.Close
        Exit Do
    End If
Loop
MsgBox "展BOM成功!"
End Sub
#3
yuk_yu2014-03-19 14:16
回复 2楼 owenlu1981
谢谢,可以将你测试的数据附件传上来看看吗?谢谢
#4
owenlu19812014-03-19 14:28
回复 3楼 yuk_yu
上阶材料和下阶材料的对应关系表给我下
#5
yuk_yu2014-03-19 14:57
回复 4楼 owenlu1981
谢谢

[ 本帖最后由 yuk_yu 于 2014-3-19 15:55 编辑 ]
#6
owenlu19812014-03-19 15:30
只有本站会员才能查看附件,请 登录
#7
owenlu19812014-03-19 15:31
看看是否OK
#8
yuk_yu2014-03-19 15:54
回复 7楼 owenlu1981
非常感谢!!
#9
owenlu19812014-03-19 17:07
百分?
#10
yuk_yu2014-03-19 17:46
回复 9楼 owenlu1981
可否改为函数,方便直接调用!谢谢
#11
lowxiong2014-03-19 19:21
没有看到递归
#12
owenlu19812014-03-19 19:33
函数不会搞,之前的VB程式可以优化如下
程序代码:

Private Sub Command1_Click()
PN = Trim(Text1.Text)
If PN = "" Then
    Exit Sub
End If
Assembly = PN
Conn.Execute ("Delete * from BOM_A")
If Rs.State = 1 Then
    Rs.Close
End If
Rs.Open "Select * from BOM where [Assembly] = '" & PN & "'", Conn, 1, 1 ' BOM为上阶材料和下阶材料的对应关系表
If Not Rs.EOF Then
    Rs.MoveFirst
    Do While Not Rs.EOF
        Component = Rs.Fields("Component")
        Component_Type = Rs.Fields("Component_Type")
        Usage = Rs.Fields("Usage")
        Conn.Execute ("Insert into BOM_A Values('" & PN & "','" & Assembly & "','" & Component & "','" & Component_Type & "'," & Usage & ")")  '--- BOM_A 为 A料的BOM表
        Rs.MoveNext
    Loop
    Rs.Close
Else
    MsgBox "没有找到材料BOM:" & Assembly
    Rs.Close
    Exit Sub
End If

Rs_Qty = 1
Do Until Rs_Qty = 0
    Rs.Open "Select * from BOM_A where [Material] = '" & PN & "' and [Component_Type] <> 'RawPart' and [Component] not in (Select distinct [Assembly] from BOM_A)", Conn, 1, 1
    Rs_Qty = Rs.RecordCount
    If Rs_Qty <> 0 Then
        StrSQL = "Insert into BOM_A Select * from (Select '" & PN & "' as [Material],A.[Component] as [Assembly],B.[Component],B.[Component_Type],B.[Usage] from (Select Distinct [Component] from BOM_A " & _
                     "where [Component_Type] <> 'RawPart' and [Component] not in (Select distinct [Assembly] from BOM_A)) as A Left join BOM B on A.[Component]=B.[Assembly])"
        Conn.Execute (StrSQL)
    Else
        Rs.Close
        Exit Do
    End If
    Rs.Close
Loop

Rs.Open "Select * from BOM_A where [Material] = '" & PN & "'", Conn, 1, 1
Set DataGrid1.DataSource = Rs
DataGrid1.Refresh
End Sub


[ 本帖最后由 owenlu1981 于 2014-3-19 23:05 编辑 ]
#13
yuk_yu2014-03-20 09:17
回复 11楼 lowxiong
版主,可否帮忙写一个递归函数,我想学习下,owenlu1981帮我解决了问题,但如果我一次查询多个Assembly就不太方便, 我想是否可用递归加数组可以解决?谢谢

[ 本帖最后由 yuk_yu 于 2014-3-20 09:19 编辑 ]
#14
lowxiong2014-03-20 13:04
回复 13楼 yuk_yu
其实我没有看懂你的意思,但我看懂了你的数据库的数据关系,应该是类似于文件目录的结构,穷尽目录路径的确是递归完成的,但你的意图似乎不是穷尽路径,所以我没看懂。
#15
owenlu19812014-03-20 13:55

目的是找一个产品的所有原材料,也就是通过成品找半成品,通过半成品找原材料
#16
yuk_yu2014-03-20 14:22
回复 14楼 lowxiong
我重新作了说明,请帮忙再看看,谢谢
只有本站会员才能查看附件,请 登录
#17
lowxiong2014-03-20 14:23
SubAssy:原材料   英语翻译:半成品
Prepped:半成品   英语翻译:准备、预备学校
RawPart:成品     英语翻译:Raw Part,原始的一部分
#18
yuk_yu2014-03-20 14:23
回复 15楼 owenlu1981
完全正确!谢谢
#19
yuk_yu2014-03-20 14:26
回复 17楼 lowxiong
正确就是成品找半成品,预计工,原材料;半成品找预计工,原材料;预计工找原材料,逐级递减
#20
风吹过b2014-03-20 16:24
都已结贴,再发短消息给我干什么?
#21
风吹过b2014-03-20 16:26
只有本站会员才能查看附件,请 登录
#22
yuk_yu2014-03-20 16:38
回复 20楼 风吹过b
不好意思,我想用递归函数实现
#23
yuk_yu2014-03-20 16:40
回复 21楼 风吹过b
分解是正确的,但还没有将数据分开,我要的结果请参考16楼附件,谢谢
#24
风吹过b2014-03-20 17:23
晕死,我代码是按你 1楼 的代码做的。

你 16 楼的要求,我有ASP 现在的代码。生成HTML 菜单 用的。

。。。。。。。。。。。


好吧。你 16 楼的要求递归代码的流程如下:

函数入口(传入需要查询的名字)
查询这个名字对应的 记录。
  do
  先添加一级记录(树型)
     以本级记录为名字,递归调用 自己查询是否存在下一级。
  loop
展开本级树内容
函数结束

流程就是这样的。
你要递归,那么生成的结果
要么使用 树型结构, treeview
要么使用 列表       listview 或 listbox

没时间再去按你 16 楼的要求重做程序了。
就这样了吧。


附件是 按1楼做的代码。做了1个多小时。主要我没装 数据库软件。
只有本站会员才能查看附件,请 登录
#25
风吹过b2014-03-20 21:46
只有本站会员才能查看附件,请 登录


只有本站会员才能查看附件,请 登录


只有本站会员才能查看附件,请 登录
#26
xiaoshi1122014-03-21 10:58
学习了,不错不错。。。。
#27
yuk_yu2014-03-21 10:58
回复 25楼 风吹过b
谢谢版主!!
#28
yuk_yu2014-03-21 11:01
回复 25楼 风吹过b
可否将这个的附件传上来?谢谢
#29
风吹过b2014-03-21 11:26
只有本站会员才能查看附件,请 登录


本想今天再检查一下代码,但没时间了。
#30
风吹过b2014-03-21 11:37
1、查询的,只能选择 成品、半成品、预加工。如果范围不对,需要修改代码里的限制条件。

2、配料表管理里:
   左边选择是可以有下级配方的,也是限定是 成品、半成品、预加工 。

3、四种类型是数据库里定义的,名字不能改,如果改了,那程序里限定也要对应改。

4、配料表里,那个 用量,估计你要再考虑一下,怎么办。
   比如说, 成品里包括 预加工1,1份 和 半成品1,2份 ,预加工1里包括原料1,1份,半成品1里也包括原料1,2份。那说这个最后的用量统计里怎么办?
   是显示  原料1,1份和 原料1,2份,分两行显示。还是合并,然后 显示 原料1,5份??
这些都没有规划,所以程序里都没有去考虑这种情况。

5、这个程序原来是计划写成三个程序的,所以每个窗体都是确保独立运行,自己初始化自己所需的内容,不依赖别的窗体。

[ 本帖最后由 风吹过b 于 2014-3-21 11:55 编辑 ]
#31
yuk_yu2014-03-21 12:13
回复 30楼 风吹过b
十分感谢版主详尽解答!!
1