比较Cell与Cell之上的VBA Excel

时间:2016-05-10 16:57:18

标签: excel vba excel-vba

我是新来的。

我正在尝试建立一个快速的VBA程序,通过层次结构(BOM级别)和状态来“压平”物料清单。

以下是一些示例数据: Sample BOM Data

示例数据显示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”状态的子项。

有什么想法吗?

3 个答案:

答案 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