以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.net/bbs/index.asp)
--  专家坐堂  (http://foxtable.net/bbs/list.asp?boardid=2)
----  [求助]递归函数编写求助  (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=94565)

--  作者:ajie5211
--  发布时间:2016/12/27 8:33:00
--  [求助]递归函数编写求助

If Tables("订单计划一览表").Current IsNot Nothing Then
    Dim ddr As Row = Tables("订单计划一览表").Current
    Dim bomlx As WinForm.ComboBox = e.Form.Controls("BOM类型")
    bomlx.ComboList = DataTables("tabDIYTable37").SQLGetComboListString("F3963","F252 = \'" & ddr("品名规格") & "\'")
    Dim khdr As DataRow = DataTables("客户合同评审单").SQLFind("单号 = \'" & ddr("合同评审单号") & "\' and 序号 = " & ddr("原序号"))
    If khdr IsNot Nothing Then
        e.Form.Controls("客户料号").text = "客户料号:" & khdr("客户品名")
    Else
        e.Form.Controls("客户料号").text = "客户料号:"
    End If
    Tables("生产制令单_Table1").Filter = "销售单号 = \'" & ddr("销售单号") & "\'"
    Dim dr As DataRow = DataTables("Ft生产制令单").SQLFind("销售单号 = \'" & ddr("销售单号") & "\'")
    If dr IsNot Nothing Then
        DataTables("Ft生产制令单").LoadFilter = "销售单号 = \'" & ddr("销售单号") & "\'"
        DataTables("Ft生产制令单").Load(False)
    Else
        DataTables("Ft生产制令单").LoadFilter = "销售单号 = \'\'"
        DataTables("Ft生产制令单").Load(False)
        Dim bomzb As DataRow = DataTables("tabDIYTable37").SQLFind("[F252] = \'" & ddr("品名规格") & "\' and [F3963] = \'常规\'")
        For Each bommx As DataRow In DataTables("tabDIYTable38").SQLSelect("ID = " & bomzb("ID"))
            Dim xdr As DataRow = DataTables("Ft生产制令单").AddNew
            xdr("销售单号") = ddr("销售单号")
            xdr("料号") = bommx("F257")
            xdr("材料品号规格") = bommx("F258")
            xdr("用量") = IIF(bommx("F255") > 0 ,bommx("F259") / bommx("F255"),bommx("F259"))
            xdr("需领量") = Math.Ceiling(xdr("用量") * (ddr("数量") + CInt(e.Form.Controls("备品数").Value)))
        Next
    End If
    \'************成品库存为0且只有一种bom时直接转成零件BOM****
    For Each r As DataRow In DataTables("Ft生产制令单").DataRows
        Dim cplxdr As DataRow = DataTables("tabDIYTable24").SQLFind("F124 = \'" & r("料号") & "\'")
        If cplxdr IsNot Nothing Then
            If cplxdr("F128") = "成品" Then
                Dim cpkc As DataRow = DataTables("tabDIYTable29").SQLFind("ID = " & cplxdr("ID") & " and F160 = \'成品仓库\'")
                If cpkc IsNot Nothing Then
                    If cpkc("F162") <= 0 Then
                        Dim zdrs As new List(Of DataRow)
                        zdrs = DataTables("tabDIYTable37").SQLSelect("[F252] = \'" & r("料号") & "\'")
                        If zdrs.Count = 1 Then
                            For Each zmx As DataRow In DataTables("tabDIYTable38").SQLSelect("ID = " & zdrs(0)("ID"))
                                Dim lhs As new List(of String)
                                lhs = DataTables("Ft生产制令单").GetValues("料号","销售单号 = \'" & r("销售单号") & "\'")
                                If lhs.Contains(zmx("F257")) Then
                                    Dim xydr As DataRow = DataTables("Ft生产制令单").Find("销售单号 = \'" & r("销售单号") & "\' and 料号 = \'" & zmx("F257") & "\'")
                                    xydr("用量") = xydr("用量") + r("用量") * IIF(zmx("F255") > 0 ,zmx("F259") / zmx("F255"),zmx("F259"))
                                    xydr("需领量") = Math.Ceiling(xydr("用量") * (ddr("数量") + CInt(e.Form.Controls("备品数").Value)))
                                Else
                                    Dim xdr As DataRow = DataTables("Ft生产制令单").AddNew
                                    xdr("销售单号") = r("销售单号")
                                    xdr("料号") = zmx("F257")
                                    xdr("材料品号规格") = zmx("F258")
                                    xdr("用量") = r("用量") * IIF(zmx("F255") > 0 ,zmx("F259") / zmx("F255"),zmx("F259"))
                                    xdr("需领量") = Math.Ceiling(xdr("用量") * (ddr("数量") + CInt(e.Form.Controls("备品数").Value)))
                                End If
                            Next
                            r.Delete()
                        End If
                    Else
                        Dim wfsl As Decimal = DataTables("发料未完成制令单").SQLCompute("sum(未发量)","料号 = \'" & r("料号") & "\'")
                        If CDec(cpkc("F162")) >= wfsl - r("需领量") Then
                            If CDec(cpkc("F162")) - wfsl < r("需领量") Then
                                Dim xlh As Decimal = (r("需领量") - CDec(cpkc("F162")) - wfsl)/ r("用量")
                                Dim zdrs As new List(Of DataRow)
                                zdrs = DataTables("tabDIYTable37").SQLSelect("[F252] = \'" & r("料号") & "\'")
                                If zdrs.Count = 1 Then
                                    r("需领量") = CDec(cpkc("F162")) - wfsl
                                    For Each zmx As DataRow In DataTables("tabDIYTable38").SQLSelect("ID = " & zdrs(0)("ID"))
                                        Dim lhs As new List(of String)
                                        lhs = DataTables("Ft生产制令单").GetValues("料号","销售单号 = \'" & r("销售单号") & "\'")
                                        If lhs.Contains(zmx("F257")) Then
                                            Dim xydr As DataRow = DataTables("Ft生产制令单").Find("销售单号 = \'" & r("销售单号") & "\' and 料号 = \'" & zmx("F257") & "\'")
                                            xydr("用量") = xydr("用量") + r("用量") * IIF(zmx("F255") > 0 ,zmx("F259") / zmx("F255"),zmx("F259"))
                                            xydr("需领量") = xydr("需领量") + Math.Ceiling(xlh * IIF(zmx("F255") > 0 ,zmx("F259") / zmx("F255"),zmx("F259")) )
                                        Else
                                            Dim xdr As DataRow = DataTables("Ft生产制令单").AddNew
                                            xdr("销售单号") = r("销售单号")
                                            xdr("料号") = zmx("F257")
                                            xdr("材料品号规格") = zmx("F258")
                                            xdr("用量") = r("用量") * IIF(zmx("F255") > 0 ,zmx("F259") / zmx("F255"),zmx("F259"))
                                            xdr("需领量") = Math.Ceiling(xdr("用量") * xlh)
                                        End If
                                    Next
                                End If
                            End If
                        End If
                    End If
                    ‘Functions.Execute("zldbomdg",DataTables("Ft生产制令单").DataRows)
                End If
            End If
        End If
    Next
    \'***********更新到最新的品名***********************
    For Each r As Row In Tables("Ft生产制令单").Rows
        Dim cplxdr As DataRow = DataTables("tabDIYTable24").SQLFind("F124 = \'" & r("料号") & "\'")
        r("材料品号规格") = cplxdr("F125")
    Next
    \'**********************************************************
    Tables("生产制令单_Table1").AutoSizeHeaderRow()
    Tables("生产制令单_Table1").ExtendLastCol = True
    Tables("Ft生产制令单").ExtendLastCol = True
    Tables("生产制令单_Table3").ExtendLastCol = True
End If
\'***依权限显示******
Dim qx As Boolean = False
For Each qxdr As DataRow In DataTables("FTtabQX").SQLSelect("表名 = \'订单计划一览表\'")
    If _UserRGroups.Contains(qxdr("部门和角色")) Then
        qx = True
    End If
Next
If qx = False Then
    e.Form.Controls("保存").Visible = False
    e.Form.Controls("保存BOM").Visible = False
    e.Form.Controls("删除特殊BOM").Visible = False
    e.Form.Controls("直接打印").Visible = False
End If

 

红色部分递归函数怎么写?写了几次都是直接报错,甚至软件直接退出。


--  作者:有点色
--  发布时间:2016/12/27 9:20:00
--  

1、你先把你datacolchanged事件的代码删除,有可能死循环了。

 

2、看不懂你的逻辑,请结合实例说明。


--  作者:ajie5211
--  发布时间:2016/12/27 10:12:00
--  

根据BOM信息取出第一级BOM
图片点击可在新窗口打开查看此主题相关图片如下:1.png
图片点击可在新窗口打开查看

遍历“Ft生产制令单”(就是图中显示两个成品的明细表),如果需求的零件是成品A,并且成品仓库中库存为0,则查询成品A有几种BOM,如果只有一种BOM组成方式,则查询组成成品A的零件料号是否在“Ft生产制令单”中已出现,如果已出现则用量和需求量增加,如果没有出现,则新增零件料号及用量信息,但是,如果成品A的成品库存大于0,则确认成品A的库存是否已被其它单子占用还未发出,如果库存量大于占用量并且库存量减占用量不满足此次需求量时,则查询成品A有几种BOM,如果只有一种BOM组成方式,成品A的需求量改为库存量减占用量,查询组成成品A的零件料号是否在“Ft生产制令单”中已出现,如果已出现则用量和需求量增加,如果没有出现,则新增零件料号及用量信息。
图片点击可在新窗口打开查看此主题相关图片如下:qq截图20161227094112.png
图片点击可在新窗口打开查看


--  作者:有点色
--  发布时间:2016/12/27 10:19:00
--  
 上传实例测试。
--  作者:ajie5211
--  发布时间:2016/12/27 10:29:00
--  
 \'************成品库存为0且只有一种bom时直接转成零件BOM****
    For Each r As DataRow In DataTables("Ft生产制令单").DataRows   ‘遍历明细表
        Dim cplxdr As DataRow = DataTables("tabDIYTable24").SQLFind("F124 = \'" & r("料号") & "\'")
        If cplxdr IsNot Nothing Then
            If cplxdr("F128") = "成品" Then   ’所用零件是成品时
                Dim cpkc As DataRow = DataTables("tabDIYTable29").SQLFind("ID = " & cplxdr("ID") & " and F160 = \'成品仓库\'")
                If cpkc IsNot Nothing Then
                    If cpkc("F162") <= 0 Then  ‘成品库存小于等于0
                        Dim zdrs As new List(Of DataRow)
                        zdrs = DataTables("tabDIYTable37").SQLSelect("[F252] = \'" & r("料号") & "\'")
                        If zdrs.Count = 1 Then  ’此成品只有一组BOM
                            For Each zmx As DataRow In DataTables("tabDIYTable38").SQLSelect("ID = " & zdrs(0)("ID"))  ‘遍历这组BOM
                                Dim lhs As new List(of String)
                                lhs = DataTables("Ft生产制令单").GetValues("料号","销售单号 = \'" & r("销售单号") & "\'")  \'得到明细表已有料号集合
                                If lhs.Contains(zmx("F257")) Then  ’明细表料号已包含了需求料号,找到数据行去增加用量及需求量
                                    Dim xydr As DataRow = DataTables("Ft生产制令单").Find("销售单号 = \'" & r("销售单号") & "\' and 料号 = \'" & zmx("F257") & "\'")
                                    xydr("用量") = xydr("用量") + r("用量") * IIF(zmx("F255") > 0 ,zmx("F259") / zmx("F255"),zmx("F259"))
                                    xydr("需领量") = Math.Ceiling(xydr("用量") * (ddr("数量") + CInt(e.Form.Controls("备品数").Value)))
                                Else  ‘ 明细表没有包需求料号,明细表增加新BOM
                                    Dim xdr As DataRow = DataTables("Ft生产制令单").AddNew
                                    xdr("销售单号") = r("销售单号")
                                    xdr("料号") = zmx("F257")
                                    xdr("材料品号规格") = zmx("F258")
                                    xdr("用量") = r("用量") * IIF(zmx("F255") > 0 ,zmx("F259") / zmx("F255"),zmx("F259"))
                                    xdr("需领量") = Math.Ceiling(xdr("用量") * (ddr("数量") + CInt(e.Form.Controls("备品数").Value)))
                                End If
                            Next
                            r.Delete()   \'此成品已转换为零件BOM,不在需要了,删除
                        End If
                    Else    ’库存大于0
                        Dim wfsl As Decimal = DataTables("发料未完成制令单").SQLCompute("sum(未发量)","料号 = \'" & r("料号") & "\'")
                        If CDec(cpkc("F162")) >= wfsl - r("需领量") Then   ‘库存量在于占用未出库量
                            If CDec(cpkc("F162")) - wfsl < r("需领量") Then  ’多的库存量小于此次的需求量
                                Dim xlh As Decimal = (r("需领量") - CDec(cpkc("F162")) - wfsl)/ r("用量")  \'减去库存可用量还关多少数量
                                Dim zdrs As new List(Of DataRow)
                                zdrs = DataTables("tabDIYTable37").SQLSelect("[F252] = \'" & r("料号") & "\'")
                                If zdrs.Count = 1 Then  ’所差的产品只有一组BOM形式
                                    r("需领量") = CDec(cpkc("F162")) - wfsl  ‘产品需求量变为库存可用量
                                    For Each zmx As DataRow In DataTables("tabDIYTable38").SQLSelect("ID = " & zdrs(0)("ID")) ’遍历需求产品的产品BOM
                                        Dim lhs As new List(of String)
                                        lhs = DataTables("Ft生产制令单").GetValues("料号","销售单号 = \'" & r("销售单号") & "\'") \'得到明细表已有料号集合
                                        If lhs.Contains(zmx("F257")) Then ’明细表料号已包含了需求料号,找到数据行去增加用量及需求量
                                            Dim xydr As DataRow = DataTables("Ft生产制令单").Find("销售单号 = \'" & r("销售单号") & "\' and 料号 = \'" & zmx("F257") & "\'")
                                            xydr("用量") = xydr("用量") + r("用量") * IIF(zmx("F255") > 0 ,zmx("F259") / zmx("F255"),zmx("F259"))
                                            xydr("需领量") = xydr("需领量") + Math.Ceiling(xlh * IIF(zmx("F255") > 0 ,zmx("F259") / zmx("F255"),zmx("F259")) )
                                        Else  ‘ 明细表没有包需求料号,明细表增加新BOM
                                            Dim xdr As DataRow = DataTables("Ft生产制令单").AddNew
                                            xdr("销售单号") = r("销售单号")
                                            xdr("料号") = zmx("F257")
                                            xdr("材料品号规格") = zmx("F258")
                                            xdr("用量") = r("用量") * IIF(zmx("F255") > 0 ,zmx("F259") / zmx("F255"),zmx("F259"))
                                            xdr("需领量") = Math.Ceiling(xdr("用量") * xlh)
                                        End If
                                    Next
                                End If
                            End If
                        End If
                    End If
                    ‘Functions.Execute("zldbomdg",DataTables("Ft生产制令单").DataRows)
                End If
            End If
        End If
    Next

--  作者:ajie5211
--  发布时间:2016/12/27 10:30:00
--  

就是希望对这个增加的BOM再次查询有没有成品,有就看是否要展开。


--  作者:有点色
--  发布时间:2016/12/27 10:36:00
--  
以下是引用ajie5211在2016/12/27 10:30:00的发言:

就是希望对这个增加的BOM再次查询有没有成品,有就看是否要展开。

 

那就用一个简单的方法。弄一个字典或者表,记录需要查询的bom。名称、标志,两个信息

 

如果bom查询过了,就设置标志为1,默认为0

 

写一个死循环

 

do while true

    If 字典或表 没有为0的数据了 Then exit do

 

    \'重复的代码

loop