VBA中用于计算合并状态的后遍历递归

VBA中用于计算合并状态的后遍历递归,vba,post,recursion,traversal,consolidation,Vba,Post,Recursion,Traversal,Consolidation,我很抱歉,因为我是VBA新手。我正在寻找一个后遍历示例来解决以下问题。我希望递归遍历A列中的树,以计算合并状态。如我下面的示例表所示,Real Proj 1的状态为A=琥珀色。实际项目2和3的状态均为绿色。由于程序B的子项目之一包含琥珀色,因此其计算状态应为琥珀色(见C列)。或者第2行的简化合并状态为琥珀色,因为其所有子项目A、程序B和C至少包含一种琥珀色状态 列A中的值包含缩进,即第3行的程序A的缩进级别为1,第6行的实际项目2的缩进级别为3。 对于如何用递归在VBA中实现这一点,我们将不胜感

我很抱歉,因为我是VBA新手。我正在寻找一个后遍历示例来解决以下问题。我希望递归遍历A列中的树,以计算合并状态。如我下面的示例表所示,Real Proj 1的状态为A=琥珀色。实际项目2和3的状态均为绿色。由于程序B的子项目之一包含琥珀色,因此其计算状态应为琥珀色(见C列)。或者第2行的简化合并状态为琥珀色,因为其所有子项目A、程序B和C至少包含一种琥珀色状态

列A中的值包含缩进,即第3行的程序A的缩进级别为1,第6行的实际项目2的缩进级别为3。 对于如何用递归在VBA中实现这一点,我们将不胜感激。 谢谢 克里斯

这是我的解决办法。希望这对其他人也有帮助。 最好的 克里斯


你如何指出哪些项目是一个项目的子项目?它是用一个真正的Proj xxx字符串来表示的吗?明确这一点很重要,否则无法编写解决方案。另外-您不想将程序标记为绿色?这是因为它没有子项目吗?请扩大你的问题。。。这会得到更好的答案。你是用空格来缩进还是其他什么?我注意到,您没有更新问题中的图像以反映第3行的绿色应在CI列中使用CTRL+ALT+TAB=增加单元格中的缩进。小更正:第3行的状态也是现有状态。提示:Excel Developer Reference/Range.IndentLevel属性:返回或设置表示单元格缩进级别的变量值细胞或范围。可以是0到15之间的整数。
Sub TestStatus()
    Call PopulateStatus(2)
End Sub

Sub PopulateStatus(rowIndex As Integer)
    Dim level As Integer
    Dim children() As Integer
    Dim child As Integer
    Dim existingStatus As String
    Dim calculatedStatus As String
    Dim counter As Integer
    Dim aggregatedRow As Integer


    If (hasChildren(rowIndex)) Then
        aggregatedRow = rowIndex
        children = getChildren(rowIndex)

        ' Do something with the children
        For counter = LBound(children) To UBound(children)
            child = children(counter)
            Call PopulateStatus(child)
        Next counter

        'Write aggregated status of all children to column B
        calculatedStatus = getStatus(children)
        Cells(aggregatedRow, 2).Value = calculatedStatus
    Else
        existingStatus = Cells(rowIndex, 2).Value
        ' Check if we are last in children
        If (Cells(rowIndex, 1).IndentLevel > Cells(rowIndex + 1, 1).IndentLevel) Then
            'Cells(aggregatedRow, 2).Value = calculatedStatus
        End If

    End If

End Sub



Function getStatus(ByRef myArray() As Integer) As String
    Dim resultStatus As String
    Dim currentStatus As String
    Dim counter As Integer
    resultStatus = "G"

    For counter = 0 To UBound(myArray)
        currentStatus = Cells(myArray(counter), 2).Value

        If currentStatus = "R" Or resultStatus = "R" Then
            calculateStatus = "R"
            Exit Function
        End If

        If currentStatus = "A" Then
            resultStatus = "A"
        End If

        If currentStatus = "G" And resultStatus = "A" Then
            resultStatus = "A"
        End If
    Next
    getStatus = resultStatus

End Function



Function getChildren(rowIndex As Integer) As Variant
    Dim children() As Integer
    Dim myIndLevel As Integer
    Dim newIndLevel As Integer
    Dim counter As Integer
    Dim count As Integer
    myIndLevel = Cells(rowIndex, 1).IndentLevel
    count = 0
    For counter = rowIndex + 1 To 14
        newIndLevel = Cells(counter, 1).IndentLevel
        If (newIndLevel = myIndLevel + 1 And newIndLevel <> myIndLevel) Then
            ReDim Preserve children(count) As Integer
            children(count) = counter
            rowIndex = rowIndex + 1
            count = count + 1
        End If
    Next
    getChildren = children
End Function



Function hasChildren(myRow As Integer)
    Dim indLevel As Integer
    Dim newLevel As Integer
    indLevel = Cells(myRow, 1).IndentLevel
    newLevel = Cells(myRow + 1, 1).IndentLevel

    If newLevel > indLevel Then
        hasChildren = True
        Exit Function
    End If
    hasChildren = False
End Function