I have 5 cells on the first row: A1 is 1, B1 is 2, C1 is 3, D1 is 4 and E1 is 5. Now I want to pick the odd numbers and name them "list_a_odd", so I hold CONTROL and select A1, C1 and E1, and type "list_a_odd" in the name box and hit ENTER. Now in A2, if I type "=SUM(list_a_odd)", it'll give me the result of 9, which is correct and expected. But if I type in "=list_a_odd", it gives me an error "#VALUE!".
However, if I select all 5 cells (A1 through E1) and name it "list_a", and I put "=list_a" in A2, it'll show "1" in the cell, and I can drag A2 to E2 to show all the 5 numbers in list_a. So that looks like only a problem when referencing non-consecutive named ranges in a cell. Is this an excel bug?
The list_a behaviour you describe is an example of the implicit intersection feature of ranges. list_a refers to a continuous range A1:E1, a formula expecting a single cell, when placed in the A to E column range using this range reference works out the intersection point and returns that cell.
That is, a formula in C2 =A1:E1 or =list_a_odd actually retuns a refence to just C1.
As you say, list_a_odd is a discontinuous multi area range. And implicit intersection doesn't apply to discontinuous ranges.
Some (but not all) functions work with discontinuous ranges, including SUM, that's why =SUM(list_a_odd) works as expected, just as =SUM(A1,C1,E1) works too.
EDIT
To return a continuous range that represents a discontinuous range I would use a user defined function combined with an array formula.
In the UDF use the Range.Areas property to loop through each of the sub ranges in a discontinuous range (remember that each item in Areas can be a single cell or a range in its own right). Build up an array of values to return to the array formula on the sheet.
The exact details will depend on your specific requirements and how generalised you want to make the UDF. Have a go, and post again if you need more help
Related
Need Help on Named Ranges in Formulas:
I have a second workbook ('TEST.xlsx') as the destination, referencing worksheet-scoped named ranges (in 12 columns X 75 rows) in the source workbook ('FLOW.xlsx'). I want to create a formula that will match a look-up value (a date entered into cell C3 in TEST that will return the matching named range IF there are 2 or more blank cells in that matched named range/column and the remaining named ranges/columns in that set of 12 columns with 2+ blank cells. The 12 separate columns in the source workbook ('FLOW') are named by month, year and location (ex., "jan_2019_class.1","feb_2019_class.1", etc.), the worksheet columns being C, H, M, R, W, AB, AG, AL, AQ, AV, BA, and BF. The rows are 80-155. I've only been able to make a simple working COUNTBLANK formula in my TEST workbook, ex.:
=COUNTBLANK('[FLOW.xlsx]Class_1-Chart'!jan_2019_class.1)
But NOT for successive columns (with different named ranges and the columns are non-sequential); and I can't figure out the functioning formula to combine with this to get the count AND data returned by criteria as described above. Please, no VBA/macros.
Thank you in advance for the help!
'TEST.xlsx' Screen Shot-RVSD
FLOW.xlsx- sample screenshot
There are many approaches but I personally prefer the use of helper rows/columns/cells and named ranges.
In my demonstration I used two class attendant schedule in two different year from January to June as shown below (they are sitting in Column C to M in my example):
As shown above, I have added two helper rows on top of each schedule. The first helper row is used to find out if there is 2 or more vacancies in each month, if so returns TRUE. I have given the name check.2019.class.1 and check.2021.class.5 for each of them.
The second helper row is simply showing the range name of each month such as jan_2019_class.1, feb_2019_class.2 etc. I have given the name NameRng.2019.class.1 and NameRng.2021.class.5 for each of them.
On the TEST sheet I have the following set up:
where the look up value in cell C3 is actually returned by a formula so it can be "dynamically" changed by the user. Please note in the following formula I used a name ClassNo which is essentially the value from cell B3.
=B2&"_"&B1&"_class."&ClassNo
I have also named cell C3 as Start_MthYrClass which will be used in my following formula.
The formula for looking up the first available month in 2019 if the start month is jan_2019_class.1 is:
=INDEX(NameRng.2019.class.1,MATCH(1,(TRANSPOSE(ROW($1:$11))>=MATCH(Start_MthYrClass,NameRng.2019.class.1,0))*Check.2019.class.1,0))
Please note it is an array formula so you MUST press Ctrl+Shift+Enter upon finishing the formula in the formula bar otherwise they will not function correctly.
The logic is to first "filter" the range NameRng.2019.class.1 using this formula =TRANSPOSE(ROW($1:$11))>=MATCH(Start_MthYrClass,NameRng.2019.class.1,0), in which ROW($1:$11) represents {1;2;3;4;5;6;7;8;9;10;11} and TRANSPOSE will turn it into {1,2,3,4,5,6,7,8,9,10,11}. This range of numbers represents the column index in that specific range which is Column C to M (in your case it would be ROW($1:$56) as your data is in Column C to BF). Then I use MATCH to return the start column index of the look up month jan_2019_class.1, and it should return 1 as this month starts in the 1st place/column in the range NameRng.2019.class.1. So this is what I am actually comparing: {1,2,3,4,5,6,7,8,9,10,11}>=1, and it will return {TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE}.
Then I multiply the above result with range Check.2019.class.1 which is essentially {FALSE,0,FALSE,0,TRUE,0,FALSE,0,TRUE,0,TRUE}. Then I will get {0,0,0,0,1,0,0,0,1,0,1}. FYI in Excel TRUE=1 and FALSE=0, so TRUE x FALSE = 0 while TRUE x TRUE = 1.
Lastly, I use MATCH to find out the position of the first 1 in the above result which is the 5th place/column, and then use INDEX to return the corresponding value from range NameRng.2019.class.1 which is mar_2019_class.1.
Here is a more universal formula which allows you enter it in the first cell C6 and drag it down to apply across board, if you have given names to the relevant cells and ranges in the same way as what I have demonstrated.
=IFERROR(INDEX(INDIRECT("NameRng."&B6&".class."&ClassNo),MATCH(1,(TRANSPOSE(ROW($1:$11))>=MATCH(Start_MthYrClass,INDIRECT("NameRng."&B6&".class."&ClassNo),0))*INDIRECT("Check."&B6&".class."&ClassNo),0)),"")
It is also an array formula so you MUST press Ctrl+Shift+Enter upon finishing the formula in the formula bar.
It is essentially the same formula as the first one but I have added IFERROR to return a blank cell if there is no match, and I used INDIRECT to refer to the named ranges dynamically based on the year and class number chosen.
Now, if I change the look up criteria to mar_2021_class.5, here is an updated result:
Let me know if you have any questions. Cheers :)
I want to find nearest value of a cell but don't know how.
In my excel sheet cell B1 has a value(LIST NAME) and cell B2 has other value which is to be searched with condition. If cell B1 has value GP_42(list name) then search the value of cell B2 withing list GP_42 (D4:D13) If cell B1 has value GP_42(list name) then se[![enter image description here][2]][2]arch the value of cell B2 withing list GP_42 (E4:E13). If value doesn't match then result should be the nearest matched value. Result should be display in the cell B3.
I'll assume you want the closest value. This means that you need the absolute (ABS function) of the difference between the value in GP_42 and your search value.
In B3 as an array formula¹,
=INDEX(GP_42, AGGREGATE(15, 6, ROW(GP_42)/(ABS(GP_42-B$2)=MIN(ABS(GP_42-B$2))), ROW(1:1))-ROW(GP_42)+1)
I have used ROW(1:1) to represent the number 1. This gives you the first encountered match. In my expanded examples, the third has two matches that meet the 'minimum difference' in B9 and B10. B10 is achieved by filling down. This advances ROW(1:1) to ROW(2:2) which represents 2 and gives you the second available match.
¹ Array formulas need to be finalized with Ctrl+Shift+Enter↵. If entered correctly, Excel with wrap the formula in braces (e.g. { and }). You do not type the braces in yourself. Once entered into the first cell correctly, they can be filled or copied down or right just like any other formula. Try and reduce your full-column references to ranges more closely representing the extents of your actual data. Array formulas chew up calculation cycles logarithmically so it is good practise to narrow the referenced ranges to a minimum. See Guidelines and examples of array formulas for more information.
I am using INDEX(MATCH) to look up a value in one column using criteria from two different cells in another sheet. Here is the formula I am trying to use:
=INDEX(Sheet1!P:P,MATCH(1,(Sheet1!A:A=Sheet2!C$1)*(Sheet1!B:B=Sheet2!$B2),0))
Sheet1 is the array and column P contains the values I am wanting the formula to return. Column A in Sheet1 contains the values for the first criteria and Column B in Sheet1 contains the values for the second criteria. The criteria are represented in C1 and B2 of Sheet2. This will change as the cell is copied. Can anyone see any errors in this formula? It is returning a "value is not available for the formula or function."
This will have to be entered as an array formula¹ so the full column references should be cut down to a minimum size or you will experience unnecessary calculation lag as hundreds of thousands of blank cells are processed.
With text in column A,
=index(Sheet1!$P$1:index(Sheet1!$P:$P, match("zzz", Sheet1!$A:$A)),
match(1, (Sheet1!$A$1:index(Sheet1!$A:$A, match("zzz", Sheet1!$A:$A))=Sheet2!C$1)*
(Sheet1!$B$1:index(Sheet1!$B:$B, match("zzz", Sheet1!$A:$A))=Sheet2!$B2), 0))
With numbers or dates in column A,
=index(Sheet1!$P$1:index(Sheet1!$P:$P, match(1e99, Sheet1!$A:$A)),
match(1, (Sheet1!$A$1:index(Sheet1!$A:$A, match(1e99, Sheet1!$A:$A))=Sheet2!C$1)*
(Sheet1!$B$1:index(Sheet1!$B:$B, match(1e99, Sheet1!$A:$A))=Sheet2!$B2), 0))
You did not have absolute reference anchors (e.g. $ ) in the original Sheet1 range references but the way you had them set up for the criteria from Sheet2 led me to believe that you required them for both row and column.
If you have column header labels in row 1, change A1, B1 and P1 to A2, B2 and P2.
¹ Array formulas need to be finalized with Ctrl+Shift+Enter↵. If entered correctly, Excel with wrap the formula in braces (e.g. { and }). You do not type the braces in yourself. Once entered into the first cell correctly, they can be filled or copied down or right just like any other formula. Try and reduce your full-column references to ranges more closely representing the extents of your actual data. Array formulas chew up calculation cycles logarithmically so it is good practise to narrow the referenced ranges to a minimum. See Guidelines and examples of array formulas for more information.
I want to reference the worksheet name and then transpose the totals in row 1 to a column in my summary worksheet.
I have found the following formula, which looks up a worksheet and takes the total, then I can paste this down to look up the row, essentially transposing row H1 to AG1 to column B on my summary worksheet.
=INDEX('201510'!$H$1:$AG$1,ROWS(B$1:B1))
Now I want to replace the direct ref to the worksheet tab to a lookup. So when I type the worksheet name in say row 2, it will give me the monthly totals.
This formula looks up the tab reference in B2 and displays the contents of H1. Where B2 has the worksheet name.
=INDIRECT("'"&$B$2&"'!$H1")
However when I copy this formula down the column, H1 does not change to H2. Furthermore, I need it to transpose vertically to I1.
How can I combine the two formulae?
Thanks,
Andy
You will need to combine the logic of an INDIRECT function with regular Excel referencing. Note that in your final formula, the "'!$H1" is text, meaning Excel doesn't try to compute it until it calculates the value of the cell. ie: it does not compute that what you are typing is a reference, just text.
So, assuming you continue to use the INDIRECT function, you will need to create the address of the final portion dynamically. There are many ways to do this. For example:
=INDIRECT("'"&$B$2&"'!H"&ROW()-1)
This version takes the string of the sheet name from B2, and then adds on the "'!H" as an additional string, and then takes the row as the current row number of the cell above the cell the formula is in. ie: if this formula is in D2, it will look up H1 on the other sheet. This method relies on your formula being in a consistent position within your sheet - if you insert a row above this one, it will change what ROW() calculates as, thus changing the formula.
Another method would be to reference H1 in a way that consistently points there, and also iterates into higher numbers as you drag down the formula. This method may be more useful for your purposes, as it also teaches another function:
=INDIRECT(ADDRESS(ROW(H1),COLUMN(H1),,1,$B$2))
Note that the ADDRESS function creates a string which shows the way a direct reference to a specific cell would. with the arguments I have above, it picks up the row number of H1 [iterating down, as there are no $ in front of the 1], the column number of H1 [iterating to the right, as there is no $ in front of the H], and the sheet name from $B$2.
I have a range B3:Bn with dates and a range C2:Y2 with another dates range. I am trying to find a date from a range B3:Bn in a range C2:Y2 and then starting from this cell to sum values. To do this i use:
=SUM(OFFSET(C3;0;MATCH(B3;$C$2:$Y$2;0)):Y3)
But instead of Y3 I would like to say: Sum values just starting from offset cell value till + 7 other columns.
Maybe someone can help with it?
Thanks!
In the table of the figure, cell B6 contains
=SUM(INDEX(A2:P2,1,B4):INDEX(A2:P2,1,B4+B5-1))
You may use an adapted formula to carry out your task.
It indirectly sets (with INDEX) the initial and final cells for carrying out the sum. I defined it as a starting cell (column 3 of range A2:P2) and a number of cells (4).
Points to consider:
You may need to use absolute referencing for some column/row references.
You may define your range to sum in slightly different ways.
You can use the INDIRECT function. It allows you dynamically create a cell range in a formula. So you could have one cell with a forumla that create your cell range as text e.g.
=B1&":"&B2 // in Cell C1, assuming B1 is "A1" and B2 is "A2" this would result in "A1:A2"
And then you can dynamically create a cell range from that using Indirect which you can then use function SUM on.
=SUM(INDIRECT(C1)) // would result the SUM(A1:A2) in our example