CountIF to Count Cells Affected by Conditional Formatting - excel

After much research I have found nothing without VBA to count a range of cells that have been affected by conditional formatting (specifically are turned "red").
I know there is no way to count the "red" cells so I am going the route of creating a CountIF formula with the same criteria that is in the conditional formatting but i'm having issues creating the criteria.
I thought it would be simple and to just add "CountIF($G:$G," before the below code. This data is also inside a table named "TT".
=AND(OR(AND(TODAY()-$F1>1095,TODAY()-$G1>1095),$G1=0,AND($F1=0,TODAY()-$G1>1095)),$A1>0)

The OR makes things slightly mode complicated - you need to add the COUNTIFS, and then subtract when both are true (to prevent double-counting), To demonstrate, if we want where Column A = 0 or Column B = 0:
=COUNTIF(A:A, 0) + COUNTIF(B:B, 0) - COUNTIFS(A:A, 0, B:B, 0)
Except, you seem to be doing this with 3 conditions, which makes it bigger (add individual, subtract where 2 match, then add where all 3 match) - but there's actually a trick here, which I'll get to later.
To make it easier, we can rewrite your conditions from format Value - A1 > Const to A1 < Value - Const. This means the COUNTIF would be Countif(A:A, "<" & Value - Const)
=AND(OR(AND($F1<TODAY()-1095,$G1<TODAY()-1095),$G1=0,AND($F1=0,$G1<TODAY()-1095)),$A1>0)
Now, let's split that out into our individual COUNTIFS. There's the outer AND, so $A1>0 is in all of them, then there's an OR with 3 conditions. This gives us:
COUNTIFS($A:$A,">0", $G:$G, "<" & Today()-1095, $F:$F, "<" & Today()-1095)
COUNTIFS($A:$A,">0", $G:$G, 0)
COUNTIFS($A:$A,">0", $G:$G, "<" & Today()-1095, $F:$F, 0)
Now, here's the trick I mentioned earlier: I don't know about you, but I can see some duplication going on here. For example, the first and the third? Column F is less than Today()-1095, OR Column F is 0. Except, day 1095 is the 30th December 1902 - so Today()-1095 will always be greater than 0. Today, for example, it will be 42576. This means when the third condition is True, the first condition will also always be true. So, we can ignore the third COUNTIF entirely!
Now, we can't do this with the first and second conditions - because if column F is greater than Today()-1095 the first condition will always be False, but the second condition will be True if Column G is 0
So, using our example from earlier, we have the following:
=COUNTIFS($A:$A,">0", $G:$G, "<" & Today()-1095, $F:$F, "<" & Today()-1095)
+COUNTIFS($A:$A,">0", $G:$G, 0)
-COUNTIFS($A:$A,">0", $G:$G, 0, $G:$G, "<" & Today()-1095, $F:$F, "<" & Today()-1095)
But! Look at that last COUNTIFS. It has G:G = 0 AND G:G < Today()-1095. But, if Column G is 0, then it is also less than Today()-1095 (Disclaimer: On-or-after New Year's Eve 1902) So, we can simplify that:
-COUNTIFS($A:$A,">0", $G:$G, 0, $F:$F, "<" & Today()-1095)
Which means our entire equation is as follows:
=COUNTIFS($A:$A,">0", $G:$G, "<" & Today()-1095, $F:$F, "<" & Today()-1095)+COUNTIFS($A:$A,">0", $G:$G, 0)-COUNTIFS($A:$A,">0", $G:$G, 0, $F:$F, "<" & Today()-1095)

I figured out my own formula using the table headers and a combination of SUM( COUNTIFS( COUNTBLANK(. It's battle tested and works!
=SUM(COUNTIFS(TT[Fiscal Law 301 CBT],"<"&TODAY()-1095,TT[Fiscal Law In-Residence],"<"&TODAY()-1095),COUNTBLANK(TT[Fiscal Law 301 CBT]),COUNTIFS(TT[Fiscal Law In-Residence],"",TT[Fiscal Law 301 CBT],"<"&TODAY()-1095))

Related

How not to show 0 with IF

This is my excel function. I don't know how to change the IF sentance to not include 0's if they are in a certian column.
Tried nesting them like in programming languages but it did not work.
=AG2
& "-"
& D2
& IF(LEN(F2)<=2;F2;"")
& IF(F2="0";"";)
& IF(F2="3XL";"XXXL";)
& IF(F2="4XL";"XXXXL";)
& IF(F2="5XL";"XXXXXL";)
& IF(F2="6XL";"XXXXXXL";)
& IF(F2="XXL";"XXL";"")
I don't seem to know how to post a cleaner version of the formula.
unedited:
=AG2 & "-" & D2 & IF(LEN(F2)<=2;F2;"") & IF(F2="0";"";) & IF(F2="3XL";"XXXL";) & IF(F2="4XL";"XXXXL";) & IF(F2="5XL";"XXXXXL";) & IF(F2="6XL";"XXXXXXL";) & IF(F2="XXL";"XXL";"")
The condition for the length of F2 needs to be nested into the condition to see if F2 is zero.
=AG2
&"-"
&D2
&IF(F2="0"; ""; IF(LEN(F2)<=2; F2; ""))
&IF(F2="3XL";"XXXL";)
&IF(F2="4XL";"XXXXL";)
&IF(F2="5XL";"XXXXXL";)
&IF(F2="6XL";"XXXXXXL";)
&IF(F2="XXL";"XXL";"")
Try the following
=AG2 & "-" & D2 & IF(F2=0; ""; IF(AND(IFERROR(FIND("XL"; UPPER(F2)); FALSE); ISNUMBER(VALUE(TRIM(SUBSTITUTE(UPPER(F2); "XL"; ""))))); REPT("X"; VALUE(TRIM(SUBSTITUTE(UPPER(F2); "XL"; ""))))&"L"; F2))
To break this down we can look at it in chunks. The first part is obvious
AG2 & "-" & D2
Takes the values from Cells AG2 and D2 and combines them with a - separator.
The next part produces the output from cell F2
IF(F2=0; ";
This tests whether cell F2 is equal to 0 and if so returns an empty string.
The next condition we test for if F2 contains an XL and if so is there a number in the cell as well.
IFERROR(FIND("XL"; UPPER(F2)); FALSE)
Tests if F2 has "XL" in the value
ISNUMBER(VALUE(TRIM(SUBSTITUTE(UPPER(F2); "XL"; ""))))
Tests whether there is a number included as well
If both the conditions above returns True then the formula repeats the letter "X" the number of times of the number in cell F2 and combines it with an "L" on the end
REPT("X"; VALUE(TRIM(SUBSTITUTE(UPPER(F2); "XL"; ""))))&"L"
e.g. this will convert
2xl -> XXL
3xl -> XXXL
4xl -> XXXXL
5xl -> XXXXXL
6XL -> XXXXXXL
7XL -> XXXXXXXL
etc.
For anything else (e.g. "", S, M, L, XL, XXL etc.) it will return those values unmodified. This should cover all of your examples above and more (if needed)

Excel formula using more if

I have a problem with my nested if condition as an Excel formula. I know it would be easier by using VBA, but I have to do it this way.
This is my formula, but it returns FALSE:
=IF(D:D="SUPER";IF(AND(AA:AA="0";AA:AA="1");"V";IF(AA:AA="3";"R";"O")))
The D:D column has 3 filters, I have to apply the same formula with each filter.
The AA:AA column has the following conditions:
- if 0 and 1 -> V
- if 3 -> R
- if anything else -> O
I don't know why it doesn't work, but I would appreciate any advice!
This will return R, because there is 3 in there
enter image description here
I think this is more a matter of prioritizing logic flow. It seems that at least a single occurrence of SUPER with 3 supersedes the rest. The next priority would be SUPER with 0 and SUPER with 1 (both must occur). If none of those apply, default to O.
=if(countifs(d:d, "super", aa:aa, 3), "R", if(not(and(countifs(d:d, "super", aa:aa, 0), countifs(d:d, "super", aa:aa, 1))), "O", "V"))
'with semi-colons
=if(countifs(d:d; "super"; aa:aa; 3); "R"; if(not(and(countifs(d:d; "super"; aa:aa; 0); countifs(d:d; "super"; aa:aa; 1))); "O"; "V"))
=IF(COUNTIFS(D:D;"super";AA:AA;3)<>0;"R";IF(COUNTIFS(D:D;"super";AA:AA;1)*COUNTIFS(D:D;"super";AA:AA;0)=0;"O";"V"))
The order of the criteria was wrong, also you generally can't refer to entire columns in the way you did. This formula first checks whether there's any cell with the value 3. Then if there isn't it multiplies the count of 1s and 0s to check whether there are both numbers present.

Evaluating INDIRECT in an array in Excel

I'm trying to write a linear regression function that dynamically references columns, can handle #N/A values, and will function as additional rows are added over time. Here is a sample dataset:
Date Value 1 Value 2
1/2/1991 #N/A #N/A
2/4/2002 276.36 346.31
1/7/2003 252 350
1/21/2004 232 345.5
1/6/2005 257 368
2/1/2006 278.24 390.11
2/23/2007 #N/A 380.46
2/11/2008 326.34 383.04
2/12/2009 #N/A 399.9
2/17/2009 334.39 #N/A
1/29/2010 344.24 400.83
1/27/2011 342.88 404.52
2/7/2012 379 417.91
1/23/2013 #N/A 433.35
Here is the function that I've developed so far, based on this forum post. It calculates the linear regression for Value 1.
=TRANSPOSE(
LINEST(
N(
OFFSET(
INDIRECT("B2" & ":B" & COUNTA(B:B)),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT("B2" & ":B" & COUNTA(B:B))),
ROW(INDIRECT("B2:B" & COUNTA(B:B))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT("B2:B" & COUNTA(B:B))))))), 0, 1)),
N(
OFFSET(
INDIRECT("A2:A" & COUNTA($A:$A)),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT("B2:B" & COUNTA(B:B))),
ROW(INDIRECT("B2:B" & COUNTA(B:B))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT("B2:B" & COUNTA(B:B))))))), 0, 1)),
TRUE, FALSE))
With the way it is currently written, dragging my array to the right to solve for Value 2 requires some manual updating of the formula. Everything in quotes in the INDIRECT formulas must be manually changed from B to C. I have 40 columns of data, though, so I tried to make the formula entirely dynamic using ADDRESS, ROW, and COLUMN:
=TRANSPOSE(
LINEST(
N(
OFFSET(
INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2))),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))),
ROW(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))))))), 0, 1)),
N(
OFFSET(
INDIRECT("A2:A" & COUNTA($A:$A)),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))),
ROW(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))))))), 0, 1)),
TRUE, FALSE))
This gives me #REF!. When I do a step-by-step evaluation of the formula, it looks like the issue comes when Excel evaluates COLUMN. It introduces braces to the formula, which propagate through the rest of the INDIRECT evaluation. Here is a quick comparison:
Original formula:
INDIRECT("B2:B15")
Dynamic formula:
INDIRECT({"$B$2:$B$15"})
This evaluates as #VALUE, and at that point the rest of the formula is broken. Is there a way to force Excel to not use braces in this evaluation, or is there a better way of making this calculation?
Are you only trying to get the SLOPE from the linear regression? If so, you can just use the SLOPE function after converting the #N/A to blanks (using IFERROR in a formula). SLOPE will then just toss out the blanks. If you want the intercept as well, use the same formulas below and substitute INTERCEPT for SLOPE.
Picture of ranges
Formulas are array formulas (use CTRL+SHIFT+ENTER) and copied over. Given this arrangement, the simple formula (non-dyanmic) would be:
=SLOPE(IFERROR(B2:B15,""),$A$2:$A$15)
If you want these to be dynamic, you can use INDEX and COUNTA to get the dynamic range.
=SLOPE(IFERROR(B2:INDEX(B:B,COUNTA(B:B)),""),$A$2:INDEX($A:$A,COUNTA($A:$A)))
Use a Table instead
Even better, you could define this data inside a Table and then use the headers to pull in the whole column. That formula would look nice and copy easily.
Still using an array formula here, but the only variable is the column heading which is used to look into the Table1. This one would be more resistant to blanks in the data which will break the COUNTA used above.
=SLOPE(IFERROR(INDEX(Table1,,MATCH(M1,Table1[#Headers])),""),Table1[Date])
It appears you can use the following, shorter, non-volatile array formula**:
=LINEST(INDEX(B:B,N(IF(1,MODE.MULT(IF(ISNUMBER(B2:B15),{1,1}*ROW(B2:B15)))))),INDEX($A:$A,N(IF(1,MODE.MULT(IF(ISNUMBER(B2:B15),{1,1}*ROW(B2:B15)))))))
B2:B15 can be dynamically defined if desired as per Jeeped's solution.
Regards
You are going to want to get rid of the use of the INDIRECT function as much as possible; certainly as it pertains to substituting column references for string equivalents. It seems that many can be replaced with a form of INDEX/MATCH function pairs.
=TRANSPOSE(
LINEST(
N(
OFFSET(B2:INDEX(B:B, MATCH(1E+99,$A:$A )),
SMALL(
IF(
ISNUMBER(
$A2:INDEX($A:$A, MATCH(1E+99,$A:$A )) *
B2:INDEX(B:B, MATCH(1E+99,$A:$A ))),
ROW(B2:INDEX(B:B, MATCH(1E+99,$A:$A ))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT($A2:INDEX($A:$A, MATCH(1E+99,$A:$A ))),
COUNT(B2:INDEX(B:B, MATCH(1E+99,$A:$A ))))))), 0, 1)),
N(
OFFSET(
$A2:INDEX($A:$A, MATCH(1E+99,$A:$A )),
SMALL(
IF(
ISNUMBER(
$A2:INDEX($A:$A, MATCH(1E+99,$A:$A )) *
B2:INDEX(B:B, MATCH(1E+99,$A:$A ))),
ROW(B2:INDEX(B:B, MATCH(1E+99,$A:$A ))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT($A2:INDEX($A:$A, MATCH(1E+99,$A:$A ))),
COUNT(B2:INDEX(B:B, MATCH(1E+99,$A:$A ))))))), 0, 1)),
TRUE, FALSE))
Fill right as necessary and have column A locked while column B cell range references will shift to column C, D, etc.
        
Further function replacement could likely exchange at least some of the OFFSET functions use for an appropriate INDEX function but the formula seems to work well as it is now.

I am trying to write a nested if formula with 3 columns AND 3 conditions

A B C FORMULA
Y TBC N ?
I want a formula to have all these 3 columns with each having different combination
For eg if a,b,c = Y , the result should be ABC, if a & b is Y, result will be AB and similarly "AC", "BC", "A", "B", "C"
If all three are N, the result will be N and if one is "TBC" and other 2 are N the result is TBC
The easiest, messiest solution would be this:
=IF(AND(OR(A1="TBC", B1="TBC",C1="TBC"), A1<>"Y", B1<>"Y", C1<>"Y"),"TBC", IF(AND(A1="N",B1="N",C1="N"), "N", IF(A1="Y", "A", "") & IF(B1="Y", "B", "") & IF(C1="Y", "C", "")))
Of course, if you wanted to expand the number of columns or similar, this quickly becomes very messy, so there are more efficient ways.
Long story short, the three functions you're using in this are IF, OR and AND.
=IF(<Condition>, <What it will return if comparison is true>, <What it will return if comparison isfalse>)
=OR(<Condition>, <Condition>,...) Will be true if one or more of the Conditions are true
=AND(<Condition>, <Condition>,...) Will be true, only if all of the Conditions are true
In our first IF we want to know if any of our cells have at least one "TBC" AND the rest "N". I simplified this to At least one "TBC" and no "Y", if this isn't exactly what you want, then there are other ways to do it (If you're using Excel 2013 you can replace the OR with XOR which will return true only if exactly one of the conditions are true).
To solve this, we use
AND(OR(A1="TBC", B1="TBC",C1="TBC"), A1<>"Y", B1<>"Y", C1<>"Y")
Which is the same as saying, return true if at least one of A, B and C are "TBC" AND None of them are "Y". If this is true, then it will set the cell to "TBC", otherwise it will go on to ask the second if statement, which uses the formula:
AND(A1="N",B1="N",C1="N")
This is even simpler. It will return true if All three cells are equal to N. If it is true, it will give us the value "N" from the second argument in the IF Statement, otherwise it will go onto one last section:
IF(A1="Y", "A", "") & IF(B1="Y", "B", "") & IF(C1="Y", "C", "")
The other thing you need to know is the concatenate function which uses the & character. What this does is join together the surrounding strings.
Each IF will give us either a single character (the row letter) if it's true, or a blank string if it's not, so for example, if the cells have the value Y, Y, N then that statement will produce the strings:
"A" & "B" & ""
Which when joined together give us AB like we'd want.

Excel formula results in a array and value error

I have the following equation:
=EXP(FORECAST(LN($A4), LN(OFFSET(INDIRECT($B$1 & "!B8"), MATCH($A4, INDIRECT($B$1 & "!A8:A308"), 1) - 1, COLUMN() - COLUMN($B4), 2)), LN(OFFSET(INDIRECT($B$1 & "!a8"), MATCH($A4, INDIRECT($B$1 & "!A8:A308"), 1) - 1, 0, 2))))
The calculation is performing linear interpolation in log-log space. In the evaluation of this portion:
INDIRECT($B$1 & "!A8:A308"), 1) - 1, COLUMN() - COLUMN($B4), 2)
The column difference (COLUMN() - COLUMN($B4)) results in an array (e.g., {0}). This causes a value error for the MATCH() function. If I run the INDIRECT(...) call above, then the column difference doesn't result in an array. My current solution is wrap the column difference with LARGE(..., 1), which effectively flattens the array.
The question is why does the column difference result in array, and is there a better way to deal with this?
Found it! Microsoft Office Reference says this about the COLUMN function: "If the reference argument is omitted ... the COLUMN function returns the column numbers of reference as a horizontal array."
That's the explanation. The solution, then, is to use COLUMN(A1) instead of COLUMN().

Resources