|
前几天有版友发帖《求个查询,见附件。Bom 成本》,我当时回复了句,分解到底层就好了。不过那几天比较忙就没有继续写例子了。一般来说,对于树形结构的问题,都是层层钻取,直达底层最后得出结果的。至于这过程中,使用递归算法还是使用循环算法,则看个人喜好了。通常情况下,递归能解决的问题,循环一样没问题的。只不过有些版友可能对递归算法不太熟悉,常常会造成一些困惑罢了。
递归其实并不算太难,论坛上也有一些经典写法。例如,斐波纳契(Fibonacci)数列和树形菜单。
我们现在回头来看看这个例子。假定某个成品需要1个001,那么拆解下来,最终需要几个基础部件呢?按我的理解是,一个001=1个002+2个003,1个002=1个004+1个009,1个003=2个004+1个005,相当于5个004+2个005+1个009…如此类推,最终无法分解之后则是我们想要的结果。拆解过程如图所示:
按惯例,还是先上传代码和附件。- Function getParent(ByVal dicParent As Dictionary) As Dictionary
- Dim rst As New ADODB.Recordset
- Dim dict As New Dictionary
- Dim dict1 As New Dictionary
- Dim strParent As String
- Dim strWh As String
- Dim strSQL As String
- Dim i As Long
- Dim j As Long
-
- For i = 0 To dicParent.Count - 1
- strParent = dicParent.Keys(i)
- strSQL = "select "
- strSQL = strSQL & " 子编码,用量 from Bom明细表 where 父编码='" & strParent & "'"
- rst.Open strSQL, CurrentProject.Connection, adOpenKeyset, adLockOptimistic
- '如果存在下级
- If rst.RecordCount > 0 Then
- Do Until rst.EOF
- If dict1.Exists(rst(0).Value) Then
- '如果已经存在键值,则将合计。例子里BOM有互相交叉的情况,因此加上这句。
- '例如,002和003分属001,按一般原则,接下来应该是两条无交集的支线,而例子里002和003都含有004
- dict1.Item(rst(0).Value) = dict1.Item(rst(0).Value) + rst(1).Value * dicParent.Items(i)
- Else
- '如果不存在键值,表示得到新物料。
- dict1.Add rst(0).Value, rst(1).Value * dicParent.Items(i)
- End If
- rst.MoveNext
- Loop
- Else
- '如果不存在新的下级物料,则进行合计
- dict1.Item(strParent) = dict1.Item(strParent) + dicParent.Items(i)
- End If
- rst.Close
- Next
- '拼接条件子句,备用
- Set dict = dict1
- For i = 0 To dict.Count - 1
- strWh = strWh & "父编码='" & dict.Keys(i) & "' or "
- Next
- strSQL = "select"
- strSQL = strSQL & " count(*) from Bom明细表 where " & Left(strWh, Len(strWh) - 4)
- rst.Open strSQL, CurrentProject.Connection, adOpenKeyset, adLockOptimistic
- '如果找到记录,表示至少还有一个没到最底层的部件,执行递归
- If rst(0) > 0 Then
- Set getParent = getParent(dict1)
- Else
- '如果找不到,则表示已到最底层,无法再分解。直接赋值即可。
- Set getParent = dict
- End If
- rst.Close
- End Function
复制代码 执行的结果如下:
附件如下:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|