Indian short currency format in google sheets - google-sheets

In google sheets, I am trying to display numbers in Indian 'short' format with lakhs and crore suffix as follows:
Cell value: 1234, Display as 1.23K
Cell value: 12345, Display as 12.35K
Cell value: 123456, Display as 1.23L [L=lakh]
Cell value: 1234567, Display as 12.35L
Cell value: 12345678, Display as 1.23C [C=Crore]
Cell value: 123456789, Display as 12.35C.
I have tried to modify this custom number format:
[<999950]0.0,"K";[<999950000]0.0,,"M";0.0,,,"B"
by Brook McEachern, but could not able to achieve my required format.
Does anyone know of a way to do this?

indian separator system in B2:
=ARRAYFORMULA(REGEXREPLACE(REGEXREPLACE(SUBSTITUTE(FLATTEN(QUERY(TRANSPOSE(QUERY(
REGEXEXTRACT(REGEXREPLACE(SUBSTITUTE(FLATTEN(QUERY(TRANSPOSE(QUERY(IFERROR(
REGEXEXTRACT(A2:A, REPT("(.)", IF(LEN(A2:A)=3, LEN(A2:A)-4, LEN(A2:A)-3))), "0"),
"select "&JOIN(",", "Col"&SORT(SEQUENCE(MAX(LEN(A2:A)-3)), 1, )))),,9^9)), " ", ),
"(.{2})", "$1,"), REPT("(.)", IF((LEN(A2:A)-3)+ROUNDDOWN((LEN(A2:A)-3)/2)<1, 1,
(LEN(A2:A)-3)+ROUNDDOWN((LEN(A2:A)-3)/2)))),
"select "&JOIN(",", "Col"&SORT(SEQUENCE(MAX((LEN(A2:A)-3)+
ROUNDDOWN((LEN(A2:A)-3)/2))), 1, )))),,9^9)), " ", ), "^,", )&","&IFNA(
REGEXEXTRACT(A2:A, "...$"), IF(A2:A="",,TEXT(A2:A, "000"))), "^0,$", ))
indian short currency in C2:
=ARRAYFORMULA(IFNA(ROUND(A2:A*VLOOKUP(LEN(A2:A), {SEQUENCE(19),
{1; 1; 1; 1; 1; 10^-5; 10^-5; 10^-7; 10^-7; 10^-9; 10^-9;
10^-11; 10^-11; 10^-13; 10^-13; 10^-15; 10^-15; 10^-17; 10^-17}}, 2, 1), 2)&" "&
VLOOKUP(LEN(A2:A), {SEQUENCE(19),
{"Rp"; "Rp"; "Rp"; "Rp"; "Rp"; "L"; "L"; "Cr"; "Cr"; "Arab"; "Arab";
"Kharab"; "Kharab"; "Nil"; "Nil"; "Padma"; "Padma"; "Shankh"; "Shankh"}}, 2, 1)))
side note: ROUND is set to 2 decimal places. this can be set to 0, or ROUND can be completely removed, or it can be replaced by TRUNC if needed
spreadsheet demo

an alternative approach would be as follows...
indian separator system:
=INDEX(IF(IFERROR(N(ABS(A1:A*1)))>0, REGEXREPLACE(REGEXREPLACE(REGEXREPLACE(
REPT(0, 50)&"×"&TEXT(A1:A, "0"), REPT("(..)", 24)&"(...)$",
JOIN(",", "$"&SEQUENCE(25))), "(.*×,?)", ), "-,", "-")&
IFNA(REGEXEXTRACT(A1:A&"", "(\.\d{1})")), A1:A&""))
indian short currency:
=INDEX(IF((IFERROR(N(ABS(A1:A*1)))>0)+(IF(ISBLANK(A1:A),,IFERROR(A1:A*1, 1)=0)),
REGEXREPLACE(TEXT(TRUNC(IFNA(A1:A*(10^-(
VLOOKUP(LEN(TEXT(INT(ABS(A1:A*1)), "0")),
SEQUENCE(8, 1, 6, 2), 1)-1)), A1:A), 1), "0.#"), "(\.)$", )&" "&
HLOOKUP(LEN(TEXT(INT(ABS(A1:A*1)), "0")), {0, SEQUENCE(1, 8, 4, 2);
SPLIT("Rp♦Rp♦L♦Cr♦Arab♦Kharab♦Nil♦Padma♦Shankh", "♦")} , 2), ""&A1:A))
both indian systems combined:
=INDEX(IF((IFERROR(N(ABS(A1:A*1)))>0)+(IF(ISBLANK(A1:A),,IFERROR(A1:A*1, 1)=0)),
REGEXREPLACE(REGEXREPLACE(REGEXREPLACE(
REPT(0, 50)&"×"&REGEXREPLACE(TEXT(TRUNC(IFNA(A1:A*(10^-(
VLOOKUP(LEN(TEXT(INT(ABS(A1:A*1)), "0")),
SEQUENCE(8, 1, 6, 2), 1)-1)), A1:A), 1), "0"), "(\.)$", ), REPT("(..)", 24)&"(...)$",
JOIN(",", "$"&SEQUENCE(25))), "(.*×,?)", ), "-,", "-")&
IFNA(REGEXEXTRACT(A1:A&"", "(\.\d{1})"))&" "&
HLOOKUP(LEN(TEXT(INT(ABS(A1:A*1)), "0")), {0, SEQUENCE(1, 8, 4, 2);
SPLIT("Rp♦Rp♦L♦Cr♦Arab♦Kharab♦Nil♦Padma♦Shankh", "♦")} , 2), A1:A&""))
works with numeric numbers
works with plain text numbers
works with text
works with empty cells
works with negative values
works with zeros
works with scientific notations
works with decimals
works up to Shankh
works up to 10^±50
english demo sheet
non-english demo sheet

