google-sheetsgoogle-sheets-formula

How to create grouped serial numbers using Arrayformula?


GOOGLE SHEET IMAGE

What would be the Array formulas at A1, B1, C1 & D1 (separately) to give the desired output columns as shown.

Google Sheet Link

NOTE: Difference between "Main Headings" (RELATIVES, FRIENDS, BUSINESS FRIENDS) & "names" is that the "Main Headings" has 1 space letter at the start & end.

Column A,B,C all three are same the only difference is that for the "Main Headings" Column A gives Alphabets, Column B gives Numbers & Column C gives Roman Numerals.

CONDITION FOR SERIAL NUMBERING:
(1) Serial numbering is done completely based on Columns: NAMES & PAX.
(2) If PAX is 0 then output is blank.

FOR Column A, B, C:
When PAX is blank:
-> if it's a "Main heading" then output is a Alphabet OR
-> if it's a "name" then the output is blank.

FOR Column D:
When PAX is blank:
-> if it's a "Main heading" then output is a blank OR
-> if it's a "name" then the output is serial Numbering until the next "Main Heading", then again restarts from 1 until next "Main Heading" & so on.

EDIT:
Column NAMES & PAX are input, rest are the required output.

Data:

A B C D NAME PAX
A 1 I RELATIVES
1 1 1 1 Nitin 2
2 2 2 2 Amit Nawal 1
3 3 3 3 Gulzari 2
4 4 4 4 Niraj 2
Vrindaswasni 0
Vishnuji
Tulsi 0
5 5 5 5 Narnarayan 3
6 6 6 6 Kalpesh 2
B 2 II FRIENDS
7 7 7 1 Manoj 2
8 8 8 2 Prashant 2
9 9 9 3 Alok 1
Sushilji 0
10 10 10 4 Deepak 2
Ankur
Shradhanand 0
11 11 11 5 RC College 13
C 3 III BUSINESS FRIENDS
12 12 12 1 Pawan 2
13 13 13 2 Pinky 2
14 14 14 3 Ashish 2
Bhavya

Solution

  • This formula in A2 generates the result for all the columns.

    
    =ARRAYFORMULA(LET(
       names, E2:E, pax, F2:F, i, ROW(names),
       header_count, COUNTIFS(RIGHT(names), " ", i, "<=" & i),
       serial_numbering, COUNTIFS(names, "<>", pax, "<>0", i, "<=" & i),
       result, IFNA(
         IF(RIGHT(names)=" ", 
           {
            CHAR(header_count + 64),
            header_count,
            ROMAN(header_count)
           },
           IF(pax = 0, ,
             {
              serial_numbering + {0, 0, 0},
              serial_numbering - XLOOKUP(header_count, header_count, serial_numbering)
             }
           )
         )
       ), 
       result
     ))
    

    How it works

    First, we do a running count of the headers and store it in header_count:

    header_count ← COUNTIFS(RIGHT(names), " ", i, "<=" & i),
    

    This formula returns an array with ROWS(names) rows where each row is the count of the headers encountered so far. A header is any value in the 'names' column that ends with a space " ".

    Then, we do the numbering based on the conditions mentioned in the OP (namely, name not empty and pax not 0) and assign it to serial_numbering:

    serial_numbering ← COUNTIFS(names, "<>", pax, "<>0", i, "<=" & i)
    

    Then, we go through each value in 'names'.

    If it's a header, we return the headers (Alphabet, Number, Roman) based on the current header_count:

    IF(RIGHT(names)=" ", 
       {
        CHAR(header_count + 64),
        header_count,
        ROMAN(header_count)
       },
    

    If it's not a header, and if pax is not 0 (or blank*), we return:

    {
     serial_numbering + {0, 0, 0},
     serial_numbering - XLOOKUP(header_count,   header_count, serial_numbering)
    }
    

    where

    serial_numbering + {0, 0, 0}
    

    is shorthand for

    {serial_numbering, serial_numbering, serial_numbering}
    

    and

    serial_numbering - XLOOKUP(header_count, header_count, serial_numbering)
    

    is the current serial number minus the serial number associated to the current header. The subtraction is necessary to reset the serial number everytime we encounter a new header.

    * Because of type coercion value = 0 is equivalent to OR(value = 0, ISBLANK(value))