我很抱歉,因为我是 VBA 的新手。我正在寻找一个后遍历示例来解决以下问题。我想递归遍历 A 列中的树来计算合并状态。如我下面的示例表“Real Proj 1”具有状态 A (=Amber)。“Real Proj 2 和 3 的状态均为 G(绿色)。由于 Program B 的子项目之一包含 Amber,因此计算状态应为 Amber(见 C 列)。或者第 2 行的“简化”合并状态为Amber 及其所有子项(“Real Proj A”,程序 B 和 C)包含至少一种 Amber 状态。
A 列中的值包含缩进,即第 3 行的“程序 A”的缩进级别 = 1,第 6 行的“Real Proj 2”的缩进级别 = 3。有关如何在 VBA 中使用递归实现此功能的任何帮助都会非常有用赞赏。谢谢,克里斯
这是我的解决方案。希望这对其他人也有帮助。最好的,克里斯
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