我是新来的。
我正在尝试建立一个快速的VBA程序,通过层次结构(BOM级别)和状态来“压平”物料清单。
示例数据显示BOM,其中Car作为顶级装配,Wheel和Engine作为第二级装配,以及构成BOM第三和第四级上的那些装配的各种子零件。
我想删除任何值为“ZE
”,“ZM
”的行或C
列中的空白。
我还想删除任何值为“ZA”的行,并且也是另一个“ZA
”项的直接子项。 (示例 - 从BOM中删除Rim行,因为Wheel是Parent“ZA
”项目
这是我到目前为止所做的:
Sub deletechildren()
Dim lr As Long, i As Long, k As Long
lr = Cells(Rows.Count, 1).End(xlUp).Row
For i = lr To 1 Step -1
If i > 2 Then
k = i - 1
End If
If Cells(i, 3).Value = "ZA" And Cells(i, 1).Value = Cells(k, 1).Value Then
Cells(i, 3).EntireRow.Delete
ElseIf Cells(i, 3).Value = "ZE" Then
Cells(i, 3).EntireRow.Delete
ElseIf Cells(i, 3).Value = "ZM" Then
Cells(i, 3).EntireRow.Delete
ElseIf Cells(i, 3).Value = "" Then
Cells(i, 3).EntireRow.Delete
End If
Next i
lr = Cells(Rows.Count, 1).End(xlUp).Row
End Sub
我在If语句的第一部分出现了一些错误,我要从“ZA
”父级解析出任何“ZA
”状态的子项。
有什么想法吗?
答案 0 :(得分:0)
问题的一部分是变量k
未被用于正确识别父/子关系(如果我正确理解您的要求)。在您的情况下,您将每个值与其上方的行进行比较,但在物料清单中,父行可能是上面的多行,并由层次结构值-1表示。
请参阅下面的修订代码。在代码中,我们首先删除我们知道要删除的任何行(ZM,ZE和Blanks)。接下来,我们循环层次结构值,直到我们在当前行上方找到一个层次结构值。这成为父行,从那里我们测试。
如果您需要其他帮助,请与我们联系。
Sub deletechildren()
Dim lr As Long, i As Long, k As Long
lr = Cells(Rows.Count, 1).End(xlUp).Row
For i = lr To 1 Step -1
If i > 2 Then
k = i - 1
If Cells(i, 3) = "ZE" Or Cells(i, 3) = "ZM" Or Cells(i, 3) = "" Then
Rows(i).Delete
Else
k = i - 1
Do Until i <= 2 Or (Cells(i, 1) - Cells(k, 1) = 1)
k = k - 1
Loop
'Now, k represents the parent row.
If Cells(i, 3) = "ZA" And Cells(k, 3) = "ZA" Then
Rows(i).Delete
End If
End If
End If
Next i
lr = Cells(Rows.Count, 1).End(xlUp).Row
End Sub
答案 1 :(得分:0)
我使用Autofilter()
对象的Sort()
和Range
方法,如下所示:
Option Explicit
Sub deletechildren()
Dim i As Long
With Worksheets("BOM")
With .Range("A1:D" & .Cells(.Rows.Count, 1).End(xlUp).Row)
.AutoFilter Field:=3, Criteria1:=Array("ZE", "ZM", "="), Operator:=xlFilterValues
With .Offset(1).Resize(.Rows.Count - 1)
If Application.WorksheetFunction.Subtotal(103, .Columns(1)) > 1 Then .SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
.AutoFilter
.Sort key1:=Range("C1"), order1:=xlAscending, key2:=Range("A1"), order2:=xlAscending, Header:=xlYes
i = .Rows(.Rows.Count).Row
Do Until .Cells(i, 1) = .Cells(2, 1)
i = i - 1
Loop
If i < .Rows.Count Then .Rows(i + 1).Resize(.Rows.Count - i).EntireRow.Delete
End With
End With
End Sub
答案 2 :(得分:0)
Sub DeleteChildren()
Dim lastRow As Long
Dim i As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
If (Cells(i, 3).Value = "ZE" Or Cells(i, 3).Value = "ZM" Or Cells(i, 3).Value = "") And Cells(i, 1) <> "" Then
Rows(i).EntireRow.Delete xlShiftUp
i = i - 1
GoTo NextIteration
End If
If Cells(i, 1).Value > 1 Then
If (Cells(i, 3).Value = "ZA" And Cells(i - 1, 3).Value = "ZA") And Not Cells(i, 1).Value < Cells(i - 1, 1).Value Then ' This way is a there are multiple levels with "ZA" there can
Cells(i, 5).Value = "Delete"
End If
End If
NextIteration:
Next i
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lastRow
If Cells(i, 5).Value = "Delete" Then
Rows(i).EntireRow.Delete xlShiftUp
i = i - 1
End If
Next i
End Sub