Related

Looking for the most profitable range (mathematical names: "maximum subarray problem" or "maximum consecutive subsequence sum")

To be able to find the most profitable range, I add the lowest value I want to the highest value I want, with that I create a table like this example:
https://docs.google.com/spreadsheets/d/17zpapBeC5wYxyU6SjbqcbnV4_QP4gooxj0PxdCywDk0/edit?usp=sharing
Cell's formulas examples:
Between 0 and 0:
=IFERROR(SUM(FILTER($B$1:$B,($A$1:$A<=D2)*($A$1:$A>=$E$1))))
Between 5 and 10:
=IFERROR(SUM(FILTER($B$1:$B,($A$1:$A<=D12)*($A$1:$A>=$J$1))))
=MAX(E2:O12)
Max Profit = £185.00
=INDEX(A1:O1,ARRAYFORMULA(MIN(IF(E2:O12=MAX(E2:O12),COLUMN(E2:O12)))))
Value Min for Max Profit = 4
=INDEX(D1:D12,ARRAYFORMULA(MAX(IF(E2:O12=MAX(E2:O12),ROW(E2:O12)))))
Value Max for Max Profit = 10
When there are hundreds of values¹ in A and B, this table gets very big and heavy, even causing crashes like my current original data spreadsheet.
Is there any way using a only one formula or script code to found Max Profit | Value Min for Max Profit | Value Max for Max Profit without doing each range one by one needing to use thousands of cells each with a specific formula?
Notes:
hundreds of values¹ → my original spreadsheet currently contains 1471 rows of data in A with the results in B. So to be able to do this analysis, I need to put 2,163,841 formulas like =IFERROR(SUM(FILTER($B$1:$B,($A$1:$A<=D2)*($A$1:$A>=$E$1)))) in the cells to create the table and find the most profitable range.
max:
=INDEX(MAX(IF(SEQUENCE(MAX(A:A)+1)>=SEQUENCE(1, MAX(A:A)+1),
SUMIF(SEQUENCE(MAX(A:A)+1), "<="&SEQUENCE(MAX(A:A)+1), B:B)*
SEQUENCE(1, MAX(A:A)+1, 1, )-QUERY(QUERY(
(SEQUENCE(MAX(A:A)+1)<SEQUENCE(1, MAX(A:A)+1))*B1:B,
"select "&TEXTJOIN(",", 1, "sum(Col"&SEQUENCE(MAX(A:A)+1)&")")),
"offset 1", ), )))
value min:
=INDEX(REGEXEXTRACT(MAX(IF(SEQUENCE(MAX(A:A)+1)>=SEQUENCE(1, MAX(A:A)+1),
SUMIF(SEQUENCE(MAX(A:A)+1), "<="&SEQUENCE(MAX(A:A)+1), B:B)*
SEQUENCE(1, MAX(A:A)+1, 1, )-QUERY(QUERY(
(SEQUENCE(MAX(A:A)+1)<SEQUENCE(1, MAX(A:A)+1))*B1:B,
"select "&TEXTJOIN(",", 1, "sum(Col"&SEQUENCE(MAX(A:A)+1)&")")),
"offset 1", )+(SEQUENCE(1, MAX(A:A)+1)*10^-10)&9, )*1)&"", "0(\d+)9$")-1)
value max:
=INDEX(REGEXEXTRACT(MAX(IF(SEQUENCE(MAX(A:A)+1)>=SEQUENCE(1, MAX(A:A)+1),
SUMIF(SEQUENCE(MAX(A:A)+1), "<="&SEQUENCE(MAX(A:A)+1), B:B)*
SEQUENCE(1, MAX(A:A)+1, 1, )-QUERY(QUERY(
(SEQUENCE(MAX(A:A)+1)<SEQUENCE(1, MAX(A:A)+1))*B1:B,
"select "&TEXTJOIN(",", 1, "sum(Col"&SEQUENCE(MAX(A:A)+1)&")")),
"offset 1", )+(SEQUENCE(MAX(A:A)+1)*10^-10)&9, )*1)&"", "0(\d+)9$")-1)
update:
=INDEX(TEXTJOIN(", ", 1, UNIQUE(FLATTEN(
IF(IF(SEQUENCE(MAX(A:A)+1)>=SEQUENCE(1, MAX(A:A)+1),
SUMIF(SEQUENCE(MAX(A:A)+1), "<="&SEQUENCE(MAX(A:A)+1), B:B)*
SEQUENCE(1, MAX(A:A)+1, 1, )-QUERY(QUERY(
(SEQUENCE(MAX(A:A)+1)<SEQUENCE(1, MAX(A:A)+1))*B1:B,
"select "&TEXTJOIN(",", 1, "sum(Col"&SEQUENCE(MAX(A:A)+1)&")")),
"offset 1", ), )=MAX(IF(SEQUENCE(MAX(A:A)+1)>=SEQUENCE(1, MAX(A:A)+1),
SUMIF(SEQUENCE(MAX(A:A)+1), "<="&SEQUENCE(MAX(A:A)+1), B:B)*
SEQUENCE(1, MAX(A:A)+1, 1, )-QUERY(QUERY(
(SEQUENCE(MAX(A:A)+1)<SEQUENCE(1, MAX(A:A)+1))*B1:B,
"select "&TEXTJOIN(",", 1, "sum(Col"&SEQUENCE(MAX(A:A)+1)&")")),
"offset 1", ), )), SEQUENCE(1, MAX(A:A)+1, 0), )))))

