I need to generate a list of values found in Column B, but I only want to include rows where the formula in Column F tests TRUE. This would ideally be a list contained within one cell where all the values from Column B are listed, separated by commas.
As an example:
| B | ... | F
----------------------------------
1 | 15 | | TRUE
2 | 10 | | TRUE
EXPECTED RESULT: "15,10"
I've tried VLOOKUP and INDEX/MATCH, but have thus far gotten nowhere.
If you have the TEXTJOIN function (Office 365, Excel 2016+), you can do it with a single formula:
=TEXTJOIN(",",TRUE,IF(F:F=TRUE,B:B,""))
This is an array formula, and you need to "confirm" it by holding down ctrl + shift while hitting enter. If you do this correctly, Excel will place braces {...} around the formula as observed in the formula bar
If your Excel does not have TEXTJOIN you will likely need VBA.
And you should shorten the whole column ranges that I used. Smaller ranges will improve computation speed. You could use either a dynamic range reference, or some size that is sure to encompass the entire data set.
Related
Stumped after looking for a bit...
I have a spreadsheet with items like so:
A B C
+------+----------------------+--------------+
| Code | Desc | Type | 1
+------+----------------------+--------------+
| 1 | Main item | Activity | 2
| 1.1 | Sub item | Sub-activity | 3
| 1.2 | Another sub item | Sub-activity | 4
| 2 | Another main item | Activity | 5
| 2.1 | Yet another sub item | Sub-activity | 6
+------+----------------------+--------------+
I want to create a dropdown based on Activity. I can do this in a typical cell (with ctrl + shift + enter for array formula):
={if(c2:c6="Activity",a2:a6,"")}
But I can't figure out how to put that formula into a named range properly. When I hit ctrl + shift + enter, no braces appear. When it's without braces, it doesn't seem to work, either (it shows the value as {...}).
Is there a way to make this work?
Thanks in advance
In the end, this wasn't possible via a named range; I ended up doing a variant of dependent dropdowns with offsets as well as two pivots, based on the blog page from Darren's comment above as well as this link. May be overkill, but at least I know how I got to it.
Setting up the first dropdown data source and data validation for the dropdown
For the first list, I created a pivot from the dropdown data source with row of column "Type" and values of count "Type" (the values aren't that relevant, but I found it useful to just know how any elements to expect for later dependent items). This pivot is in the standard default pivot location on a new sheet, where the header row starts on A3. Using a pivot also sorts it by default alphabetically (which I wanted). Turn of all total columns.
I then created a named range ("costCategory") with the following formula:
=OFFSET('PivotSheet'!$A$4,0,0,COUNTA('PivotSheet'!$A$4:$A$100),1)
That basically makes a list of the items and removes any blanks. It's not as dynamic as I'd like, but I think it's very unlikely I'll ever get beyond ~100 items on the list so I decided to live with it.
I created another named range ("emptyList") with the following formula:
={""}
So that I could also lock the first dropdown if the second, dependent one is selected (to prevent weird non-matching data issues).
For the table rows that needed the dropdowns, I put in the data validation for a list with this formula:
=IF(ISBLANK($B3),costCategory,emptyList)
where $B3 is the second, dependent dropdown location.
Setting up the second, dependent dropdown data source and data validation
5. I created another pivot from the same data source, with rows of "Type" and "Desc", and values of count of "Type" (again, the values not a big deal). The pivot layout was set to tabular, repeating labels, no totals or subtotals. I put this pivot next to the other one, with the first header row starting at E3. It also alpha sorts.
I put in helper columns to determine where the list starts for a particular parent of the dependent dropdown, and the number of rows of that list. It uses the same arbitrary long ranges approach as in the first dropdown - just put in a number of rows unlikely to be exceeded in the pivot. In col C, for getting the first row where the dependent data starts, I put this formula:
=ROW(INDEX('PivotSheet'!$F$4:$F$200,MATCH($A3,'PivotSheet'!$E$4:$E$200,0)))
In col D, for getting the number of cols where there is dependent data, I put this formula:
=(LOOKUP(2,1/('PivotSheet'!$E$4:$E$200=$A3),ROW('PivotSheet'!$F$4:$F$200))-ROW(INDEX('PivotSheet'!$F$4:$F$200,MATCH($A3,'PivotSheet'!$E$4:$E$200,0))))+1
Finally, in the column with the dependent dropdown (col B), I used the following data validation rule:
=OFFSET('PivotSheet'!$F$1,$C3-1,0,$D3,1)
Which basically takes the range that's found in the helper cols to make the dropdown list.
When these formulas are extended, they increment (A3 to A4, B3 to B4, etc.) so that they all still work even as you add rows to the listobject table.
Create a helper column in column D and write simple formula
=IF(C2="Activity",A2,"")
Once you have column D , you can create a list from column D ignoring the blank cells which is what you want.
P.S. If you're not concerned about the blank cells use the formula in column E2 and drag below which will give you consecutive values that you want to see in your list.
=IFERROR(SMALL($D$2:$D$6,ROW()-1),"")
I have looked for proper formula that would solve my problem but I couldn't find anything.
I have a table with multiple date ranges and I want to highlight all dates in my calendar between these ranges. I've tried to use formula AND
=AND(F5>=$A$6,F5<=$B$6)
however the formula highlights only dates between 1st range. I tried to put array ($A6:$A$9 and $B6:$B$9) but it doesn't work.
Column A Column B
row 6 | 05/01/2018 | 12/01/2018
row 7 | 03/04/2018 | 16/04/2018
row 8 | 06/05/2018 | 17/05/2018
row 9 | 01/11/2018 | 05/11/2018
My calendar starts in cell F5 and ends in AP16.
Regards,
Adrian
You need to wrap your AND's within an OR:
=OR(AND(F5>=$A$6,F5<=$B$6),AND(F5>=$A$7,F5<=$B$7), AND(...))
or, in a more compact but equivalent form:
=SUMPRODUCT((F5>=$A$6:$A$9)*(F5<=$B$6:$B$9))
or
=OR((F5>=$A$6:$A$9)*(F5<=$B$6:$B$9))
Each of the equality arrays returns an array of 1's or 0's. Multiplying them together is the equivalent of AND and will return a 1 if and only if both values in the same position are TRUE. Adding the arrays (the equivalent of OR) will then show if any result is a 1.
Although Excel 2016 will accept an OR in the conditional format formula, I seem to recall that some earlier versions will not, hence I have also supplied the equivalent SUMPRODUCT formula.
Or once again you can use countifs
=COUNTIFS($A$6:$A$10,"<="&F5,$B$6:$B$10,">="&F5)
For an Excel formula I need the first cell out of a list of cells which contains a numeric value:
A | B | C | ... | Z |
-----------------------------
| 0.1 | 0.4 | ... | =0.1
| | 0.2 | ... | =0.2
I use this schema:
IF(ISNUMERIC(A1);A1;IF(ISNUMERIC(B1);A2;IF(ISNUMERIC(C1);C1;IF(...))))))))
Unfortunately this only works for seven columns, because the maximum length is limited in Excel.
Is there any way to re-phrase this formula so that it doesn't get deeper with every additional column?
OK, lets see. Try this
=INDEX(A1:Y1,SUMPRODUCT((A1:Y1="")*1)+1)
The sumproduct counts the number of blanks, then the index looks up the value in the cell where number of blanks + 1
Hope that helps.
In a single cell you can do this with an array formula:
Isnumber provides the test in Excel 2007
Multiply the result by column()
Use an if statement to help the following min function along:
Use the min function to identify the first numeric column.
Remember to use Ctrl-Shift-Enter when you want to make an array formula, not just enter.
=INDEX(A1:Z1,MIN(IF(ISNUMBER(A1:Z1),COLUMN(A1:Z1),5000)))
This also finds the first used column across multiple rows should you need that functionality.
Perhaps this may help XL: How to Determine Top/Bottom Used Cells in a Sparse Array
astanders answer works (with the assumption that the cells following the first number are allways filled).
You can also write your own function in a VBA Module.
Public Function getFirstNumber(ByRef sourceRow As Range) As Double
For Each Cell In sourceRow.Cells
If WorksheetFunction.IsNumber(Cell) = True Then
getFirstNumber = Cell.Value
Exit Function
End If
Next Cell
End Function
Hi All You Amazing People
Update
You know what, I should let you know that I am actually trying to do this with numbers and not alphabets. For instance, I have a field with value like 225566 and I am trying to pick out fields which have 55 in them. It is only now I realize this might make a huge difference
ColumnA | ColumnB |
225566 | 2
125589 | 3
95543 | 2
(Below is what I had asked first and later realized I wasn't asking the right question.)
*Lets say I have a table as
ColumnA | ColumnB |
AABBC | 2
AADDC | 3
ZZBBC | 2
Now how could I get a SUMIF for those rows where Column A has a field with BB in it? Assume that there are hundreds of rows. I realize that I have to borrow something conceptually from the way text to column is done. But I wonder if anyone would know how I could do this. Thanks a lot.*
Since you're trying to do this on numbers, you'll need to use an array formula.
If your test values are in A3:A5 and your values to sum are in B3:B5, this will work:
=SUM( IF(ISERROR(FIND("55", TEXT(A3:A5,"#"))), 0, 1) * B3:B5 )
When entering an array formula, use Ctrl-Shift-Enter rather than just hitting Enter.
This sums the product of the sum value and a 0 or 1 from the IF() statement, which tests whether or not each test value, after being converted to text, contains a "55".
I think you will need an matrix/array formular to do this:
{=SUM(IF(ISERROR(FINDEN("55";A2:A4;1));0;1))}
The weird brakets {} indicate it is an matrix formular you get them by pressing SHIFT+CTRL+RETURN instead of Return when editing the formula.
This formula will cycle through the range A2:A4, check if it finds "55" inside and if so add 1 to the sum.
Google array/matrix formulas as they are not self explanatory.
Best
Jan
In Excel 2003 and 2007 (and possibly earlier versions, I cannot test), you can use * as a wildcard character in the match. For example, with your sample data set C1 to
=SUMIF(A1:A3,"*BB*",B1:B3)
and you should see the value 4.
Create a 3rd column (ColumnC) and put this formula in it:
=Text(A2,0)
Drag that column down to complete your column. This will format the value as text. Next, use SUMIF as DocMax explained, except with different columns:
=SUMIF(C1:C3,"*BB*",B1:B3)
The reason you do this is because you need to be reading a Text value, not a Number value when using the *BB* comparison of SUMIF. Great question.
I'm trying to calculate the conditional median of a chart that looks like this:
A | B
-------
x | 1
x | 1
x | 3
x |
y | 4
z | 5
I'm using MS Excel 2007. I am aware of the AVERAGEIF() statement, but there is no equivalent for Median. The main trick is that there are rows with no data - such as the 4th "a" above. In this case, I don't want this row considered at all in the calculations.
Googling has suggested the following, but Excel won't accept the formula format (maybe because it's 2007?)
=MEDIAN(IF((A:A="x")*(A:A<>"")), B:B)
Excel gives an error saying there is something wrong with my formula(something to do with the * in the condition) I had also tried the following, but it counts blank cells as 0's in the calculations:
=MEDIAN(IF(A:A = "x", B:B, "")
I am aware that those formulas return Excel "arrays", which means one must enter "Ctrl-shift-enter" to get it to work correctly.
How can I do a conditional evaluation and not consider blank cells?
Nested if statements.
=MEDIAN(IF(A:A = "x",IF(B:B<>"",B:B, ""),"")
Not much to explain - it checks if A is x. If it is, it checks if B is non-blank. Anything that matches both conditions gets calculated as part of the median.
Given the following data set:
A | B
------
x |
x |
x | 2
x | 3
x | 4
x | 5
The above formula returns 3.5, which is what I believe you wanted.
Use the Googled formula, but instead of hitting Enter after you type it into the formula bar, hit Ctrl+Shift+Enter simultaneously (instead of Enter). This places brackets around the formula and will treat it as an array.
Be warned, if you edit it, you cannot hit Enter again or the formula will not be valid. If editing, you must do the same thing when done (Ctrl+Shift+Enter).
There is another way that does not involve the array formula that requires the CtrlShiftEnter operation.
It uses the Aggregate() function offered in Excel 2010, 2011 and beyond. The method also works for min,max and various percentiles.
The Aggregate() allows errors to be ignored, so the trick is to make all values that are not required cause errors. The easiest way is to do the task set above is:
=Aggregate(16,6,(B:B)/((A:A = "x")*(B:B<>"")),0.5)
The first and last parameters set the scene to do a percentile 50%, which is a median, the second says ignore all errors (including DIV#0) and the third says select the B column data, and divide it by a number which is one for all non empty values that have an x in the A column, and a zero otherwise.
The zeros create a divide by zero exception and will be ignored because a/1=a and a/0=Div#0
The technique works for quartiles (with an appropriate p value), all other percentiles of course, and for max and min using the large or small function with appropriate arguments.
This is a similar construct to the Sumproduct() tricks that are so popular, but which cannot be used on any quantiles or max min values as it produces zeros which look like numbers to these functions.
Bob Jordan
Perhaps to generalize it a little more, instead of this...
{=MEDIAN(IF(A:A="x",IF(B:B<>"",B:B)))}
... you could use the following:
{=QUARTILE.EXC(IF(A:A="x",IF(B:B<>"",B:B)),2)}
Note that the curly brackets refer to an array formula; you should not place the brackets in your formula but press CTRL+SHIFT+ENTER (or CMD+SHIFT+ENTER on macOS) when entering the formula
Then you could easily get the first and third quartile by altering the last number from 2 to 1 or 3 respectively. QUARTILE.EXC is what most commercial statistical software (e.g. Minitab) use by the way. The "regular" function is QUARTILE.INC, or for the older versions of Excel, just QUARTILE.