My understanding is that you can define a range using index. example I can set a defined name of MyList to
=index(A:A,3,1):index(A:A,5,1)
This would be the equivalent of saying A3:A5. I can then turn around and use index(MyList,1,1) and I would see the contents of A3. All this works for me.
So I was trying to define a range of sheet names. I used defined name sheetnames as:
=TRANSPOSE(GET.WORKBOOK(1,Structural!$J$3)&T(NOW()))
(I used transpose to get the list vertical)
when I use:
=INDEX(Sheetnames,3,1)
=INDEX(Sheetnames,6,1)
I get the name of my 3rd or 6th sheet in my workbook respectively. So that part is working. However when I try to define a range like I did for MyList using the following I get #value
=INDEX(INDEX(Sheetnames,3,1):INDEX(Sheetnames,6,1),1,1)
QUESTION:
Why is it not working?
As a test to get first sheetname I have also tried:
=OFFSET(Sheetnames,1,1,1,1)
This also gave the same error.
What I am ultimately trying to do is generate a pull down list through data validation of all sheet names except the sheets named "Index" and "Master".
As per Excel's help file on INDEX...
Reference form
Description
Returns the reference of the cell at the intersection of a particular
row and column. If the reference is made up of nonadjacent selections,
you can pick the selection to look in.
Syntax
INDEX(reference, row_num, [column_num], [area_num])
The INDEX function syntax has the following arguments.
Reference Required. A reference to one or more cell ranges
etc...
Therefore, in order to return a reference, you would need to reference a range of cells. SheetNames, however, doesn't refer to a range of cells. It refers to GET.WORKBOOK, which returns an array of values. In this case, it returns an array of sheet names.
So with the following formula...
=INDEX(INDEX(Sheetnames,3,1):INDEX(Sheetnames,6,1),1,1)
...it gets evaluated as follows (assuming the workbook is called Book1.xlsx and you have Sheet1, Sheet2, Sheet3, etc)...
--> some preliminary evaluations <---
=INDEX("[Book1.xlsx]Sheet3":"[Book1.xlsx]Sheet6",1,1)
=INDEX(#VALUE!,1,1)
=#VALUE!
You can evaluate the formula for yourself by selecting the cell containing the formula, and stepping through it using the Evaluate Formula button on the Ribbon (Formulas tab > Formula Auditing group).
You can also confirm that INDEX doesn't return a reference in this case by using the ISREF function. The following formula should return FALSE...
=ISREF(INDEX(Sheetnames,3,1))
Hope this helps!
Related
I want to sum the total value preceding a lookup value in a range with a defined starting point. can anyone clue me into why this formula wont work?
=SUM(E9:CELL("address",INDEX(E9:BN9,MATCH("130LSR",E9:BN9,0))))
The result from just the cell function works:
=CELL("address",INDEX(E9:BN9,MATCH("130LSR",E9:BN9,0)))
This returns $F$9 in my sheet which is correct. It also has the workbook and sheet references prior, is that my problem? is there a way to remove the book and sheet references? The sum function obviously works if I provide the address, but why can't i define the end of my range with the cell(address) formula?
Similarly to this thread I have found Click here...
I am trying to create various formulae looking across tabs with the tab names kept in cells. My hyperlink function has been successful as:
=HYPERLINK("#'"&B2&"'!A1","Click Here")
Where B2 represents a 2-3 character tab name of a person's initials (e.g. AA in this example).
However if I try this method with other formulae I am returning a #VALUE! error. Can anyone help me with making this nested Index/Match function work dynamically from cell B1 rather than being fixed to the tab name "AA"?
=IF(OR(INDEX(AA!B:AH,MATCH(TODAY()-WEEKDAY(TODAY(),11)+1,AA!B:B,0),2)="",INDEX(AA!B:AH,MATCH(TODAY()-WEEKDAY(TODAY(),11)+1,AA!B:B,0),10)="",INDEX(AA!B:AH,MATCH(TODAY()-WEEKDAY(TODAY(),11)+1,AA!B:B,0),14)="",INDEX(AA!B:AH,MATCH(TODAY()-WEEKDAY(TODAY(),11)+1,AA!B:B,0),22)=""),"No","Yes")
Thanks in advance?
Dan
The hyperlink function accepts a constructed string to use as the link and interprets it as a range address just as it would a true url. A formula cannot accept a constructed string address as a worksheet range reference but the INDIRECT function converts constructed strings to a usable worksheet range reference.
INDEX(AA!B:AH,MATCH(TODAY()-WEEKDAY(TODAY(),11)+1,AA!B:B,0),2)
... becomes,
INDEX(indirect(text(B2, "'#'!\B\:\H")), MATCH(TODAY()-WEEKDAY(TODAY(), 11)+1, indirect(text(B2, "'#'!\B\:\B")), 0), 2)
With AA in B2, text(B2, "'#'!\B\:\H") becomes 'AA'!B:H. I find it easier to take care of the wrapping ' marks with a format mask.
I may going up the wrong tree with this.
I have the following formula, that will replace the * with the range of sheets in the workbook, and SUM the values in cell B2 on each of the sheets:
=(SUM('*'!B2)/J2)/100
This works fine, however the formula doesn't retain the '*', it replaces it with the actual range, eg:
=(SUM('Period 1:Period 4'!B2)/J2)/100
So, is it possible to either:
Retain the '*' so that the formula doesn't update, and therefore remains dynamic should I add a new tab.
Add a reference into the reference. The first sheet will always be 'Period 1', however the end sheet will change from month to month, and will be 'Period x', where x is the value in cell J2. Is it possible to reference J2 within =(SUM('Period 1:Period 5'!B2)/J2)/100? =(SUM('Period 1:Period [J2]'!B2)/J2)/100 or something similar?
The only way I know to do this is to create a 'sheet sandwich' with a 'Start' and 'End' sheet then the range is =SUM('Start:End'!B2). New sheets obviously have to be inserted between these to be included.
Note:not my solution, credit belongs to SUM across multiple sheets with variable sheet name question.
I'm using two cells with Data Validation - the first cell (E9) simply creates a drop down menu based on the range A2:A6, and the second cell (E10) validation uses the source INDIRECT(E9), which will always refer to one of five different named ranges.
When I have the named ranges fixed, (i.e A2:A250), the second drop down works, but I really need the ranges to be dynamic, so far I've been creating named ranges with the following "source" formula:
=OFFSET(LookupLists!$B$2,0,0,COUNTA(LookupLists!$B:$B),1)
With the other ranges being the exact same only in columns C-F.
When I write out this formula it highlights the correct area on the screen, but the drop down button in cell E10 is completely unresponsive, when the drop down list should show the exact area that's being highlighted.
As a note, the lists themselves are created using an array formula and some VBA code to create a sorted unique list based on another part of the spreadsheet, so I've been unable to use tables to create the ranges as some other websites have suggested.
INDIRECT doesn't work with dynamic ranges. Credit to these guys for the solution:
http://chandoo.org/forum/threads/passing-a-named-range-to-a-formula-with-indirect.5854/#post-32423
First, insert a module into you sheet and paste in the UDF:
Option Explicit
Function RetrieveRangeForName(psRange As String) As String
RetrieveRangeForName = Range(psRange).Address
End Function
Then you will need a helper cell, since I don't think UDFs work in the Data Validation dialog. In E11, enter =RetrieveRangeForName(E9).
Then in the Data Validation, set to List, you can enter: =INDIRECT(E11)
The reason it doesn't work as discussed here is that INDIRECT expects a string that it can evaluate to give a reference. However your named range is already a reference. Logically, the only way to use it in INDIRECT is to convert it into a string first which you can do with a UDF:-
Function GetAddress(Name As String) As String
Dim rng As Range, addr As String
Set rng = Worksheets("Sheet1").Range(Name)
addr = rng.Address
GetAddress = addr
End Function
Then use this to define a range called NewRange:-
=INDIRECT(GetAddress(Sheet1!$E$9))
Finally this can be used in the validation for E10 (Named Range ListB is defined as in the question, ListA etc. correspondingly for columns A to E).
The data in column A looks like this.
RowHeaderThatIsText
RowHeaderThatIsNumber
empty
empty
empty
empty
empty
14.00
-3.00
-4.00
The project goal is to to calculate summary statistics for the series of numbers and update the summary each month.
My goal is to allow a new number to be added to the series and have the summary update automatically.
Here's what I've done so far.
Define a range named LastCell with the formula
=INDEX($A:$A, MAX(($A:$A <> "") * (ROW($A:$A))))
This returns the last non-empty cell in the column. The data to summarize is always the last block of numbers.
Define a named range called HeaderOffset with the formula
=3
Used in the step 3.
Define a range named FirstCell with the formula
=OFFSET(LastCell, HeaderOffset - COUNTA($A:$A), 0)
This returns the first cell of the last block of numbers if, as is the case with the data I'll be summarizing, the cells between the first and last blocks are empty.
Define a range named DataBlock with the formula
=FirstCell:LastCell
So far so good. This allows one to enter =SUM(DataBlock) into any cell and get the expected result of 7.00. And, if I add another value, say 3.00, to the list the SUM result will update to 10.
The part I don't like is HeaderOffset. If another row is added to the header, HeaderOffset needs to be updated from =3 to =4. What if I forget to update HeaderOffset? This lead me to the problem I can't currently solve...
Is there an Excel formula that, given the ending cell, returns the starting cell of a block of data? Basically I'm looking for a FirstCell formula that removes the need for HeaderOffset.
As a bonus I was trying to do this whole thing without using volatile Excel functions. I failed by using OFFSET. Solving this is great. Solving it without volatile functions is ideal.
Is FirstCell always the first number? If so try this to define FirstCell
=INDEX($A:$A,MATCH(TRUE,ISNUMBER($A:$A),0))
That's an "array formula" if entered on the worksheet but doesn't need any special treatment if used in the "refers to:" box to define a named range.
Note: if your final aim is the sum of the numbers then could you just use =SUM(A:A) [I assume that's oversimplifying the issue?]
Revised given comment below:
Try this for LastCell
=INDEX($A:$A,MATCH(9.99E+307,$A:$A))
and this one for FirstCell
=INDEX($A:$A,MATCH(2,1/($A$1:LastCell=""))+1)
assumes LastCell is numeric (although that can be changed if required)