Using Microsoft 365 Excel.
In cell K2, I have:
=VLOOKUP(F2,METERS,2,FALSE)
In cell L2:
=VLOOKUP(G2,KNOTS,2,FALSE)
The result in L2 is what I expect.
No matter what I do to the equation or anywhere in the workbook, I keep getting #N/A in K2.
When I replace the named range in K2, METERS for KNOTS, the function evaluates properly.
Copying the named range works properly, so there's nothing wrong with the named range:
=METERS
returns the complete named range without errors.
Checking the value in F2 evaluates as TRUE, so the value is an exact match:
=(F2=MS!A210)
Oddly enough, if I change the function in K2:
=VLOOKUP(F2,METERS,2,TRUE)
then it sort of works, in that it gives me a value instead of #N/A, but doesn't give me exactly the result I need.
I tried moving the function from K2 to different cell and using a different cell for the lookup value; then no matter what I input, I get 0.
I know the syntax in K2 is correct. The named range is correct. Everything seems to be correct.
Yet no matter what, I get #N/A.
Here/screenshot(s) refer:
Given the info you have provided, the only reasons I can think of why this could occur are:
a) Conflicting named ranges with common names/different scopes
b) Inconsistency between the two named ranges you're using
These aren't mutually exclusive (a different scope could lead to an inconsistency). I'll demonstrate the following in this solution:
No issues arise when using two different names that refer to the exact same range / sheet / scope
How easily issues can arise due to duality of scope (e.g. worksheet vs. workbook) for common names, and how either of these can be referenced anywhere in the workbook
Finally, I'll comment on the 'true/false' indicator in the vlookup function you mentioned, and propose an alternative / improved feature avail. with Office 365.
Context
Conflicts RE: named ranges can arise in several ways - e.g. when multiple sheets contain named ranges that have common names, when copying a function that comprises a named range from one sheet to another, etc. It's possible to produce a conflict from one workbook to another in this fashion too.
When copying such a function from one sheet to another you should see the something like the following UI appear:
Sheet 1 - correct referencing
Comprises two named ranges (range_1, range_2 resp.) which both refer to the exact same range (with identical scopes). Vlookups operate perfectly fine and produce identical results:
Besides their name, range_1 and range_2 are otherwise identical in every way per the following in Name Manager:
Sheet 2 - conflict / error
Copy of Sheet 1, with range_1 amended to only include the 1st column - the same vlookup functions as Sheet 1 now produce an error for range_1:
Note: copying the functions from Sheet 1 have now produced the following in Name Manager:
However, I'm still able to reference range_1 from Sheet 1 per the following tooltip that appears when I start typing '=range_1' in any cell within Sheet 2:
Thus its possible to retrieve what appears to be the 'correct' range for range_1 in any cell in the workbook by referencing the original scope (workbook), despite the vlookup in Sheet 2 producing an error.
It this is not the case (and you do not have 'duality' in scopes for the same named range) then the only other reason I can think of is inconsistency RE: formulation. If they are truly identical in the ranges they reference, then I would suggest adopting a single name (KNOTS, given this appears to function correctly) to simplify the workbook/functions and improve auditability.
Vlookup parameter (0/1)
RE: vookup(range, lookup, True/False) -
True (i.e. '1') parameter will return an 'approximate' match (which distinguishes this function from alternatives such as index/match). However, xlookup is advisable / preferred over vlookup in any case given it also has this feature and can reference to the left or right of the lookup column (vlookup works strictly to the right). Although it is more complex with additional parameters/arguments to consider. See here for details.
Related
My current formula is: =XLOOKUP(R2&S3,X1:EA1&X2:EA2,X1:EA150) with the source data being in the same sheet (X1:EA150). However, the source data is not usually within the same sheet (I only copied it over to see if the formula works). How do I nest(?) another =xlookup within my current formula to find the source data in Sheet1. I don't really want to use helper cells as then I'll have 2 dynamic ranges unless it can be automated.
(my previous question)
Thanks
Screenshot(s) refer:
The issue doesn't concern ranges from what I can tell - it's the missing final parameter assoc. with xlookup (like match: exact match: 0 etc.).
Of course, this assumes that your lookup ranges (K1:N1, K2:N2) correspond with respective lookup values that you have combined as (H2 & I3).
=XLOOKUP(H2&I3,K1:N1&K2:N2,K2:N11,"not found",0)
It's a trivial matter to then cut the appropriate range (i.e. contiguous range, 1:1 correspondence with resp[. (sub/) function ranges etc)
But what about duplicate match results?
The above will only return the first instance of a match. If you're looking to return every instance where there is a match, then I far prefer the filter function for this job:
=FILTER(K2:N11,--ISNUMBER(MATCH(K1:N1,H2,0)*MATCH(K2:N2,I3,0)))
And now we have this:
(assumes Office 365 compatibility RE: Excel)... ta
I've been struggling with this longer than I care to admit, but I have a fairly simple OFFSET function call which works on one sheet, but if I copy it to a different sheet it gives a #VALUE error.
On a sheet named "Deliverable" I have this formula in a cell:
=OFFSET(Deliverable!$B$72,1,0,,3)
and it works fine.
If I go to any other sheet and use the same exact formula, or use it in the Name Manager, it gives a #VALUE error.
If I leave off the final parameter indicated the number of columns I want, it does work:
=OFFSET(Deliverable!$B$72,1,0)
but of course isn't giving me the range I need.
Any idea what's going on with this?
I'm using Excel 2016 on Windows 7.
-- Updated Info --
In a nutshell, my spreadsheet has two cells which I'm using as dropdown lists, where the 2nd cell's list feeds off the selection in the first. The data they are based on has this format:
OptionA A B C D
OptionB A B
OptionC D E F
So the first dropdown uses a simple Data Validation source pointing to the column with OptionA, OptionB, etc. Once that's chosen, the second dropdown list should contain the appropriate options for the one selected. So if OptionB is selected, then the 2nd dropdown list should show A and B.
When I initially wrote this, the data validation source was just a simple VLOOKUP entry, but the lists often had blanks since the number of options varies for each entry. Wanting to fix it up a bit, I ended up with this formula:
=OFFSET(Deliverable!B72,Deliverable!B87,0,1,COUNTA(OFFSET(Deliverable!B72,Deliverable!B87,0,1,5)))
There won't be any more than 5 options, and there are no empty cells in the middle of the data to filter out.
In one spreadsheet I have I used this as a named range definition, then specified the named range for the cells data validation source and it worked. In this other spreadsheet however, it gave me the error described earlier.
However, it looks like when I enter the statement directly into the data validation source field and not in the name manager, it works as expected.
Am I taking the totally wrong approach?
What is it that you want this formula to do? As written, it is returning a block of three horizontal cells. The #VALUE error is Excel's way of telling you "Hey, you're trying to return three cells, but I can't fit them all in the one cell that you are calling this formula from".
The reason you see a result in some places and not others is because of something called Implicit Intersection. Give it a spin on Google. But basically, it just returns whichever one of those three results corresponds to the column that the formula is entered into. If you copy that exact same formula to say row F you will see that it returns a #VALUE error there, because it doesn't know what cell it should return given the column you're calling it from doesn't match any of the cells it is returning. The fact that you don't know this indicates that the formula you're using doesn't in fact do what you think it does.
--UPDATE --
Okay, following your further clarificaiton it seems that you're talking about Cascading Dropdowns aka Dynamic Dropdowns. Lots of info on Google about how to set these up, but you may be interested in an approach I blogged about sometime back that not only provides this functionality, but also ensures that someone can't later on go and change the 'upstream' dropdown without first clearing the 'downstream' one should they want to make a change.
Note that those links talk about a slightly complicated method compared to others, but the method has it's advantages in that it also handles more levels than two, and your DV lists are easily maintained as they live in an Excel Table.
This sounds like an array equation. Try hitting Ctrl+Shift+Enter in the other sheets to validate it as an array equation.
Whenever you need to reference ranges instead of single cells, Excel needs to know that you are working with arrays.
I have a pricelist, with currently 5 different categories of products. Each product will have to have two different prices. Depedning of the product and the type of price, the calculation will be different. Therefor I've used INDEX/MATCH to find the formula needed, from a table I created.
Below a screendump, and I wanted to attach the Excel fil, but canøt seem to work out how.
Question: HOW do I then "run" the formula I fetched? -I've tried different suggestions on using EVALUATION, but it doesn't seem to cut it? Also I've tried "Indirect' on the whole formula, without success.
I would like to avoid any VBA for this case.
Can anybody provide some insight?
You could but if I understand properly, the only thing changing in the formulas is the "muliplier" number, then it's better to lookup that number instead of the whole formula. The other method (which would use Evaluate etc) is not be considered "good practice" for a number of reasons.
EDIT:
I didn't see the 2nd varying value (since I was on the SO mobile app) but it's still not an issue since it would a target column. You could be thinking of the opposite: sometimes lookups based on multiple criteria can get complicated, but this a matter of more data, as opposed to adding criteria for the lookup.
VLookup would have been the simplest method, like G2 could have been:
=VLOOKUP(E2, $J$4:$L$8, 2, False)
...to return the second column of range J4:L8 where the first column equals E2. (Then for the next required column, same formula except with 3 instead of 2.)
Since I wasn't sure more columns could be added one day, I allowed for that by, instead of specifying "Column 2 or 3" etc, it finds the column dynamically by name. (So the multiplier/factor used in G2 will change if you change the title in G1 to the name of a different column existing in the target data chart.
For the sake of neatness as well as potential of additional columns like G & H, I moved the lookup table to a separate sheet. It can stay out of the way since you won't need to see or change it very often. (If the same chart was going to be referenced by many workbooks, you could even move it to a separate workbook and point all formulas at that, since it's always best to have one copy of identical data instead of many in different workbooks.
Also to assist with potential future changes (and just to be tidier), instead of referring to the target table range addresses (like "J4:L8" etc) I named two ranges:
the table of multiplier/factor data can be referred to by it's address, or by myMultipliers
the titles of the same table is also called myMultiplierTitles (used to match to the titles of column G & H on the original sheet.
Formula
After those changes, the lookup formula in G2 is:
=INDIRECT(VLOOKUP($E2,myMultipliers,MATCH(G$1,myMultiplierTitles,0),FALSE)&ROW())*VLOOKUP($E2,myMultipliers,MATCH(G$1,myMultiplierTitles,0)+1,FALSE)
INDIRECT returns the value of a cell that you refer to by name (text/string) as opposed to directly (as a range). For example:
=INDIRECT("A1")
returns the same as
=A1
...but with INDIRECT we can get the name from elsewhere (a cell, function or formula). So if x="A1" then =INDIRECT(x) returns the same as the 2 above examples.
Your original plan of storing the entire formula in a table as text would have worked with the help of INDIRECT and/or EVALUATE but I think this way is considered better practice partly because it facilitates easier future expansion.
The formula is longer than it would have been, but that's mostly because it's dynamically reading the field names. And size doesn't matter. :-)
I am trying to return multiple values using multiple criteria...below is the code I have tried (but using the special brackets) but it keeps coming back as though I am trying to create a sum and have an error...
=IFERROR(INDEX(Sheet2!$C$4:$C$25,SMALL((IF(Sheet2!$D$4:$D$41=Sheet3!G2)*(Sheet2!$E$4:$E$67=Sheet3!$L$3),ROW(Sheet2!C4:C24)),ROW(1:1))),"")
Below is a code that returns one result, but there are multiple names for the two matching criteria.
=IFERROR(INDEX(Sheet2!$C$4:$E$43,MATCH(1,(Sheet2!$D$4:$D$26=Sheet3!$G$2)*(Sheet2!$E$4:$E$26=Sheet3!$L$3),0),1)," ")
essentially, I have a stakeholder analysis square - broken down into:
Keep Satisfied (Sheet 3: cell C2)
Manage closely (Sheet 3: cell G2)
Keep Informed (Sheet 3: cell C13)
Monitor (Sheet 3: cell GG13)
I am using a data validation in sheet 3: cell L11 (linked to Sheet 2), to create the second criteria (project).
What I would like to happen is for it to return the names into each of the stakeholder analysis headings. The problem is, if for example, I have 3 names in 'manage closely' for one project - I cannot get it to return all three names...only the one.
This has been driving me insane
There are several errors in the first formula you give, i.e.:
=IFERROR(INDEX(Sheet2!$C$4:$C$25,SMALL((IF(Sheet2!$D$4:$D$41=Sheet3!G2)*(Sheet2!$E$4:$E$67=Sheet3!$L$3),ROW(Sheet2!C4:C24)),ROW(1:1))),"")
For one, the ranges passed should be of an identical size; in your case, all four are different, viz:
Sheet2!$C$4:$C$25: 22 rows
Sheet2!$D$4:$D$41: 38 rows
Sheet2!$E$4:$E$67: 64 rows
Sheet2!C4:C24: 21 rows
I can only guess at what should be the correct range, so let's assume the largest for the sake of argument.
Secondly, I assume that the reference:
Sheet3!G2
should actually be absolute, i.e.
Sheet3!$G$2
so as to be invariable as this formula is copied down?
I will also make a few other corrections, to the value_if_true clause being used for the IF statement (the one you are currently using is not correct), and also to SMALL's k parameter (ROWS is more robust than ROW here: https://excelxor.com/2014/08/25/row-vs-rows-for-consecutive-integer-generation/).
All in all:
=IFERROR(INDEX(Sheet2!$C:$C,SMALL(IF(Sheet2!$D$4:$D$67=Sheet3!$G$2,IF(Sheet2!$E$4:$E$67=Sheet3!$L$3,ROW(Sheet2!$C$4:$C$67))),ROWS($1:1))),"")
and copied down.
You might also want to take note that, if the ranges being questioned are in fact quite large, the use of IFERROR can here be very inefficient:
https://superuser.com/questions/812727/look-up-a-value-in-a-list-and-return-all-multiple-corresponding-values/812848
Regards
Many "advanced" (aka: VBA) excel tutorials on the web or even excel's vba help encurage us to use the
Range("B2:B10")
method (to be precise: object) for selecting cells or getting values. In the same place they often add it's totally ok to use predefined names as well:
Range("valuesabove")
On the other hand I fell in love with the incredible power of relatively defined cell names. They make it so much easier to write and handle big composite formulas, and basically to refer to nearly anything.
However, relative names don't work in the Range("valuesabove") method the way we are used to it.
Usually (when used on the worksheet) relative names are relative to the currently selected cell or to the cell in which they are used.
In VBA's Range() object this is not true. Range is relative to a WorkSheet object, by default to the ActiveSheet. But ActiveSheet is represenetd by its leftupper cell, A1. And this is what Range turns out to be relative to. And this is why absolute names ($C$23) do work with it, and relative ones ("one column to the left, two rows up") don't.
So my question is:
How can I harness the power of relative names in VBA then?
EDIT:
Realising that my question was rather unclear (thx's go to you guys commenting tirelessly) let me try to put it in a specific form and clarify terms:
IMHO on an excel worksheet it is very comfortable to use names in order to refer to cells or define calculated values by functions based on cell values.
In excel a reference to a cell can be either relative, absolute, or mixed. This is true also when creating names. Thus we can speak about absolute, relative or mixed names (in terms of referring of course).
Here an absolute name is used a couple times (created using excel's Trace Dependents function):
Name "name" = $D$2
A relative name is used a couple times here:
Name "upright24" while, e.g. cell A7 is selected = C3 (without $ signs!). But this changes constantly according to the selected cell or region. You can check it in the name manager! (Ctrl+F3)
And this is what we can consider as a mixed name:
Name "rel_serialnumber" while, e.g. cell C6 is selected = $B6. The row of which (6) changes constantly according to the selected cell or region.
The creation of a relative or a mixed name is explicitly based on the active cell at the moment of creating the name. The creation of an absolute name naturally doesn't rely on the cursor position.
Note, that
absolute names mean a dinamic offset from the referenced cell, which is one and only
relative names mean a static offset from the referenced cell, which thus changes always corresponding to the place where the name is used
mixed names mean a mixed (or half-dynamic) offset from the referenced cell, the row or column of which thus changes always corresponding to the place where the name is used while the other remains always the same (the offset in one or the other direction remains zero).
Okay, now here is the thing. I have a database-like excel sheet where I handle the rows like records and the columns as fields for properties. The user uses this thing as follows: he "selects a record" by placing the cursor in any cell of the row of the desired record. Then he presses a big command button which starts my VBA macro. This intends to open a prepared skeleton file and fill some specific cells in it (which are btw defined by absolute names) with some values (which are defined by mixed names) from the selected record.
Since Range("name") is considered ok to use in VBA (see above) I thought Range("relativename") or Range("mixedname") will work just as fine while automatically relying on the active cell.
I couldn't be worse.
Only Range("absolutename") works in the way one would expect! Explanation see above.
So I'm after a function / method / object that is possibly as comfortable to use with a "relativename" or a "mixedname" as Range("absolutename") is.
It appears you are looking for Range.Offset() http://msdn.microsoft.com/en-us/library/office/ff840060%28v=office.15%29.aspx
However you could do it as:
'Your example Range(Col_B_in_current_row) as
Range("B" & ActiveCell.Row).Select
'Your example Range("B2:B10") -> Range("valuesabove") as
Range("B2:B10").Offset(-1, 0).Select
Just seems like a relatively simple syntax already exists for this.
I think I've found a proper and compact solution. It's
Names("mixedname").RefersToRange
Not as short as Range("mixedname") would be but it is really providing the expected values.
UPDATE:
This solution is mostly unuseful if you want to copy relative-named cell values in a source workbook to relative-named cells in a dest workbook with a single codeline. This is because Names() relies on the actual position of the cursor which is depending on which workbook is currently the active one and in most cases this won't be ok for the other.
In this case the non-fixed part of the name has to be stored:
sourcerow = ActiveCell.Row
[...]
'opening a wbk, this also makes it the active one
[...]
Names("dest").RefersToRange = mysheet.Cells(sourcerow, mybook.Names("src").RefersToRange.Column)
To reference a Range relative to another Range you can use this syntax:
myRange.Range("namedRange")
Note: This only works if both the Row offset AND the Column offsets are positive. For example if the "Refers to" formula for the named range is "=Offset(A1,r,c)", then the above syntax will throw an error if Either r Or c is negative. But, it will work if both are positive.
The asymmetry is unfortunate but business as usual for VBA...
To Reference the third column in the row of the current ActiveCell:
ActiveCell.EntireRow.Range("C1")
To reference a cell offset by (for example) 1 row and 3 columns relative to the ActiveCell:
ActiveCell.Range("C2")
Obviously, you can use the same syntax with the Selection Object or any other Range value in VBA.
Private Sub Worksheet_Change(ByVal Target as Range)
If Not Intersect(Target.Address,ThisWorkbook.Sheets('sheetname).Range('RangeName)) Is Nothing Then _
'Do whatever you want down here.
ThisWorbook.Sheets('sheetname).Range('RangeName).Offset(0,Target.Row)
End If
End Sub
This should send you on the right path to what you want (which is super unclear). Use the worksheet change event to bring in user worksheet selections and changes into VBA modules. Put it into the relevant sheet.
I had the same problem, but I did get it to work - sort of. I don't know what is different about the simple example below, but it works. At first I thought selection mattered, but no - it works without changing the active cell.
(I still can't get it to work in my main spreadsheet.)
Named range: "TestName" = Sheet1!$H1
Values in H1:H10 = 1,2,3,4,5,6,7,8,9,10
Sub Test()
Dim x As Integer
For x = 0 To 10
Range("A1").Offset(x, 0).Value = Range("A1").Offset(x, 0).Range("Testname").Value
Next x
End Sub
Result: A1:A10 = 1,2,3,4,5,6,7,8,9,10