Reputation: 15
I am looking to make a list of heading type 1, sub-heading type 2 and sub-sub-heading type 3, and each subsequent instance of a heading increments in excel. e.g.
Outcome 1
Output 1.1
Activity 1.1.1
Activity 1.1.2
Output 1.2
Activity 1.2.1
Activity 1.2.2
Activity 1.2.3
Outcome 2
Output 2.1
Activity 2.1.1
etc
Here is my formula - getting to be a complicated nested IF statement:
IF([@Column1]="","",
IF([@Column1]="Outcome", "Outcome " & COUNTIF(tbOOA[[#Headers],[Column1]]:[@Column1], [@Column1]),
IF([@Column1]="Output","Output "& COUNTIF(tbOOA[[#Headers],[Column1]]:[@Column1],"Outcome") ***&"."&*** COUNTIF(tbOOA[[#Headers],[Column1]]:[@Column1],[@Column1]),
"Activity " & "serious help")))
In Column 1, choose from a list of 'Outcome', 'Output', or 'Activity'.
In column 2, calculate the appropriate number, e.g. Output 1.2
If the row is empty, then nothing. - Fine
If it is "Outcome", count from the header until current row for the number of instances of "Outcome". - Fine
Else if it is "Output", count the number of "Outcome"s there are. - Fine
This is where it falls apart. Trying to calculate the number after the "." (bold and italic)
I need to count the # of instances of "Output", but then this has to reset to 1 each time there is a new 'Outcome'.
The logic I'm trying to follow is:
(# of "Outputs" from the table header until the current row) minus
(# of "Outputs" from the table header until the last instance of "Outcome")
I've tried several attempts at calculating row number, but everything has been problematic.
The logic is the same for activities, though will complicate the formula even more and I haven't bothered to start on that until I can get level 2 sorted.
Does anyone know of a similar problem/solution?
Upvotes: 1
Views: 4549
Reputation: 101
I had a similar problem, where I wanted to create the multi-level heading numbers based on the indentation of list of texts. So the numbers must be generated automatically with a user-defined formula (UDF) like below:
For this to work, you must type ="1" in cell A2. The same formula in A3 (below) must be copied down to A4:A14.
=NextLevelNum(A2;IndentLevel(B3))
Function IndentLevel I took from https://professor-excel.com/how-to-return-the-indentation-of-a-cell-in-excel/
Function NextLevelNum I did myself. All code below.
Option Explicit
Public Function IndentLevel(Ref As Range) As Long
Application.Volatile
IndentLevel = Ref.IndentLevel
End Function
Public Function NextLevelNum(prevNumRef As Range, level As Integer) As String
Dim prevNum As String
Dim nums() As String
Dim prevLevel As Integer
prevNum = prevNumRef.Value
nums = Split(prevNum, ".")
prevLevel = UBound(nums) + 1
' Ensure 1 <= level <= prevLevel +1
level = WorksheetFunction.Max(level, 1)
level = WorksheetFunction.Min(level, prevLevel + 1)
ReDim Preserve nums(0 To level - 1)
If level = prevLevel + 1 Then
nums(level - 1) = "1"
Else
nums(level - 1) = CStr(CInt(nums(level - 1)) + 1)
End If
NextLevelNum = Join(nums, ".")
End Function
Upvotes: 0
Reputation: 1082
If you are open to using hidden helper columns, the formulas become much more manageable. Use Column A to hold your "Outcome", "Output", and "Activity" data.
Then use column B to deal with Outcome
numbers, column C to deal with Output
numbers, and column D to deal with Activity
numbers. Merge the final results together in Column E.
In B1
, C1
, and D1
, manually write in the first values (1
, 0
, and 0
).
Then, fill down starting from B2
with the following:
=IF(A2="Outcome",B1+1,B1)
This works by incrementing only if you have found your next Outcome.
Fill down from C2
with the following:
=IF(A2="Outcome",0,IF(A2="Output",C1+1,C1))
This works by incrementing only if you have found your next Output. It resets to 0 if you have a new Outcome.
Then fill down from D2
with
=IF(OR(A3="Outcome",A3="Output"),0,IF(A3="Activity",D2+1,D2))
It's very similar to the prior formula, but resets on an Outcome or an Output.
Finally, in D4
, merge it all together with
=B1&IF(C1>0,"."&C1&IF(D1>0,"."&D1,""),"")
&
is a string concatenate operation. By checking if the inner values are 0, we only concatenate .
and the next number if the next number is non-zero.
Upvotes: 1