Reasoning with columns in mind: Don't know how to access "This" value - google-sheets

I am trying to do the following:
For each Row
If Cell A contains text "abc" then get value on column B and
if value on Column B is > than 0:03:00 return 0.9
else if value on Column B is < 0:03:00 and > 00:01:00 return 0.6
else return 0.3
Sum the returned value with all the others.
The result should be something like:
=IF(ISNUMBER(FIND("abc",INDIRECT(""&$A16&""&"!$D$2:$D"))),IF(INDIRECT(""&$A16&""&"!$D$2:$D")>"00:0300,???,???),?etc??)
??? are the missing parts. Also, INDIRECT() could be removed for testing, but the problem is that ??? part. I have no idea how to get the result of the IF statement and how to process it. I suppose I don't understand how to work with columns.

You could possibly use an "array formula" with LOOKUP like this in excel
=SUM(IF(ISNUMBER(FIND("abc",A2:A100)),LOOKUP(B2:B100,{0,1,3}/1440,{3,6,9}/10)))
confirmed with CTRL+SHIFT+ENTER
or this version with IFs [edited]
=SUM(IF(ISNUMBER(FIND("abc",A2:A100)),IF(B2:B100>="0:03"+0,0.9,IF(B2:B100>"0:01"+0,0.6,0.3))))
In Google spreadsheets use this version
=arrayformula(SUM(IF(ISNUMBER(FIND(ʺabcʺ,A2:A100)),IF(B2:B100>=ʺ0:03ʺ+0,0.9,IF(B2:B100>ʺ0:01ʺ+0,0.6,0.3)))))
That will add 0.3 for the total for every row where "abc" is found in the text in column A and column B is >=0 but < 0:01, 0.6. where B >=0:01 and < 0:03 and 0:09 if B >= 0:09
Using LOOKUP makes it easier to avoid multiple IFs but I'm not sure if it gives the correct values for you on the boundaries, that's more easily adjustable with the second version. You can adjust the range lengths and add INDIRECT if required.
Note: using FIND for the first condition means that the formula will look for "abc" (case-sensitive) anywhere in the text, if you only want to check for exactly "abc" with no other text you can use just range = "abc" [not case-sensitive] or EXACT(range "abc") [case-sensitive]

Related

How do I display the value of a cell in one column based on the value of a cell in a different column?

I have a simple table.
Column A are dates (rows 2 to 100) that reflect approximately the next 3 months.
Column C are percentages that range from 0 to 1 (i.e. 0% to 100%). The %s are derived from a =FORECAST function.
I want to query a date in column A based on a value of 100% in column C. However, the QUERY function does not work because it's reading the =FORECAST formula in column C rather than the text or value of "100%" itself. (In other words, if I remove the =FORECAST formula and type in the string "100%", the query works.
How can I pull the date value in Column A and keep the formulas used in column C?
This sounds like a lookup to find the value in column A on the first row where column C contains the value 100%. Try this:
=vlookup(100%, { C2:C, A2:A }, 2, false)
In the event multiple rows in column C may contain 100%, and you want to get all such dates, try this:
=filter(A2:A, C2:C = 100%)
In the event your forecast() numbers do not produce exact percentages but figures like 100.04%, use this:
=filter(Forecast!A2:A, round(Forecast!C2:C, 2) = 100%)
Thanks to everyone who contributed. My workaround was replacing the = sign with a > sign, as shown:
=QUERY(StageHist!A:H, "SELECT A WHERE C>.99")
since I couldn't figure out how to make the 100% figure an exact 100%. Apparently the =FORECAST formula is designed to give a result with 8 or 9 digits to the right of the decimal. (Although I'm sure that I could nest a =ROUNDing function inside of FORECAST and get an exact 1.0 value. (A project for another day!)

How can I get the last numerical value value in a column in Google Sheets?

I need to find the last numerical value in a column. I was using this formula to get the last value in column G, but I made some changes and it no longer works: =INDEX(G:G, COUNTA(G:G), 1). My column now looks like this:
645
2345
4674.2345
123.1
"-"
"-"
"-"
...and the formula returns "-". I want it to return 123.1. How can I do this?
There are many ways to go about this. Here is one of them:
=QUERY(FILTER({G:G,ROW(G:G)},ISNUMBER(G:G)),"Select Col1 ORDER BY Col2 Desc LIMIT 1")
FILTER creates a virtual array of only numeric values in G in the first column and the row of those numeric values in the second column.
QUERY returns flips the order by row number and returns only the new top value from the first column (which winds up being your last numeric value in the original range).
However, if your numeric values start at G1, and if there are only numeric values up to where you start adding hyphens in cells, you could just alter your original formula like this:
=INDEX(G:G,COUNT(G:G))
This would work because COUNT only counts numeric values while COUNTA counts all non-null values (including errors BTW).
Not to take anything away from the accepted answer, but I've been working on this a bit lately in relation to this for the never-ending last row discussion and thought I'd share some potential similar solutions. These ideas are inspired by a pattern of google sheet array questions that seem to be coming up more often. I am also intentionally using different ways to do the same thing just to give people some ideas (i.e. left and Regex).
Last Row that is...
Number: =max(filter(row(G:G),isnumber(G:G)))
Text: =max(filter(row(G:G),isText(G:G)))
An error: =max(filter(row(G:G),iserror(G:G)))
Under 0 : =max(filter(row(G:G),G:G<0))
Also exists in column D: =max(filter(row(G:G),ISNUMBER(match(G:G,D:D,0))))
Not Blank: =max(filter(row(A:A),NOT(ISBLANK(A:A))))
Starts with ab: =max(filter(row(G:G),left(G:G,2)="ab"))
Contains the character !: =max(filter(row(G:G),isnumber(Find("!",G:G))))
Starts with a number: =max(filter(row(G:G),REGEXMATCH(G:G,"^\d")))
Only contains letters: =max(filter(row(G:G),REGEXMATCH(G:G,"^[a-zA-Z]+$")
Last four digits are upper case: =Max(filter(row(G:G),REGEXMATCH(G:G,"[A-Z]{4}$")))
To get the actual value (which I realize was the actual question), just wrap an index function around the Max function. So for this question, a solution could be :
=Index(G:G,max(filter(row(G:G),isnumber(G:G))))

Using COUNTIFS or dcounta instead of multiple COUNTIF

In our Staff timetable, employees can have an "A"shift (which starts at 9am) a "B" shift (which starts at 10:30am) etc.
I need to know how many shifts in total the employees make so what I use now is a multiple times COUNTIF to count the presents of a few arguments in a range of cells
=countif(D8:BM8;A43)+countif(D8:BM8;A44)+countif(D8:BM8;A45)+countif(D8:BM8;A46)++countif(D8:BM8;A47)
Where field A43 contains "A" field A44 cointains "B" etc.
This works perfect, however, I want to have a smarter way to do this, so I tried to use "COUNTIFS" but the result is always 0 and I can't find why
=COUNTIFS(D8:BM8;A43;D8:BM8;A44;D8:BM8;A45;D8:BM8;A46;D8:BM8;A47)
if looks like all arguments are checked with a logical and, but I need a logical and in this case or a solution with dcounta
You are getting a 0 because there is no cell that will meet ALL conditions.
Instead, maybe try something like
=sum(ArrayFormula(--regexmatch(D8:BM8; textjoin("|"; 1; A43:A47))))
Regexmatch returns a boolean, for all the cells in D8:BM8 (true if a match is found, false otherwise). These booleans are converted into 1 and 0 (see the -- in front of the regex). Then all those values are summed.
Copy and paste the code in a module.(VBA)
Select the cell you want to have the results
Use COUNTIFMATCH Function as the usally functions.
The first Argument is the range you want to count. The second Argument is the range with your criteria. e.g
=COUNTIFMATCH($A$1:$A$20,$C$1:$C$3) or =COUNTIFMATCH($A$1:$A$20,($B$1,$D$1))
whatever you need based on your needs.
Option Explicit
Function COUNTIFMATCH(Range As Range, Criteria As Range) As Integer
'counts the number of cells in one range by the values ​​of another range.
Dim datax As Range
Dim rslt As Range
Dim i As Integer
Set rslt = Range
For Each datax In Criteria
i = i + WorksheetFunction.CountIf(rslt, datax)
COUNTIFMATCH = i
Next datax
End Function

If statement status dependent on dates (3 columns).TODAY() does not work

Hi all I have a situation where I have 3 columns which results in 3 results.
3 columns are empty, display "0"
First column has a date <= today(), 2nd and 3rd column empty, result is "1"
First column has a date > today(), 2nd and 3rd column empty, result is "0"
Second column has a date and third column is empty (First col can be empty or filled), result = "2"
Third column has a date, result = "3"
Here is my code below:
=if(and(ISBLANK(A6), ISBLANK(B6), ISBLANK(C6)),"0",IF(and(A6<=NOW(), ISBLANK(B6), ISBLANK(C6)),"1",if(and(NOT(ISBLANK(A6)),B6<=NOW(), ISBLANK(C6)),"2",IF(C6<=NOW(),"3","0"))))
However I am getting mixed results, especially if the date in the first column is greater than the today's date, it shows up a result of "2" and not the expected "0"
So despite your somewhat mismatched directives - here is a start - I am still unsure about which of your rules actually overrides - so when you updated that I will update the formula:
=if(counta(A1:C1)=0,0,IF(LEN(C1)>0,3,IF(LEN(B1)>0,2,IF(AND(LEN(A1)>0,COUNTA(B1:C1)=0,A1>TODAY()),0,IF(AND(LEN(A1)>0,COUNTA(B1:C1)=0,A1<=TODAY()),1,)))))
A couple things I am doing here:
Part of the reason your formula is having issues is two major things -
1) you need to reverse the order of your IF statements to allow the cells in C or B to trump the other rules, if that is the result you want. This way if you always want a 3 when anything is in column C, that should be the second check after checking if all 3 are blank
2) when using things like <= a date or time - it treats blank cells as always being less than. So change/add one more check within your AND function to check that the length of it is greater than 0 so make sure there is a valid value in there.

Return 0 when a value of a cell is negative

I have a google spreadsheet that uses this function:
=SUM(E:E) - SUM(C:C)
It adds up all the values of column E and column C and them subtracts the difference. I would like to be able to return a 0 if the difference is negative.
=MAX(SUM(E:E) - SUM(C:C),0)
The MAX function receives a list values
eg. MAX(1, 2, 3, 4) would give 4
so if you give it 0 then it will return 0 since it's higher than the negative result
IF((SUM(E:E) - SUM(C:C))< 0,0,SUM(E:E) - SUM(C:C))
Possible without changing the existing formula but with formatting such as:
#.00;"0";0
This differs from a formula approach such as =MAX(SUM(E:E)-SUM(C:C),0) because adding a number to the output of that formula will give as a result the added number, where SUM(C:C) is greater than SUM(E:E). Adding the same addend to =SUM(E:E)-SUM(C:C) where SUM(C:C) is greater than SUM(E:E) will not give the addend as the result, except when the added is 0.
I took another route - I just copied the entire column to another column to the far right, and then referenced that column for my formulas in the column I want to edit.
When you're finished, "hide" the copied column (click on the column menu and there is a "hide" option), but DO NOT delete it, because then your formulas will not work.

Resources