VBA基于父项数量乘以子项数量
我正在使用一个表示为ITEM_NO的分支层次结构,其中“1.2”是“1”的第二个子级,因为没有进一步的继承(这个“1”是最顶层的父级)。我有一个代码,可以找到子-父关系,并将某个值从父行复制到子行VBA基于父项数量乘以子项数量,vba,parent-child,multiplication,Vba,Parent Child,Multiplication,我正在使用一个表示为ITEM_NO的分支层次结构,其中“1.2”是“1”的第二个子级,因为没有进一步的继承(这个“1”是最顶层的父级)。我有一个代码,可以找到子-父关系,并将某个值从父行复制到子行 Sub subgroup() 'Disable screen update Application.ScreenUpdating = False Application.DisplayAlerts = False 'Main function Dim i As Lon
Sub subgroup()
'Disable screen update
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'Main function
Dim i As Long
Dim LastRow As Long
Dim subgroup As String
Dim parent As String
With Worksheets("BOM")
LastRow = .Cells(.Rows.Count, 5).End(xlUp).Row
For i = 2 To LastRow
If i = 2 Then
subgroup = .Cells(i, 3).Value
parent = getParent(.Cells(i, 10))
ElseIf Left(.Cells(i, 10), Len(parent)) <> parent Then
subgroup = .Cells(i, 3).Value
parent = getParent(.Cells(i, 10))
Else
.Cells(i, 3).Value = subgroup
End If
Next i
End With
'Enable screen update
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Function getParent(cell As Range) As String
If Not InStr(1, cell.Value, ".") Then
getParent = cell.Value
Else
getParent = Split(cell, ".")(0) & "." & Split(cell.Value, ".")(1)
End If
End Function
子群()
'禁用屏幕更新
Application.ScreenUpdating=False
Application.DisplayAlerts=False
"主要功能",
我想我会坚持多久
最后一排一样长
作为字符串的Dim子组
将父对象设置为字符串
带有工作表(“BOM”)
LastRow=.Cells(.Rows.Count,5).End(xlUp).Row
对于i=2到最后一行
如果i=2,那么
子组=.Cells(i,3).Value
parent=getParent(.Cells(i,10))
ElseIf左(.Cells(i,10),Len(parent))父
子组=.Cells(i,3).Value
parent=getParent(.Cells(i,10))
其他的
.单元格(i,3).值=子组
如果结束
接下来我
以
'启用屏幕更新
Application.ScreenUpdating=True
Application.DisplayAlerts=True
端接头
函数getParent(单元格作为范围)作为字符串
如果不是InStr(1,单元格值“.”),则
getParent=cell.Value
其他的
getParent=Split(cell,“.”(0)和“.”&Split(cell.Value,“.”(1)
如果结束
端函数
现在,我正试图找出如何修改它,使列“I”中的子数量乘以它的父数量,无论子-父级别出现多少次。因此,如果“child 1.2.1”QTY=1
与“child 1.2”QTY=2
相乘,现在是“child 1.2.1”QTY=1*2=2
,我们更高一级,看到“child 1QTY=3
所以现在是初始值”child 1.2.1“数量=2*3=6
。我需要对表中的每一行从下到上做这件事,因为它总是按自上而下的顺序排列,而且每一项都是唯一的
下面是一个示例图像:
我用不同的颜色填充了每个传统级别。因此,在本例中,每个黄色行的数量必须与红色行的数量相乘,然后与灰色行相乘。同样,红色行与灰色行相乘
有人能帮帮我吗?使用K列中的以下公式生成新数量,如下所示: 自下而上的计算
=IFERROR(INDEX(I:I,MATCH(LEFT(J:J,FIND("#",SUBSTITUTE(J:J,".","#",LEN(J:J)-LEN(SUBSTITUTE(J:J,".",""))))-1),J:J,0))*I:I,I:I)
=IFERROR(IF(INDEX(L:L,MATCH(LEFT(J:J,FIND("#",SUBSTITUTE(J:J,".","#",LEN(J:J)-LEN(SUBSTITUTE(J:J,".",""))))-1),J:J,0))="", INDEX(I:I,MATCH(LEFT(J:J,FIND("#",SUBSTITUTE(J:J,".","#",LEN(J:J)-LEN(SUBSTITUTE(J:J,".",""))))-1),J:J,0)),INDEX(L:L,MATCH(LEFT(J:J,FIND("#",SUBSTITUTE(J:J,".","#",LEN(J:J)-LEN(SUBSTITUTE(J:J,".",""))))-1),J:J,0)))*I:I,I:I)
自上而下计算
=IFERROR(INDEX(I:I,MATCH(LEFT(J:J,FIND("#",SUBSTITUTE(J:J,".","#",LEN(J:J)-LEN(SUBSTITUTE(J:J,".",""))))-1),J:J,0))*I:I,I:I)
=IFERROR(IF(INDEX(L:L,MATCH(LEFT(J:J,FIND("#",SUBSTITUTE(J:J,".","#",LEN(J:J)-LEN(SUBSTITUTE(J:J,".",""))))-1),J:J,0))="", INDEX(I:I,MATCH(LEFT(J:J,FIND("#",SUBSTITUTE(J:J,".","#",LEN(J:J)-LEN(SUBSTITUTE(J:J,".",""))))-1),J:J,0)),INDEX(L:L,MATCH(LEFT(J:J,FIND("#",SUBSTITUTE(J:J,".","#",LEN(J:J)-LEN(SUBSTITUTE(J:J,".",""))))-1),J:J,0)))*I:I,I:I)
这个公式有什么作用?
例如1.5.3.10
左(J:J,FIND(“#”),替换(J:J,”,“#”,LEN(J:J)-LEN(替换(J:J,”,”))-1)
去掉最后一组,这样您就可以得到
1.5.3
MATCH(…[1]…,J:J,0)
将1.5.3
与第J列匹配,以获取1.5.3
索引(I:I,…[2]…)
获取通过匹配找到的行号的第I列中的值2
*I:I
并将其与当前行第I列的值相乘,因此2*2=4
IFERROR(…)
只返回当前行第I列的值。因为对于1.5
,它将剥离到1
,并尝试找到它无法找到的内容。因此,如果没有父项进行切割,则保持质量不变因此,我将把
I:J
的数据读入一个数组,使用WorksheetFunctions
进行所有计算,如公式所示,将结果保存在另一个数组中,并将结果数组写回I
列
Option Explicit
Public Sub TopToBottomCalculation()
Dim ws As Worksheet 'define worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim LastRow As Long 'find last row with data in column I
LastRow = ws.Cells(ws.Rows.Count, "I").End(xlUp).Row
Dim ArrQty() As Variant 'read quantity into array
ArrQty = ws.Range("I2", "I" & LastRow).Value
Dim ArrItm() As Variant 'read item no into array
ArrItm = ws.Range("J2", "J" & LastRow).Value
Dim iRow As Long
For iRow = LBound(ArrQty, 1) To UBound(ArrQty, 1)
Dim ParentItem As String 'get parent item number
Dim LastDotPosition As Long
LastDotPosition = InStrRev(ArrItm(iRow, 1), ".")
If LastDotPosition > 0 Then 'if no dot was found there is no parent
ParentItem = Left$(ArrItm(iRow, 1), LastDotPosition - 1)
Dim ParentMatch As Double
ParentMatch = 0 'initialize because in loop
On Error Resume Next 'next line throws error if no parent item is found
ParentMatch = Application.WorksheetFunction.Match(ParentItem, ArrItm, 0)
On Error GoTo 0 're-enable error reporting
If Not ParentMatch = 0 Then 'if there was a parent item multiplicate current quantity with parent quantity
ArrQty(iRow, 1) = ArrQty(iRow, 1) * ArrQty(ParentMatch, 1)
End If
End If
Next iRow
'write array quantity back to cells
ws.Range("I2").Resize(RowSize:=UBound(ArrQty, 1)).Value = ArrQty
End Sub
//根据评论编辑
要能够跳转不存在的父项,例如存在1
和1.2.3
但不存在1.2
,则即使没有1.2
,以下代码仍将与1
相乘
请注意,如果混合使用数字和字符串,则始终存在匹配问题。因此,请确保您输入的所有项目编号都是字符串,否则匹配将失败,并且计算错误。因此,如果您将1
作为项目编号,请确保将其作为'1
输入,撇号不会显示,但确保1
是文本而不是数字,以便匹配可以正常工作。
Option Explicit
Public Sub TopToBottomCalculation()
Dim ws As Worksheet 'define worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim LastRow As Long 'find last row with data in column I
LastRow = ws.Cells(ws.Rows.Count, "I").End(xlUp).Row
Dim ArrQty() As Variant 'read quantity into array
ArrQty = ws.Range("I2", "I" & LastRow).Value
Dim ArrItm() As Variant 'read item no into array
ArrItm = ws.Range("J2", "J" & LastRow).Value
Dim iRow As Long
For iRow = LBound(ArrQty, 1) To UBound(ArrQty, 1)
Dim ParentItem As String 'get parent item number
Dim CurrentItem As String
CurrentItem = ArrItm(iRow, 1)
Dim LastDotPosition As Long
LastDotPosition = InStrRev(CurrentItem, ".")
Dim ParentMatch As Double
ParentMatch = 0 'initialize because in loop
Do While LastDotPosition > 0 And ParentMatch = 0 'loop through parent levels until parent is found or no parent exists
ParentItem = Left$(CurrentItem, LastDotPosition - 1)
ParentMatch = 0 'initialize because in loop
On Error Resume Next 'next line throws error if no parent item is found
ParentMatch = Application.WorksheetFunction.Match(ParentItem, ArrItm, 0)
On Error GoTo 0 're-enable error reporting
If Not ParentMatch = 0 Then 'if there was a parent item multiplicate current quantity with parent quantity
ArrQty(iRow, 1) = ArrQty(iRow, 1) * ArrQty(ParentMatch, 1)
Else 'if parent item did not match then try to find the next upper level parent item
CurrentItem = ParentItem
LastDotPosition = InStrRev(CurrentItem, ".")
End If
DoEvents
Loop
Next iRow
'write array quantity back to cells
ws.Range("I2").Resize(RowSize:=UBound(ArrQty, 1)).Value = ArrQty
End Sub
你到底想把乘法的结果放在哪里?这在图片中并不清楚。您能在示例图像中显示所需的结果吗?这样我们就可以看到您希望在该示例中获得的结果了?当然!乘法的结果应该返回到有问题的初始行的数量。在示例图像中,每个黄色行乘以红色,即“当前行*2”,然后乘以结果*1。因此,在这种情况下,每个黄色的数量将是两倍大,红色的数量将是相同的,因为它乘以灰色,即1。你还想让我做一个想要的结果图像吗?请做这个结果。特别是我不明白为什么
1.5.3.1.1
和1.5.3.1.2
是黄色的?我认为它们应该是另一种颜色,因为它们比其他黄色深一层?请澄清并制作结果图,以便更好地理解.OPS!你说得对!谢谢你注意到了!我在乘法之前和之后添加了一个图像,那么您是从上到下计算,而不是像您所说的从下到上。@Eduards您可以在VBA中以相同的方式进行计算(请参见我的编辑)。如何做的想法是一样的。@Eduards我编辑了我的问题并添加了自上而下的计算方法。@Eduards请看我的编辑。示例数据非常重要。您的示例可能没有涵盖所有类型的数据。可能存在一个没有点的项目编号
(因此不存在父项)。查看我的编辑,这将忽略那些没有父项的行。@Eduards查看我的添加。如果