ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 17037|回复: 33

[求助] BOM递归续 增加对应产品

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2011-2-12 15:24 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
首先感谢三坛老窖的帮助,解决了核算的问题,
在实际应用中,发现核对比较困难,需要增加对应成品信息。
如需求材料1为10KG,他对应的产品为产品1计5件,产品2计3件等,这样的话,可以方便核对了。
请高手协助修改,原代码我都看不懂,看着看着就晕了。
另外,如果有子件规格,如何加进去,使在材料需求中也显示出来,目前使用的方法为通过VLOOKUP找的。
原代码如下,详见附件
Const MAXTAB As Byte = 10
Dim dicBOM, dicM
Private Sub CommandButton1_Click()
Dim i&, arr

i = Worksheets("BOM").Range("A" & Cells.Rows.Count).End(xlUp).Row
arr = Worksheets("BOM").Range("A2:C" & i)
Set dicBOM = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(arr)
    dicBOM(arr(i, 1)) = dicBOM(arr(i, 1)) & arr(i, 2) & "," & arr(i, 3) & "/"
Next

i = Range("A" & Cells.Rows.Count).End(xlUp).Row
arr = Range("A2:B" & i)
Set dicM = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(arr)
    BOM arr(i, 1), arr(i, 2), 0
Next i

i = dicM.Count
With Worksheets("需求")
    .Range("A1").CurrentRegion.Offset(1).ClearContents
    .Range("A2").Resize(i) = Application.Transpose(dicM.keys)
    .Range("B2").Resize(i) = Application.Transpose(dicM.items)
    .Select
End With

Set dicBOM = Nothing
Set dicM = Nothing
End Sub

Private Sub BOM(ByVal Pid As String, ByVal N As Double, ByVal iTab As Long)
    Dim i&, temp1, temp2
    If iTab >= MAXTAB Then Exit Sub
    If dicBOM.exists(Pid) Then
        temp1 = Split(dicBOM(Pid), "/")
        For i = 0 To UBound(temp1) - 1
            temp2 = Split(temp1(i), ",")
            BOM temp2(0), N * temp2(1), iTab + 1
        Next
    Else
        dicM(Pid) = dicM(Pid) + N
    End If
End Sub

采购预算模型V2.rar

9.92 KB, 下载次数: 955

TA的精华主题

TA的得分主题

发表于 2011-2-13 09:28 | 显示全部楼层
看着看着就晕了……
确实难以理解,尤其是牵涉到递归。不过此类问题,除了用递归求解外,好像没有更通俗易懂的方法了。

我将上边代码的解题思路大致作一下讲解,希望能对楼主的理解有所帮助。
--------CommandButton1_Click 主程序---------
第一步:根据BOM表创建一个BOM字典,即dicBOM,字典的键为BOM的母件名称,项为该母件的所有子件名称+子件用量连成的串。如:产品1 由子件1、子件2、材料1等三项子件构成,用量分别是 2、4、6,则该项的值为:子件1,2/子件2,4/材料1,6/   。
第二步:创建一个需求字典,即dicM,备用。
第三步:根据计划表,生成产品产出计划数组,在数组中循环调用BOM子程序,求出该计划所涉的终端物料的需求数量。
-------BOM子程序----------------------
这是一个递归调用的子程序,它有三个输入参数:
Pid---母件名称(或产品名称),注意:它是相对的,本层的子件即为下一层的母件。
N----从顶层产品累积的本层的需求数量。
iTab---层级,可以忽略。在这儿出现,主要是防止BOM表中存在母件-子件环。
进入BOM子程序后,首先判别该产品(Pid)有无子项,即在主程序中创建的BOM字典中查看是否存在该项目。如果存在,表明它不是终端物料,否则为终端物料。
对于非终端物料,将该物料在BOM字典中的项取出来,并将其分割成一个一维数组(temp1),再在这个数组中循环。在循环体中,将temp1 的元素再次分割为数组temp2,其中就二个元素,temp2(0)为子件名称,temp2(1)为子件用量,用temp2(0)作为进入下一层的母件名称--Pid的输入参数,用temp2(1)和本层的输入参数N的乘积作为进入下一层的需求数量--N的输入参数。递归调用BOM子程序,进入下一层。
对于终端物料,将输入参数N累加到需求字典dicM中
------------------------------------------------------------------------
注:用字典和数组来求解BOM递归问题的思路来自于http://club.excelhome.net/thread-669877-1-1.html 帖中 honggexjq 大侠

TA的精华主题

TA的得分主题

发表于 2011-2-13 10:04 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
附件为添加了追踪需求来源功能的,不知是否符合楼主的原意。
------------------------------------------------------------
采购预算模型V3.rar (14.71 KB, 下载次数: 915)

至于楼主提到的在代码中加入子件规格,使之在需求表中显示。我以为:
1.可以实现。如果理解了一楼的代码,实现起来并不困难。楼主可自己试一试。
2.没有必要。能用简单的函数实现所要的功能,不是更好吗?再说,一般而言,所有的物料信息应该集中在一个表中,其他地方需要物料信息,如类别、规格型号、计量单位、标准成本等等,都从该表引用,这样更符合数据管理规范。像楼主提供的附件,在BOM表上,其实不应该出现子件规格字段的,而应该增加一个物料信息表。

TA的精华主题

TA的得分主题

