My raw data contains yes, no and NA (Column AJ:AN).
I convert them to 1 if yes, 0 if no and blank if NA (Column CG:CK).
Based on the data in columns CG:CK, how can I get Column DM to show 100% if there are no "0" (blanks and Yes only), 0.00% if there is even just one "0" in any of the 5 columns and blank if all are blanks?
Thank you for your help!
Use COUNTIF:
=IF(COUNTIF(CG2:CK2,0),0,IF(COUNTIF(CG2:CK2,1)=COLUMNS(CG2:CK2),1,""))
Using a combination of nested IF and COUNTIF is in the right direction, but I would rather use your data in AJ:AN rather than the data in CG:CK in the formula.
Suppose your data starts in Row 1, you can use the following formula to return either blank "", 1 or 0 based on the given criteria:
show 100% if there are no "0" (blanks and Yes only), 0.00% if there is even just one "0" in any of the 5 columns and blank if all are blanks?
=IF(COUNTIF(AJ1:AN1,"N/A")=5,"",IF(COUNTIF(AJ1:AN1,"No")>0,0,1))
Change the row number to suit your case.
Then you need to change the format of the outcome to 0%;;0.00% through custom format, so it will show 100% without decimal places and 0.00% with two decimal places (if this is exactly what you want).
In cell DM2 enter this formula:
=IF(COUNTIFS(CG2:CK2,0)>0,0,
IF(SUM(CG2:CK2)>0,1,TEXT(,)))
and apply this numberformat:
0%;0%;0.00%;#
suggest also to change the formulas in CG2:CK2 to something like:
=IF(AJ2="Yes",1,IF(AJ2="No",0,TEXT(,)))
in order to eliminate the redundancy of IF(AJ2="N/A","","") in the formula
=IF(AJ2="Yes",1,IF(AJ2="No",0,IF(AJ2="N/A","","")))
Related
If I have 1200 rows, and I want 120 of my rows to say "Yes" and the rest to say "No", how should I apply this to an Excel file? I know to use:
=CHOOSE(RANDBETWEEN(1,2),"Yes","No")
But I do not know how to make it so that 10% of random rows will have "Yes" in their respective row. Is there a way to tweak this formula.
I personally like this formula:
If(rand()<0.1,"Yes","No")
Of course, they are randomly distributed. So it won't be exactly 10%.
To make exactly 120 = "Yes" I would use a helper column with =rand(). Then next to it the formula if(rank(b1,b:b)<121,"Yes","No")
With Microsoft365 you could try:
=IF(SORTBY(SEQUENCE(1200),RANDARRAY(1200))<121,"Yes","No")
There is a general approach to this kind of question:
I have a function, generating a random number between 0 and 1 (e.g. rand()).
I want to have a certain value for 1/n cases.
Solution:
n * rand(), and check if the result is between 0 and 1.
Are you wanting to have the distribution be exactly 10% - 90% or is this just a target.
You could use =IF(RANDBETWEEN(1,10) = 1,"YES", "NO")
I have the following formula in my B:B column
=VLOOKUP(A1;'mySheet'!$A:$B;2;FALSE)
It does output in B:B the values found in the mySheet!B:B where A:A = mySheet!A:A. It works fine. Now, I would like to also get the third column. It works if I add the following formula to the whole C:C column:
=VLOOKUP(A1;'mySheet'!$A:$C;3;FALSE)
However, I'm working with more than 100k lines and about 40 columns. I don't want to do 100k * 40 * VLOOKUP, I would like to only do it 100k and not have to multiply this by all the columns. Is there a way (with array-formulas maybe) to just do the VLOOKUP once per line to get all the columns I need?
data example
ID|Name
-------
1|AB
2|CB
3|DF
4|EF
ID|Column 1|Column 2
--------------------
1|somedata|whatever1
4|somedate|whatever2
3|somedaty|whatever3
I would like to get:
ID|Name|Column 1|Column 2
-------------------------
1|AB |somedata|whatever1
2|CB | |
3|DF |somedaty|whatever2
4|EF |somedate|whatever3
INDEX works fast than VLOOKUP, I would recommend using that. It'll reduce the strain that many vlookups would put on your system.
First find the row that contains what you need in a helper column with MATCH:
=MATCH(A1,'mySheet'!$A:$A,0)
Then an INDEX using that number, that you can drag across and populate all your columns with:
=INDEX('mySheet'!B:B,$B1)
Your output would be akin to:
ID|Name|Match |Column 1 |Column 2
-------------------------
1|AB |Match1|IndexCol1|IndexCol2
2|CD |Match2|IndexCol1|IndexCol2
3|EF |Match3|IndexCol1|IndexCol2
Also! I'd recomend setting these ranges to actually cover the data, rather than referencing the whole column, for additional speed gains, e.g.:
=INDEX('mySheet'!B1:B100000,$B1)
I was thinking more on your problem, and if you have contorl over the data you're looking up on, I have another suggestion you could try.
In 'mysheet', where the raw data is kept, add in a new column that concatenates each column into one cell, with some sort of unique divider not in your data:
=B1&"+"&C1&"+"&D1&"+"&E1 etc...
Then you could do one VLOOKUP or INDEX/MATCH for each row, instead of 40.
Once you have it in your new sheet, you could split the results back out.
Splitting without formulas
Copy/Paste the results of the lookup formulas as Values in the next column.
Select that column, and in the Data tab on your ribbon, select Text to Columns.
Leave it on Delimited, hit Next. Uncheck Tab, check Other, and input your delimeter (+ in my example).
Click Finish.
Splitting with formulas
Use =FIND() to locate each delimter, and =MID() to pull out the text between each set of delimeters, using the previous delimeter as the Start_num.
Definitely the more complex of the two methods.
If I'm understanding correctly one thing I would do to start would be to use =VLOOKUP(A1;'mySheet'!$A:LastColumn;COLUMN(B1);FALSE). This way your column reference will move as you drag your Vlookup to the right.
No formula.No output. So there can't be a way to apply formula on 1 column only and get on the others.
The other feasible way is, put i formula in 1 cell, use $ signs inteligently and drag across all cells in a giffy without having to put vlookup 40 times.
Vlookup has 4 codes to input
1-Lookup Value. Use this $A1 (put $ on A and not 1)
2-Source data- Put $ signs everywhere
3-Column index no. Just above your entire data,in the 1st row,add an empty row.Put the values 1 in A1, 2 in B1, 3 in C1 and so on. Now in the formula,instead of manually putting "2" or "3" Give reference to these cells.Put $ on Numberal and not column ( B$1).
4- Type false or 0
Then drag this across everywhere.
Lookup Value. Use this $A1 (put $ on A and not 1)
Source data- Put $ signs everywhere
Column index no. Just use column name from where data needs to be pulled (e.g. COLUMN(B1) if Lookup value is in Column A and you want value from column B).
Type false or 0
I need to get a MAX of a range that is bound by two 1s in a helper column.
The 1s are a variable number of rows apart.
By way of example, here is a sample of what I'm talking about:
1
0 -1.10%
0 0.00%
1
0 1.43%
0 1.15%
0 2.12%
0 2.69%
0 1.32%
0 0.86%
0 -0.69%
1
~
[and so on]
So, for instance, there are two ranges visible that I'm interested in here -- the range between rows 1 and 4 and the range between rows 4 and 12.
In a third column, wherever there is a 1 in the helper column, I want the MAX of the ranges.
I've managed to cobble together this formula that does the job (this is copied directly from the spreadsheet so it's in row 122 and the data currently goes to row 16120, the helper column is column E and the column with the values is F):
=IF(E122=1,MAX(F122:INDIRECT(ADDRESS(ROW()+MATCH(1,E123:$E$16120,0),COLUMN(F122),4))),"")
My basic thinking is to build the bottom of the range by looking for the next 1 down the helper column (using MATCH), add that to the current row (using ROW and COLUMN) wrapped inside an ADDRESS function and then tie it all together using INDIRECT. Finally, it sits inside an IF to only hit the rows with a 1 in the helper column.
Can anyone think of a more elegant, less cumbersome way?
Thanks in advance.
If you have a larger dataset, I'd recommend to use INDEX instead of OFFSET! The latter is volatile, i.e. Excel will recalculate all OFFSET formulas and any dependants every time it does any recalculation. INDEX on the other hand is non-volatile, i.e. only if any of it's predecessors change will Excel recalc the formula.
Therefore, give this formula a try:
=IF(E122=1,MAX(F123:INDEX(F123:$F$16120,MATCH(1,E123:$E$16120,0))),"")
You could use OFFSET:
=IF(E122=1,MAX(OFFSET(E122,1,1,MATCH(1,E123:$E$16120,0)))-1,"")
I have a list of 4000 different price values in one column. I want to calculate the average of the first X values in the column and display the result in cell "B21". The value of X can be changed and is located in cell "B20". How would I use excel functions to do this? Perhaps Average and Offset?
This will do it:
=AVERAGE(A1:INDEX(A:A,B20))
Note that a 0 or blank in B20 will average the whole column. You could filter that out with an IF statement:
=IF(B20=0,"NA",AVERAGE(A1:INDEX(A:A,B20)))
As Barry mentioned in his comment, I chose INDEX because it's not as volatile as OFFSET and INDIRECT.
How about:
=AVERAGE(INDIRECT("A1:A" & B20))
I'll throw my hat in the ring as well using the functions the op suggested.
=average(offset(A1,0,0,B20))
As Doug's comment this will also give an error with blanks or 0 in B20.
Gordon
What is the best way to find cells whose formulas refer to blank cells in Excel VBA. I'd like to delete any cell that references a blank cell.
More concretely, I have a two sheets: One sheet contains the actual values:
Product Month1 Month2 Month3
Sample1 1 3 5
Sample2 5 7 6
Sample3 3 8 2
The other is a summary view, with formulas to sum up the values, with the following formulas:
Product Month1
=values!A2 =SUM(values!B2:D2)
=values!A3 =SUM(values!B3:D3)
=values!A4 =SUM(values!B4:D4)
=values!A5 =SUM(values!B5:D5)
TOTAL =SUM(values!B:D)
Now in the previous example, the last raw refers to a blank row, namely the fifth row. Excel will show those cells as "0". Is there a mechanism to delete those cells within VBA?
Please note I prefer deleting the rows, to keep the TOTAL row close to the actual last value. Otherwise, the Total row might be distant from the rest of the values. Also, having blank cells with formulas may lead to a large Excel file.
EDIT: Clarified the question to role out the keeping the cells blank.
Is it always the last row, that could evaluate to 0?
If so u Could use a IF statement like:
=IF(SUM(values!B2:D2) > 0 ,values!A2,"") =IF(SUM(values!B2:D2),SUM(values!B2:D2),"")
No VBA needed...
I think Autofilter is the way to go here. If there's a zero in column A, I'm guessing you want to hide that whole row. You say delete, but I wonder if hide is a better way.
Put a filter on the range and for column A select everything except 0.
You could do this without having to write code to delete rows. I would use a variant of Arnoldiuss' solution.
For the Month total use:
=IF(LEN(values!A2)>0,SUM(B2:D2),"")
In this way, you can simply fill-down all the formulas and not have to worry if you reference a non-existent product.
Based on your edit i guess a pivot table fits your needs.
Add the products to the rowlabels and add the following calculated field to the values
=SUM(Month1,Month2,Month3)
Then add a value filter > 0
I would not recommend deleting rows in the "formula worksheet", for future use the series would wrecked, because of the missing references.