I have data in rows where each column represents a day, some of which are blank and some of which have numbers. I want to "scan" down the row, comparing each cell with the one before to the left of it (or the one 2 spaces left of it, etc). For example, I want to sum the number of cells (days) with a blank in the cell before it. Or, I want to sum the number of cells that are greater than the cell to the left of it. I can't figure out how to dynamically compare to the prior column using addresses that change with each cell.
This is from what I understood from your Question:
If you refer to the screenshot below, you want to count Columns B to H if the column has a number and the column to the left is blank.
So, if this was just one column, we would write the formula as:
=COUNTIFS(B3,">0",A3,"")
Now since you want to do this for a range of columns (an array of cells), you need to do something like:
=COUNTIFS(B3:H3,">0",A3:G3,"")
and accept with a Ctrl + Shift + Enter.
So the formula would be displayed as:
{=COUNTIFS(B3:H3,">0",A3:G3,"")}
Array formulas are perfect for this task. I can't give you a lecture on the topic but you should read on it. Basically, you can select multiple cells in a range and act as if it was one cell.
For example, you could do something like this:
=SUM(IF($A$1:$A$100="", 1, 0))
When you enter array formulas, be sure to hit CTRL + SHIFT + ENTER in the formula box to signify that you want Excel to treat this formula as an array formula. Otherwise you will not get the expected results.
Using this method you can do any kind of comparison. Sometimes it helps to see how Excel treats the formula. You can select part of the formula in the formula editor and hit F9 to see what this segment computes to according to Excel.
Related
Summary:
I am currently trying to fill a formula to a whole column in Excel to the end of an adjacent dataset (A2:A14500). Instead of the usual behaviour where Excel will flash-fill it to the end of the dataset in the adjacent column B2:B14500 for example, it instead flash fills it to the whole column (B2:B1048576), even past the end of the dataset in column A.
Use Case:
Column A is just a =FILTER command to pull from another sheet, excluding the blanks (in my live sheet, cell A1 is =FILTER('Raw'!A:A,'Raw'!A:A<>""). All other columns contain headers in cell 1:1. Cell B2 contains a basic 2 part =IF statement with an error catchall: =IF(ISERROR(VLOOKUP(A2,'Lookup'!A:B,2,FALSE)),"No",IF(VLOOKUP(A2,'Lookup'!A:B,2,FALSE)="Error","Yes","No"))
In my current example, the =FILTER in column A produces 14500 rows of data. I am attempting to use the fill handle to populate B3:B14500 with the =IF statement currently in cell B2. When I double press the fill handle, it fills the whole column of B3:B1048576, which causes Excel to crash (I am trying to do the same for 32 columns (B2:AG14500), so it is flash-filling over 33 million formulas instead of 600K).
Expected result when double clicking flash handle in formula column:
Data
Formula
1
Yes
2
Yes
3
No
4
Yes
Actual current result when double clicking flash handle in formula column:
Data
Formula
1
Yes
2
Yes
3
No
4
Yes
No
No
No
No
No
Final Comment:
Usually, when double pressing the fill handle on a formula in column B, I'd expect it to match the end of the dataset in column A (If column A contains data in cells A2:A100, I'd expect double pressing a formula in cell B2 to copy that formula to B2:B100, not B2:B1048576).
I know that copy-pasting is an option, as is manually dragging the fill handle down, but this involves me using weird Ctrl/Shift/Arrowkey combos to select the right range (this is supposed to be user friendly by others who don't use Excel much), or a long time holding the fill handle as there's 14K rows of data. Additionally, I am aware of Home>Fill>Down and Data>Flash Fill but neither of these work for me (Fill Down replaces the formula in B2 with the header in B1 and only copies down to B2, and Flash Fill tells me it can't see a pattern, despite providing it 1/2/5/10 cells of example data).
Any assistance with understanding why the double-click fill handle isn't working (I suspect it's due to the way it handles the =FILTER in column A), or how to overcome this would be appreciated. Currently using MSO365. Thanks!
PS. The reason I haven't filled the formulas manually is the number of cells in column A will change for each report generated with this spreadsheet, so the number of cells it needs to populate will vary.
=IF(ISERROR(VLOOKUP(A2#,'Lookup'!A:B,2,FALSE)),"No",IF(VLOOKUP(A2#,'Lookup'!A:B,2,FALSE)="Error","Yes","No"))
Adding # to the cell range that results in the spill will reference the whole spill. In case of lookup it'll spill the result of the lookups from the first to the last of the cells from the spill range.
PS since you own Office 365 you might want to look into XLOOKUP instead of VLOOKUP. XLOOKUP already has an embedded value if not found.
I have a spreadsheet that I'm using to try and keep track of google keyword rankings, but I can't figure out how to track the last change in keyword ranking, meaning the last cell in the row MINUS the second to last cell in the row. I've included a picture on what I'm trying to accomplish. The formula would take, for example, in J3-I3 to get the last change of 4 shown in D3.
Right now I have this code:
=(LOOKUP(2,1/(3:3>0),3:3))-LOOKUP(9E+300,B3:INDEX(B3:J3,MATCH(9E+300,B3:J3)-1))
Which is fine, but I need to keep changing the cell references is. Is there any easier way to accomplish this?
You can use just INDEX(MATCH()) and refer to the full row.
=INDEX(3:3,MATCH(1E+99,3:3))-INDEX(3:3,MATCH(1E+99,3:3)-1)
If you have, say, 12 columns B="Jan" to M="Dec" with a formula in each, and you need to calculate the difference between the latest month's value and the previous month's value, the formula above does not work if any columns are blank but with formulas, or until you have a value for each of the 12 months.
If you want to calculate, say, Jun minus May when Jul to Dec are blank except for their formulas, this formula (for row 4) will do it for whatever the latest month with a numerical value is:
=INDEX(4:4,MAX(IF(ISNUMBER(B4:M4),COLUMN(B4:M4))))-OFFSET(B4,0,SUM(IF(ISNUMBER(B4:M4),1))-2,1,1)
It must be entered with Ctrl+Shift+Enter.
#ScottCraner has provided an answer with the right logic, which is to
locate the second last and last number in each row, and then perform a
simple subtraction between the two.
INDEX+MATCH is one way of solving the question, but in this case, given that all data are stored in a table, and to add the flexibility of
1) moving the table around or across worksheets;
2) entering numeric value in the same row outside of the table;
without incurring errors, I've used OFFSET+COLUMNS instead.
Please note in my example I have given a name to the table, called it Tbl_WordRk, and I have added some data (in the gray area) for testing purpose.
Basically, OFFSET works in similar logic as INDEX, with a known starting point (such as B3 in my example), it will find the value (or even a range of values) in another row or column as long as you know the relative position of the value compared to the starting point. For example, if your starting point is cell A1, the following OFFSET function will return the value in cell D8.
=OFFSET(A1,7,3) which is interpreted as 7 rows down and 3 columns to the right of cell A1
COLUMNS finds the total number of columns of a given range, which is perfect for finding a column position within a table. The following formula will return number 7 which is the total number of columns of the table in my example, but please note it is NOT the relative column position of the last column to cell B3.
=COLUMNS(Tbl_WordRk)
You need to add -1 to the above formula to find the relative column number of the last column from B3. And therefore, adding -2 will return the relative column position of the second last column from B3.
So the final formula in cell B3 in my example is
=OFFSET(B3,,(COLUMNS(Tbl_WordRk)-2))-OFFSET(B3,,(COLUMNS(Tbl_WordRk)-1))
Then you just drag it down to the last row.
Just one more advice on the conditional format of your example, I would prefer not to show a green upward arrow if there is no change in the word ranking. If you know how to edit an existing conditional formatting, here is how to set it:
Cheers :)
I have two columns. Each cell in column A contains a full sentences and each cell in column B contains a word or phrase. I would like to check if the contents of any cell in column B appears in each cell in column A and get the word or phrase of the cell/cells of Column B that appear in Column A.
Column A Column B Search Result
Twenty One Twenty Twenty, One
Five Boxes Ten
Ten Words Thirty Ten
Twenty Pens One Twenty
You can use a matrix (array) formula to achieve this. Please enter the following formula into cell C2 (assuming your table starts at A1):
=LEFT(CONCAT(IF(ISNUMBER(SEARCH($B$2:$B$5;A2))=TRUE;$B$2:$B$5&", ";""));MAX(LEN(CONCAT(IF(ISNUMBER(SEARCH($B$2:$B$5;A2))=TRUE;$B$2:$B$5&", ";"")))-2;0))
Please make sure you press Ctrl+Shift+Enter after pasting the formula into the cell! This combination says to the Excel that you are using a matrix formula. If you press Enter only the formula will not work properly. Then you can copy the formula into cells below in a standard way. If you want to input more data you need to expand range $B$2:$B$5.
You can check my example sheet here. You can also read more about matrix formulas in Microsoft documentation.
Edit #1
There is a different list separator in the US locale. If you use US locale please try this formula:
=LEFT(CONCAT(IF(ISNUMBER(SEARCH($B$2:$B$5,A2))=TRUE,$B$2:$B$5&", ","")),MAX(LEN(CONCAT(IF(ISNUMBER(SEARCH($B$2:$B$5,A2))=TRUE,$B$2:$B$5&", ","")))-2,0))
Please keep in mind to use Ctrl+Shift+Enter after entering the formula.
I am attempting to use an IF statement to check whether the sum of two cells from another Excel sheet is greater than or equal to 1.
For a sheet called Test1 with the values of interest in column C, this is what I have so far, which works fine:
=IF((Test1!C1+Test1!C2>=1),1,0)
In column B on a second sheet that I'll call Test2, I want to copy this formula down 200,000 rows. However, if the aforementioned formula is in cell B1, for the formula in B2 I would like the formula to read:
=IF((Test1!C3+Test1!C4>=1),1,0)
I want to copy the formula down the column so that the second cell reference in the formula in the first row does not become the first cell reference in the formula in the second row (eg. it would go C1+C2, then C3+C4, C5+C6, etc.).
I have tried manually entering the formula for a few rows, highlighting those, and copying them down but can't get the desired cell reference pattern. If I highlight and drag these first three formulae down another three rows, C4 and C5 are repeated and not in the correct pair.
=IF((Test1!C1+Test1!C2>=1),1,0)
=IF((Test1!C3+Test1!C4>=1),1,0)
=IF((Test1!C5+Test1!C6>=1),1,0)
=IF((Test1!C4+Test1!C5>=1),1,0)
=IF((Test1!C6+Test1!C7>=1),1,0)
=IF((Test1!C8+Test1!C9>=1),1,0)
I have tried using OFFSET() within this formula but couldn't get it to work. I am basically just wanting to add 1 to each of the cell references in the formula, as compared to the previous row (but not to actually add 1 to the value of that cell, as would happen with C1+1 for example).
Any insight would be greatly appreciated!
If you plan on copying this down 200K rows then you will want the absolute simplest formula that accomplishes the stagger. Avoid the volatile OFFSET function or be prepared to spend a lot of time waiting for random calculation cycles to complete. A volatile function will recalculate whenever anything in the workbook changes; not just when something changes that involved the formula in the cell.
=--(SUM(INDEX(Test1!C:C, (ROW(1:1)-1)*2+1), INDEX(Test1!C:C, (ROW(1:1)-1)*2+2))>=1)
The following formula should do the trick:
=(SUM(INDIRECT("C"&ROW()*2-1);INDIRECT("C"&ROW()*2))>=1)*1
And that's the version using IF:
=IF(SUM(INDIRECT("C"&ZEILE()*2-1);INDIRECT("C"&ROW()*2))>=1;1;0)
You say I am basically just wanting to add '1' to each of the cell references in the formula but appear to be incrementing by 2, so I am confused but an option might be to apply you existing formula to 400,000 rows, together with =ISODD(ROW()) in another column, then filter on that other column to select and delete those showing FALSE.
Excel's autofill won't do the 2-cell shift that you're looking for. You can use the functionality that is there.
Put =IF((Test1!C1+Test1!C2>=1),1,0) in the top cell and drag a copy to the second row (it will be =IF((Test1!C2+Test1!C3>=1),1,0) but that's okay). Now, put 'A' and 'B' in the next column. Select all 4 cells and copy them down 400k rows.
Use filter to delete rows flagged with 'B' and delete the blank rows.
(Select blank rows with [F5] click Special and select Blanks, then right-click and delete)
Here is all you need. It's fast and nonvolatile.
=--(SUM(INDEX(Test1!C:C,ROW(1:1)*2-2):INDEX(Test1!C:C,ROW(2:2)*2-2))>=1)
Copy it down as far as you like.
I have an excel file generated by SAP. I need change its format from multiple tables separated by a title to one single table. This is the original table:
and i need it to look like this:
Im new to excel, so i dont have a clue how to do it.
I cant do it manually becuase the file has 5000+ rows.
Any guidance?
I usually use the generic formula:
=IF(XX="",YY,XX/ZZ)
Where XX is a cell you can use to identify a header to append to the individual transactions and YY is the cell directly above the cell you have put your formula. XX is when you need that value itself, ZZ is another value. You'll understand when you apply it.
For instance, here, you could use cell D5 to do this. I would insert two columns before column D (the value of cell D5 is now in cell F5), and put this formula in cell C5:
=IF(F5="",C4,B5)
I will then fill the formula down. This carries the Material ID everywhere down to the last row. There are two quick ways to do this in a file of this type:
Copy the formula, scroll to the bottom of the sheet, hold Shift and click the last cell in the column, then paste.
Select the cell containing the formula, scroll to the bottom of the sheet, hold Shift and do Ctrl + ,D.
In cell D5, I would put the formula:
=IF(F5="",D4,F5)
And fill it down as well to get the material description.
Now for the size per unit, you can create a column to the right of column K (column K now has 'Size per Unit' since we inserted two columns earlier), and put this formula in cell L6:
=IF(K6="",L5,K6)
Fill it down to get it everywhere.
Now, to finish it up, select the whole sheet and copy/paste values (Paste Special > Paste Values) to remove the formulae. Delete rows 1 and 2, put a filter and sort by a field such as the column 'Metric'. Go to the bottom and delete the no longer needed rows.
As a bonus, if you need to make absolutely sure that the order of the transactions is the same as initially, insert a column somewhere, put sequential numbers into it; that is the first cell in the column has 1, the second 2, then 3 etc and fill to the bottom. Be sure that it is in the filter when you delete the unneeded rows, and sort by this column when you are done.
5000+ rows is still good though, I've had to deal with 10+ workbooks each with ~90000 rows once ;)