发表于 2012-10-5 15:24 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
三坛老窖 发表于 2011-2-13 10:04
附件为添加了追踪需求来源功能的,不知是否符合楼主的原意。
------------------------------------------ ...

不错      

TA的精华主题

TA的得分主题

发表于 2012-10-9 10:28 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2012-12-22 20:59 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
非常感谢非常感谢

TA的精华主题

TA的得分主题

发表于 2013-9-6 10:05 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
三坛老窖 发表于 2011-2-13 10:04
附件为添加了追踪需求来源功能的,不知是否符合楼主的原意。
------------------------------------------ ...

终于被我找着原作者了,之前下载了你的“采购预算模型V1”也是碰到楼主一样的需要加入产品各类信息再展开,因为直接用函数引用的话有时候数据量过大就会导致运算缓慢。俺是初学者,代码认识我我不认识它,求老师帮加入扩大展开范围的代码,感激不尽!!!

采购预算模型(作者:三坛老窖).rar

21.64 KB, 下载次数: 264

TA的精华主题

TA的得分主题

发表于 2017-12-15 13:58 | 显示全部楼层
三坛老窖 发表于 2011-2-13 09:28
看着看着就晕了……
确实难以理解,尤其是牵涉到递归。不过此类问题,除了用递归求解外,好像没有更通俗易 ...

@ 三坛老窖   我在论坛里看了很多有关BOM展开计算的贴子,觉得您的求解思跟最为通俗易懂。我在实际的使用过程对于BOM展开计算时还需要扣减库存,即是上一级库存如果大于等于需求量则,不再展计算;如果库存小于需求量,则展开计算,但传入下一级的需求量是上级库存减去库存后的需求数量。我的初步构思是增加一个库存工作表,并在VBA里面创建一个字典用于装载库存的数据,BOM展开计算时先与库存进行比较,扣减库存后,再计算。库存字典每次扣减进行更新一次
       但我更改后的VBA代码计算结果不正确,请帮忙修正。(附件为实例)

        如能修改代码,应用到实际的生产环境中去,真是万分感谢!

Private Sub BOM(ByVal Pid As String, ByVal N As Double, ByVal iTab As Long, _
                ByVal PName As String, ByVal PNum As Double)
    Dim i&, temp1, temp2                                                        '定义i为长整型,temp1/temp2为临时数组

    Dim iINV&, arrINV
    iINV = Worksheets("库存").Range("A" & Cells.Rows.Count).End(xlUp).Row
    arrINV = Worksheets("库存").Range("A2:B" & iINV)

    For iINV = 1 To UBound(arrINV)
        dicINV(arrINV(iINV, 1)) = dicINV(arrINV(iINV, 1)) + Val(arrINV(iINV, 2))
    Next

    If iTab >= MAXTAB Then Exit Sub                                             '如果拆分的层次大于10次,就退出程序
    If dicBOM.exists(Pid) Then                                                  '根据存货编码或名称在Bom字典里进行查找匹配,如果存在就将dicBOM字典对应的item内容进行分割并赋值给临时数组temp1
        temp1 = Split(dicBOM(Pid), "/")
        For i = 0 To UBound(temp1) - 1                                          '将BOM明细的存货编码和耗用量进行分割并赋值组临时数组temp2
            temp2 = Split(temp1(i), ",")

            If dicINV(Pid) >= N Then

            dicINV(Pid) = dicINV(Pid) - N
            GoTo 30

            Else

            N = N - dicINV(Pid)

            dicINV(Pid) = 0

            End If

            BOM temp2(0), N * temp2(1), iTab + 1, PName, PNum                   '父物料的数量*BOM单位耗料数量

        Next
    Else
30:        dicM(Pid) = dicM(Pid) + N                                            '如果不存在物料需求量就等于父物料的数量
        If Not dicPP.exists(PName & Pid) Then                                   '如果某项物料不存在下级物料,则该项物料的item值为空
            dicPP(PName & Pid) = ""
            dicP(Pid) = dicP(Pid) & PName & "(" & PNum & ") " & "/"                   '
        End If
    End If
End Sub



采购预算模型V3-扣减库存计算需求.rar

15.86 KB, 下载次数: 105

TA的精华主题

TA的得分主题

发表于 2017-12-15 21:00 | 显示全部楼层
wbjjzhu 发表于 2017-12-15 13:58
@ 三坛老窖   我在论坛里看了很多有关BOM展开计算的贴子,觉得您的求解思跟最为通俗易懂。我在实际的使用 ...

已按要求帮你修改,你测试一下,看是否有误。
--------------------------------------------------------
采购预算模型V3-扣减库存计算需求.rar (17.71 KB, 下载次数: 282)

TA的精华主题

TA的得分主题

发表于 2017-12-16 18:16 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
三坛老窖 发表于 2017-12-15 21:00
已按要求帮你修改,你测试一下,看是否有误。
------------------------------------------------------ ...

@ 三坛老窖     你好,修改后的表格我代入实际的数据后,测试计算结果:当订单表的行数小于等于6行时,计算结果正常,大于7行后计算结果不正确。(仅对示例中的20040079物料进行核对),请帮忙查找原因,是那里计算有误。
错误.jpg

采购预算模型V3-扣减库存计算需求-已经核对计算结果20171216-002.rar

411.62 KB, 下载次数: 256

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-18 11:31 , Processed in 0.042652 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表