以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.com/bbs/index.asp)
--  专家坐堂  (http://foxtable.com/bbs/list.asp?boardid=2)
----  BOM嵌套检查的内部函数死循环。  (http://foxtable.com/bbs/dispbbs.asp?boardid=2&id=37659)

--  作者:zpx_2012
--  发布时间:2013/7/8 0:37:00
--  BOM嵌套检查的内部函数死循环。
各位大师:

下面为BOm嵌套检查的内部函数,下面红色部份不注释掉就会死循环退出。
Dim pc As String = args(0)
Dim fpc As String = args(1)
Dim dt As DataTable = args(2)
Dim tbl As Table = args(3)
Dim drs As List(of DataRow)
drs = dt.Select("键 = \'" & fpc & "\'")
If drs.count > 0 Then
    For Each dr As DataRow In drs
        fpc = dr("父键")
        If pc = fpc Then
            \'新增嵌套或父子相同的键
            Dim dr1 As DataRow = tbl.DataTable.addnew()
            dr1("_Identify") = dr("_Identify")
            dr1("键") = dr("键")
            dr1("标题") = dr("标题")
            dr1("父键") = dr("父键")
        Else
            Functions.Execute("findfather",pc,fpc,dt,tbl)
        End If
    Next
End If

 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:bom嵌套检查死循环.foxdb


请教大家是哪里条件没有设置好还是其他?谢谢!
[此贴子已经被作者于2013-7-8 0:37:49编辑过]

--  作者:狐狸爸爸
--  发布时间:2013/7/8 8:20:00
--  
逻辑只有你最清楚,解决办法很简单,自己增加两三行数据,用MessageBox跟踪执行进度,看看在该退出的地方,为什么没有退出。
--  作者:zpx_2012
--  发布时间:2013/7/8 10:16:00
--  
就是找不到才提问求助啊,我在表中已经故意录入了会嵌套的键值了。请高手直接指点一下吧。
--  作者:Bin
--  发布时间:2013/7/8 10:22:00
--  
   If pc = fpc Then  你这个条件永远不成立那就永远执行下去啊.
--  作者:Bin
--  发布时间:2013/7/8 10:32:00
--  
Dim pc As String = args(0)  \'这里这两个值不就是上次传进来的这两个值吗?
Dim fpc As String = args(1)
Dim dt As DataTable = args(2)
Dim tbl As Table = args(3)
Dim drs As List(of DataRow)
drs = dt.Select("键 = \'" & fpc & "\'")
If drs.count > 0 Then
    For Each dr As DataRow In drs
        fpc = dr("父键")
        If pc = fpc Then  \'你每次都把上次传入的两个值进行比较. 那么一旦这两个值不一样的话,那么不就永远执行ESLE死循环了吗?
            \'新增嵌套或父子相同的键
            Dim dr1 As DataRow = tbl.DataTable.addnew()
            dr1("_Identify") = dr("_Identify")
            dr1("键") = dr("键")
            dr1("标题") = dr("标题")
            dr1("父键") = dr("父键")
        Else
            Functions.Execute("findfather",pc,fpc,dt,tbl) \'然后又把这两个值传进去
        End If
    Next
End If

--  作者:zpx_2012
--  发布时间:2013/7/8 14:18:00
--  
谢谢BIN,但是我的逻辑好象没有错啊?
第一步是从表A中提取唯一的键值出来生成一个临时表dt2(为了让相同的键只执行一次循环),然后遍历这个dt2中的键先取出来第一个键值pc,然后查找其父键是否有相同的值存在,在此值的向上所有层没有循环完成这个pc是不会改变的。
第二步到原表A中去筛选出键=pc的记录出来生成集合drs,然后用pc和此集合中的每个父键比较,如果相等说明是嵌套父子相同在窗口中新增行将其记录下来。
第三步,如果pc不等于父健则再往上循环在表A中查找键等于父键的记录生成集合再用其父键值与原pc比较看是否相同,直到drs.count > 0 不成立为止。

Dim pc As String = args(0)  \'传此值进来的目的就是保持pc在没有循环完之前一直不变,用它来和父键比较。
Dim fpc As String = args(1) ’传此值进来的目的就是用来在原表A中查找键等于它的记录(第6行)。
Dim dt As DataTable = args(2)
Dim tbl As Table = args(3)
Dim drs As List(of DataRow)
drs = dt.Select("键 = \'" & fpc & "\'")  ‘在原表A中查找键等于父键的记录,实际上就是用第一个键pc的父级作为键(子级)再来查找其父级。
If drs.count > 0 Then  ‘如果还找得到,说明还没有循环完(这个集合实际上是pc的父键的集合)
  msgbox(1)  \'如果加上这行测试死循环就是这里一直显示1
    For Each dr As DataRow In drs
        fpc = dr("父键")  ‘用新的集合中的父键更新原来的父键()
        If pc = fpc Then  \'这里pc没有变,但是fpc已经不是传入来的那个了?如果相同说明嵌套,不相同才执行下一次循环。
            \'新增嵌套或父子相同的键
            Dim dr1 As DataRow = tbl.DataTable.addnew()
            dr1("_Identify") = dr("_Identify")
            dr1("键") = dr("键")
            dr1("标题") = dr("标题")
            dr1("父键") = dr("父键")
        Else
            Functions.Execute("findfather",pc,fpc,dt,tbl) \'将不变的pc和新的fpc传递给下一次循环。
        End If
    Next
End If
或者能否直接将我例子中不正确的改过来。谢谢!

--  作者:Bin
--  发布时间:2013/7/8 14:24:00
--  
你怎么不是死循环呢.  举个例子 键为FPC的行有10个. 你循环第一次.取第一行的父键和PC做对比.不等于  又执行这个函数.

那么你进来了.依然是  循环键为FPC的行, 那么依然是有10个 那么 循环第一次.取第一行的父键和PC做对比.不等于  又执行这个函数.  死循环

--  作者:zpx_2012
--  发布时间:2013/7/8 15:23:00
--  
还是不理解,比如下表

键   父键
pc   A1
A1   A
A1   B
第一次循环时得到pc的父键A1因为不等于pc,所以把pc,A1传递给下一个循环执行,此时用A1作为键查找实际上得到如下的集合
A1  A
A1  B
再遍历这个集合中的每一行,fpc=dr("父键") 实际上将fpc变为A了,然后再用pc 与A是否相等来作判断,如果不相等则又进行下一次循环用A作为键来查找得到其父键的集合,直到新的集合没有为止。

你怎么不是死循环呢.  举个例子 键为FPC的行有10个. 你循环第一次.取第一行的父键和PC做对比.不等于  又执行这个函数.

下一次循环时是用“取第一行的父键” 作为键来查找得到新的集合了。怎么还可能是原来fpc的那十行呢?




--  作者:Bin
--  发布时间:2013/7/8 15:34:00
--  
   If pc = fpc Then 问题你的条件判断呀. 
--  作者:Bin
--  发布时间:2013/7/8 15:35:00
--  
你自己写的代码你自己最清楚,一开始我看过去都看错了.