Use Sheet's Array formula to count values in each row

When I apply an array formula for:
=count(D3:AA3)
It looks like this:
=ArrayFormula(if(row(A:A)=1,"Count",Count(D1:D:AA1:AA)))
Too many ":" (colons)?
I could (manually) paste the =count(D3:AA3) ...down every row, but I'd like it to be automated.
Here is a formula to count all the number values (COUNT does exactly that) row-wise:
={
"Count";
MMULT(
ARRAYFORMULA(--(ISNUMBER(F2:O))),
SEQUENCE(COLUMNS(F2:O), 1, 1, 0)
)
}
You can replace F2:O with the range you have the data in.
Update.
Count is in column A:A, sum - column B:B, avg - column C:C, avg in a single cell (w/o using count and sum columns) - column D:D. F2:N cells have random data, some numeric, some text (will be ignored).
Here is a formula for the row wise sum of numeric values:
={
"Sum";
MMULT(
ARRAYFORMULA(IF(ISNUMBER(F2:O), F2:O, 0)),
SEQUENCE(COLUMNS(F2:O), 1, 1, 0)
)
}
Here is the formula for the row wise average if you have count and sum columns:
={
"AVG";
ARRAYFORMULA(IF(A2:A = 0, 0, B2:B / A2:A))
}
And the row wise average in a single cell w/o using count and sum columns:
={
"AVG one single formula";
ARRAYFORMULA(
IF(
MMULT(
--(ISNUMBER(F2:O)),
SEQUENCE(COLUMNS(F2:O), 1, 1, 0)
) = 0,
0,
MMULT(
IF(ISNUMBER(F2:O), F2:O, 0),
SEQUENCE(COLUMNS(F2:O), 1, 1, 0)
) / MMULT(
--(ISNUMBER(F2:O)),
SEQUENCE(COLUMNS(F2:O), 1, 1, 0)
)
)
)
}

How to rank a cell value within the same cell

