I have several cells that calculate totals from a single cell from multiple worksheets, in this case "Y3" from each of the sheets that are in Week, where n is an integer from 1 through 10:
=SUMPRODUCT(COUNTIF(INDIRECT("'Week"&{1,2,3,4,5,6,7,8,9,10}&"'!Y3"),"W"))
I would like to have a cell in my workbook that contains, A1:
1,2,3,4,5,6,7,9,10
So that way I can update only one cell when I add a worksheet to be counted. I've tried a few things and nothing seems to work.
Your formula : =SUMPRODUCT(COUNTIF(INDIRECT("'Week"&{1,2,3,4,5,6,7,8,9,10}&"'!Y3"),"W"))
This formula only work if you have 10 sheets with named Week1,Week2,Week3….Week10
But if you have less than 10 sheets e.g. Week1,Week2,Week3….Week9, your formula will fail and return "#REF!" error
The formula workaround is wrapping with a IFERROR() and become :
=SUMPRODUCT(IFERROR(COUNTIF(INDIRECT("'Week"&{1,2,3,4,5,6,7,8,9,10}&"'!Y3"),"W"),0))
However, if you wanted the formula acting dynamic and in A1 enter : 1,2,3,4,5,6,7,9,10
But 1,2,3,4,5,6,7,9,10 is a text string, you need converted it to an array. Using FILTERXML() can do the work of which available since Excel 2013
This is an array formula you need to confirm by pressing CTRL+SHIFT+ENTER instead of just ENTER:
=SUM(IFERROR(COUNTIF(INDIRECT("'Week"&FILTERXML("<a><b>"&SUBSTITUTE(A1,",","</b><b>")&"</b></a>","//b")&"'!Y3"),"W"),0))
EDIT 1 :
And,
if you haven't Excel 2013, you could use this longer array (CSE) formula instead
=SUM(IFERROR(COUNTIF(INDIRECT("'Week"&TRIM(MID(SUBSTITUTE(","&A1,",",REPT(" ",99)),ROW(INDIRECT("1:"&LEN(A1)-LEN(SUBSTITUTE(A1,",",))+1))*99,99))&"'!Y3"),"W"),0))
After that,
you can make adjustment to A1 number without changing formula contents
AFAIK you can't do that with a formula if you place the sheet list in a single cell I stand corrected: see bosco_yip's answer! (although you could with a UDF).
But, if you place your sheet list in a column, you can do this (using OFFSET, the list is dynamic, but must be the only data in that column. There are alternatives if that doesn't suit you):
=SUMPRODUCT(COUNTIF(INDIRECT("'Week"&TRANSPOSE(OFFSET(A1,1,0,COUNTA(A:A)-1,1))&"'!Y3"),"W"))
Applying the FILTERXML method, to create a non-array formula
=SUMPRODUCT(COUNTIF(INDIRECT("'Week"&FILTERXML("<a><b>"&SUBSTITUTE(A2,",","</b><b>")&"</b></a>","//b")&"'!Y3"),"W"))
Related
I use formula as below to get what I need:
=$G467-INDIRECT(ADDRESS(LOOKUP(2,1/($J$1:$J466=$J467),ROW($J$1:$J466)),7))
I try to use formula as below for dynamic range
=$G467-INDIRECT(ADDRESS(LOOKUP(2,1/(INDIRECT("$J$1:$J"&(ROW()-1),1)=$J467),ROW(INDIRECT("$J$1:$J"&(ROW()-1),1))),7))
But I got N/A, does anyone help me?
Both of your formulae are valid, but inefficient (due to the use of the volatile INDIRECT() function).
A more efficient version of your first formula would be
=$G467-INDEX($G$1:$G$466,MAX(($J$1:$J466=$J467)*ROW($J$1:$J466)))
(this will have to be entered as an array formula if you aren't using Excel 2021/Microsoft 365)
and a more efficient (albeit longer) version of your second formula would be
=$G467-INDEX($G$1:INDEX($G1:$G466,ROW()-1),MAX(($J$1:INDEX($J1:$J466,ROW()-1)=$J$467)*ROW($J$1:INDEX($J1:$J466,ROW()-1))))
(if you had to enter the first formula as an array formula then you will also have to enter this one in the same way)
That your second formula returned #N/A is either because of your data, or because of the cell where you entered the formula: if you enter your second formula in a cell on row 467 then it should produce the same result as your first formula.
This phrase is embedded in many formulas on my sheet:
OFFSET(Table1[ReportDate],0,$B$1)
It returns a reference to a column in Table1.
To make those many formulas shorter, I'd like to extract this OFFSET formula to a separate cell for the others to refer to.
The OFFSET returns a reference. Putting OFFSET(…) in a cell just returns #VALUE, and so does INDIRECT(OFFSET(…)).
EDIT: The "many formulas" are SUMIFS, and the OFFSET chooses the column to be summed:
=SUMIFS(OFFSET(Table1[ReportDate],0,$B$1),Table1[ColumnB],$H10,Table1[Report Date],"<="&rYesterday)
If I understand you correctly, you want to replace the original OFFSET formula with something simpler to be used in other formulas.
You can do so by giving a name to this OFFSET formula.
In the above mock-up example, I have given a name SUM_Rng for the OFFSET formula and used it in my second formula, which is the same as your original SUMIFS formula.
You can press Ctrl+F3 to bring out the Name Manager in Excel and add or modify names which can represent a reference of a cell or a range either hard-coded or returned by a formula. I noticed that you already used a name rYesterday in your SUMIFS formula so there should be no problem for you to add this formula to the name manager.
Cheers :)
It's probably a simple problem, but I did not even know the keywords to google it ;/. Let's say I have this data :
Now I also have this litle formula:
If I know drag the C cell to the right, Excel will attempt the following caluclation:
=2+B1
What I want him to do is to attempt this calculation
=2+A2
Of course the easiest solution would be to store my initial data in one row instead of 1 column, but it is really inconvenient for me. Thanks for any help
You can use the indirect() method to reference a cell by it's "String identifier", i.e. "A3". When filling out to the right, use CONCATENATE() and COLUMN() to create your String identifiers {A1,A2,A3,A4,A5...} as required:
=2+INDIRECT(CONCATENATE("A";COLUMN()-2))
This will result in the following:
Side-Node: If you want this for some x/y-Grid-Generation, you can also be lazy,
and just insert =COLUMN() for every cell from "A1 - Z1" and ROW() for every cell from "A2 - A24".
(Or even avoid these at all and directly perform your actual calculation by using column() and row() as replacement for your x/y.
You may try using a combination of the INDIRECT and COLUMN functions:
=2+INDIRECT("A"&(COLUMN()-2))
You would paste the above formula into cell C1, and then drag across to the right however many columns/rows you wanted to cover.
This would result in the following:
This works because COLUMN()-2 returns 1 for the C column, 2 for the D column, and so on. Therefore, the formula will be calling INDIRECT on A1, A2, etc. for column C, D, and so on.
In general, if you want relative references to move down as cells are dragged to the right, you can use this:
Instead of:
= 2+A1
Do:
= 2+INDEX($A:$A,COLUMN()+<offset>)
Where <offset> is whatever offset you need. The offset will change depending on which column the starting formula is located in.
INDEX should be preferred over INDIRECT because INDIRECT is volatile (must recalculate after any change to the workbook) but INDEX is not (only recalculated when one of the inputs the formula, in this case $A:$A, changes).
In an excel workbook, I'm referencing a defined name from another tab (to get dependent data validation). Accessing the defined name directly works, but accessing it through INDIRECT doesn't.
=INDEX(DefinedName,1) returns the first value of the range
=INDEX(INDIRECT("DefinedName"),1) returns #REF!
I have also tried
=INDEX(INDIRECT("SheetName!DefinedName"),1), but it also returns #REF!
Sample file can be downloaded here.
Thomas,
I hadn't come accross this before.
It appeas that INDIRECT and dynamic range names are incompatible. There is a useful reference here from Dicks blog
Not quite an answer, but it may have something to do with the fact that your named range is returning an array instead of a cell reference (in this case {"VALL";"GENADMIN";"HOSP";"CELLAR"}).
You can replicate the error by removing the named range and replacing it with its actual formula, and then F9'ing the formula:
=INDIRECT(OFFSET(Defaults!$C$1,1,0,COUNTA(Defaults!$C:$C)-1))
=INDIRECT({"VALL";"GENADMIN";"HOSP";"CELLAR"})
Since Excel is expecting some sort of reference to a sheet range, it is failing here since it can't resolve the array to anything specific (pressing F9 again yields ={#REF!;#REF!;#REF!;#REF!}).
The INDEX formula works because it can handle the array reference:
=INDEX(OFFSET(Defaults!$C$1,1,0,COUNTA(Defaults!$C:$C)-1),1)
=INDEX({"VALL";"GENADMIN";"HOSP";"CELLAR"},1)
={"VALL"}
Not an expert, but that's my best crack at it.
This absolutely will work. Maybe they were incompatible in 2012, but they certainly work in 2018. I imagine it would have also worked in 2012 if used correctly.
The INDIRECT function attempts to turn TEXT into a range reference. That TEXT must be a valid reference.
A named range is already a Range Reference. There is no need to get a reference from a reference. This is why the OP example works without using INDIRECT.
A more likely implementation would be if you had the value "DefinedName" from the OP, or any named range in a cell. Then point INDIRECT to that cell where it find plain ol' text. Then it turns that text into a range reference.
You can even use formulas in the INDIRECT to modify the reference. A common approach might be to have a Sheet name in a cell and then use INDIRECT to pull data from various sheets. This is primarily useful when you want to copy and paste formulas and have the sheet (or cell) reference dynamically adjust to a new target.
Setup
Start with a blank workbook which should contain three blank worksheets, (Sheet1, Sheet2, and Sheet3) If not, get to that point. Then enter the following basics:
Sheet 1
Cell A1, enter "Range Reference"
Cell A2, enter "SUM from Sheet"
Cell B1 enter "Sheet2!A1:A4" (Note there is no "=" This text is a range reference.)
Cell C1, enter "THIRD_SHEET" (This text is equivalent to a named range we'll create in a second.)
Then in Sheet2,
Cell A1, enter 1
Cell A2, enter 2
Cell A3, enter 3
Cell A4, enter 4
In Sheet3
Cells A1-A4 enter 100 through 400 respectively.
Then create a named range called "THIRD_SHEET" which refers to cells A1-A4 on Sheet3.
Try
In Sheet1:
Cell B2, enter the formula:
"=SUM(INDIRECT(B1))"
Copy that formula to Cell C2.
Results:
The INDIRECT uses the text in the column headings to point to a valid range reference. This is just illustration. You wouldn't likely use a mixture of named ranges and text ranges, and its not very clean to write out, "Sheet1!A1:A4" but you can use any of the standard formula to arrive at a textual reference.
Try
Change the formula in B2:
"=SUM(INDIRECT("Sheet"&COLUMN()))&"!A1:A4"))"
Now copy that to cell C2.
Results
Well, are the same. The SUM from cells A1:A4 is being returned from Sheets 2 and 3 respectively. This time, however, the column headers are not being used, and the range reference is being assembled in the INDIRECT call itself using the string join "&" operator and the COLUMN number.
Named ranges can be used in the same way. What's important to understand is that anything inside the INDIRECT parenthesis needs to first be resolved to a vaild TEXT range reference.
I hope that helps!
How does one cell obtain the formula of another cell as text without using VBA? I can see this question has already been asked many times and the answer is always to write a custom function in VBA.
However, I found a post made in 2006 which claimed to have found the non-VBA solution but the link provided in that post is already broken.
=FormulaText(Reference) will do the trick Documentation
There is nice way of doing this without VBA. It uses XL4 macros (these are macros, but it is not VBA, as asked).
With reference to the figure 1, cells A2:A4 contain usual formulas.
Going to Formulas -> Define Name, I defined two named ranges (see fig. 2), with the information shown in cells A6:B8.
Enter in cell B2 =FormulaAsText. This will retrieve the formula in cell A2 as text.
Explanation:
The named range FormulaAsText uses =GET.CELL(info_type,reference). In this case, ìnfo_type = 6 retrieves the formula, and reference = OFFSET(INDIRECT("RC",FALSE),0,-1) uses the cell with 0 rows and -1 columns offset from the one the formula is used in.
Copy B2 and paste into B3:B4. This will show formulas in A3:A4. Cell A4 shows that the worksheet function CELL only retrieves values, not formulas (as opposed to GET.CELL).
Since FormulaAsText gets the formula from a cell at fixed offset (0,-1) from the current, I defined another range FormulaAsText2, which uses an offset (rows,cols) read from the worksheet itself. Cells D2:D4 contain =FormulaAsText2. Thus, cell D2 shows the contents of cell B3 (=OffSET(D2,1,-2)), which is FormulaAsText. cells D3:D4 show the contents of themselves. This adds some flexibility. YMMV.
PS1: The essence was taken from
http://www.mrexcel.com/forum/excel-questions/20611-info-only-get-cell-arguments.html
PS2: Tim Williams mentioned in a comment "the old XLM GET.FORMULA()". This answer is possibly related (not the same, since this one uses GET.CELL()).
PS3: A simple VBA solution is given, e.g., in
http://dmcritchie.mvps.org/excel/formula.htm
EDIT: Complementing this nice answer, the worksheet function FormulaText is available for Excel 2013 and later.
This suggestion may be helpful for those who after retrieving a block of formulas and transporting them to a new spreadsheet want to put them to work again. Excels FORMULATEXT function is great for picking up formulas but it leaves them as unusable text strings. If you want to get them back as fully functioning formulas you have to edit each one individually to remove the string character, but here is a shortcut for larger blocks.
Get to the position where you have the required formulas as text (in other words after using FORMULATEXT - you have done a copy and (value only) paste). The next step involves highlighting all the cells you want to convert and then navigating to the [Text-To-Columns] menu option ({Data} bar on Excel 2016). You can select 'Delimited' but on the next screen just make sure you de-select any marks that do appear in your formulas. Then 'Finish'. Excel should automatically analyse the cells as containing formulas and you should now have them working again.
There is a way to do this. In my example I had a table that showed a date. The date comes from Sheet!G91. In my table I also had a column that showed the sheet name. I added two more columns to my table. The first column had column(Sheet!g91), which returns the number 7, because G is the seventh letter in the alphabet. I then converted the number to a letter (G) using another table in my workbook. In the second column that I added, I made a formula row(Sheet!G91), which returns the number 91. Note: Row and Column may appear as volatile formulas, which recalculate with every calculation of the workbook.
I wanted another column to show the formula contents of the date cell mentioned at the beginning of this post. I included the following string function (you can also use CONCATENATE).
"=" & AJ9 & "!" & AM9 & AN9
The items separated by ampersands get strung together (that is, concatenated). AJ9 in my example contains the sheet name, AM9 contains the column letter, and AN9 contains the row number.
I now have a column that dynamically updates its contents to reflect the sheet name and cell reference. The results in my workbook cell are
=Sheet!G91.
You can't. This is most likely a design choice to eliminate an average Excel user from accidentally getting something they did not want.
What you are reading is correct - writing a UDF is the solution you want.