I am trying to rank a set of numbers (in a column), but I want that rank to appear next to the number in the same cell.
For example, if the number is "21" and that ranks "3rd" – I would want the cell to read "21 (3)". BONUS POINTS if I can format the (3) to be smaller/superscript.
WHAT I'VE TRIED:
While the cell I am working in already has an equation in it, I will simplify it. Let's say A23 = 15 and A24 = 6. I have tried the following equation but it keeps giving me an error. The cell I am working in is H103. The range for ranking is H103:H114.
=SUM(A23+A24) & "(" & RANK(H103,$H$103:$H$114) & ")"
Even if I remove the parentheses or rework that a bit, I am still left with an error. Just trying to find any way I can have 2 formulas, with different results in the same cell; one of which showing the rank of that particular cell.
HERE IS COPY OF MY SHEET — This is a duplicated Google Sheet, so feel free to play around in there if you'd like. I am focusing on ranking H103:H114.
paste in cell H103:
=ARRAYFORMULA(TEXT(VLOOKUP(B103:B114, QUERY(INDIRECT($A$100&"!B:C"),
"select B,sum(C) where B is not null group by B", 0), 2, 0)+
VLOOKUP(B103:B114, QUERY(INDIRECT($A$100&"!E:D"),
"select E,sum(D) where E is not null group by E", 0), 2, 0), "#.00")&" "&CHAR(8317)&
VLOOKUP(RANK(VLOOKUP(B103:B114, QUERY(INDIRECT($A$100&"!B:C"),
"select B,sum(C) where B is not null group by B", 0), 2, 0)+
VLOOKUP(B103:B114, QUERY(INDIRECT($A$100&"!E:D"),
"select E,sum(D) where E is not null group by E", 0), 2, 0),
VLOOKUP(B103:B114, QUERY(INDIRECT($A$100&"!B:C"),
"select B,sum(C) where B is not null group by B", 0), 2, 0)+
VLOOKUP(B103:B114, QUERY(INDIRECT($A$100&"!E:D"),
"select E,sum(D) where E is not null group by E", 0), 2, 0), 0),
{1, CHAR(185); 2, CHAR(178); 3, CHAR(179);
4, CHAR(8308); 5, CHAR(8309); 6, CHAR(8310);
7, CHAR(8311); 8, CHAR(8312); 9, CHAR(8313);
10, CHAR(185)&CHAR(8304); 11, CHAR(185)&CHAR(185); 12, CHAR(185)&CHAR(178)}, 2, 0)&
CHAR(8318))
paste in cell I103:
=ARRAYFORMULA(VLOOKUP(B103:B114, QUERY(INDIRECT($A$100&"!B:C"),
"select B,sum(C) where B is not null group by B", 0), 2, 0)+
VLOOKUP(B103:B114, QUERY(INDIRECT($A$100&"!E:D"),
"select E,sum(D) where E is not null group by E", 0), 2, 0)-C103:C114)
paste in cell L103:
=ARRAYFORMULA(VLOOKUP(B103:B114, QUERY(INDIRECT($A$100&"!B:C"),
"select B,sum(C) where B is not null group by B", 0), 2, 0)+
VLOOKUP(B103:B114, QUERY(INDIRECT($A$100&"!E:D"),
"select E,sum(D) where E is not null group by E", 0), 2, 0)-J103:J114)
conditional formatting for H column:
red color custom formula:
=REGEXMATCH(H103, CHAR(8317)&CHAR(185)&CHAR(178)&CHAR(8318))
green color custom formula:
=REGEXMATCH(H103, CHAR(8317)&CHAR(185)&CHAR(8318))

Add a new row when sum of rows reaches value

How would I go about adding a new row beneath the value where max 48 in the below example is reached in Google Sheets?
Edit: Demo Google Sheet added: https://docs.google.com/spreadsheets/d/1jKX-AOfbFAEvks_Q8P8jegFek4ZocZJY113TfaY6jcQ/edit#gid=2041258691
=ARRAYFORMULA(SPLIT(TRANSPOSE(SPLIT(QUERY(IF(A5:A<>"",
"♦"&A5:A&"♠"&B5:B&IFERROR(VLOOKUP(A5:A, REGEXREPLACE(""&SORTN(FILTER({A5:A,
IF(LEN(A5:A), QUERY(ROUNDUP((ROUND(MMULT(TRANSPOSE((ROW(B5:B)
<= TRANSPOSE(ROW(B5:B)))*B5:B), SIGN(B5:B))*5/48, 1))-1), "offset 1", 0), )},
MOD(IF(LEN(A5:A), QUERY(ROUNDUP((ROUND(MMULT(TRANSPOSE((ROW(B5:B)
<= TRANSPOSE(ROW(B5:B)))*B5:B), SIGN(B5:B))*5/48, 1))-1), "offset 1", 0), ), 5)=0,
IF(LEN(A5:A), QUERY(ROUNDUP((ROUND(MMULT(TRANSPOSE((ROW(B5:B)
<= TRANSPOSE(ROW(B5:B)))*B5:B), SIGN(B5:B))*5/48, 1))-1), "offset 1", 0), )<>0),
999^99, 2, 2, 1), "^\d+", "♦♥"), 2, 0)), ),,999^99), "♦")), "♠♥"))

Alternating Cycle (T)op/(B)ottom Sequence

Needing either a single array formula or one dragged down the column that will show alternating sequence per a rule set. Ruleset and detailed example are within the attached link here.
https://docs.google.com/spreadsheets/d/1Sdi1jFpBKF2RJeqWNjLybVcwR0G6hvozZZTvcTK1xis/edit?usp=sharing
let cell E79 be:
=IF(E79>55, "T",
IF(E79<45, "B",
LOOKUP(MIN(MAX(INDEX(E2:E78,
MATCH(1,INDEX((E2:E78>55)+(E2:E78<45)*(E2:E78<>""), ), 0)), 45), 55),
{45,55}, {"B", "T"})))
paste this in cell E78 and drag it upwards:
=IF(((E78<55)*(E78>45))*((E79<55)*(E79>45)),,
IF((QUERY({F79:F},"where Col1 is not null limit 1", 0)="T")*(E78<=55)*(E79>=45), "B",
IF((QUERY({F79:F},"where Col1 is not null limit 1", 0)="B")*(E78> 45)*(E79< 55), "T", )))
paste this in G2 cell:
=ARRAYFORMULA(INDEX(SORT({VLOOKUP(ROW(
INDIRECT("F2:F"&MAX(IF(F2:F<>"", ROW(F2:F), )))), IF(INDEX(SORT({
INDIRECT("F2:F"&MAX(IF(F2:F<>"", ROW(F2:F), ))), ROW(
INDIRECT("F2:F"&MAX(IF(F2:F<>"", ROW(F2:F), ))))}, 2, 0),,1)<>"", {ROW(
INDIRECT("F2:F"&MAX(IF(F2:F<>"", ROW(F2:F), )))),INDEX(SORT({
INDIRECT("F2:F"&MAX(IF(F2:F<>"", ROW(F2:F), ))), ROW(
INDIRECT("F2:F"&MAX(IF(F2:F<>"", ROW(F2:F), ))))}, 2, 0),,1)}), 2, 1), ROW(
INDIRECT("F2:F"&MAX(IF(F2:F<>"", ROW(F2:F), ))))}, 2, 0),,1))
and paste this in H2 cell:
=ARRAYFORMULA(
IF(G2:G="T", IFERROR(VLOOKUP(C2:C, {QUERY(TRANSPOSE(QUERY(TRANSPOSE(QUERY(
SPLIT(TRANSPOSE(SPLIT("♦"&QUERY(IF(G2:G="T", C2:C, )&
IF(F2:F<>"", "♦", ),,999^99), "♦")), " ")*1, "where Col1 is not null", 0)),
"select "&TEXTJOIN(",", 1, IF(LEN(FILTER(F2:F, F2:F="T")),
"max(Col"&ROW(F2:F)-ROW(F2)+1&")", ))&"")), "select Col2"),
FILTER(F2:F, F2:F="T")}, 2, 0)),
IF(G2:G="B", IFERROR(VLOOKUP(D2:D, {QUERY(TRANSPOSE(QUERY(TRANSPOSE(QUERY(
REGEXREPLACE(TO_TEXT(
SPLIT(TRANSPOSE(SPLIT("♦"&QUERY(IF(G2:G="B", D2:D, )&
IF(F2:F<>"", "♦", ),,999^99), "♦")), " ")*1), "^0$", "999999999")*1,
"where Col1 is not null", 0)), "select "&TEXTJOIN(",", 1,
IF(LEN(FILTER(F2:F, F2:F="B")),
"min(Col"&ROW(F2:F)-ROW(F2)+1&")", ))&"")), "select Col2"),
FILTER(F2:F, F2:F="B")}, 2, 0)), )))
spreadsheet demo
=ARRAYFORMULA(IF(IFERROR(VLOOKUP(INDIRECT("C2:C"&COUNTA(C2:C)),
MIN(FILTER(C2:C, D2:D<45, D2:D<>"")), 1, 0))<>"", "B", ))

Resources