Excel - Sheet as a function - excel

I have two excel sheets. The first contains a formula for calculation with one input cell (A1), and one output cell (B1). The formula for B1 could be B1 = A1 * 3 (example).
The second sheet contains various values in column A: A1 = 4; A2 = 9; A3 = 5 ... In corresponding column B of this sheet I'd like to get the result of B1 (first sheet) = A1 (second sheet) * 3 for each A (second sheet) input value.
Basically I'd like to treat the first sheet as a function, where A1 is the argument and B1 the result that is passed back to the second sheet's B column.
Sheet 2
A1 4 B1 12 (result from sheet 1)
A2 9 B2 27 (result from sheet 1)
...
Is it possible without macros?

This is built into Excel. In version 2003, use the Data, Table menu.
You can find many examples on the net. Here is one.
You can create such tables with either 1 or 2 entries (parameters).

I don't think so .....
If in B1 Sheet1 you have
3*A1
If you try this in Sheet2 B1
`=SUBSTITUTE(Sheet1!$B$1,"A1",A1)`
it will give
3*4, and Sheet2 B2 will be
3*9etc
But I don't see how you could coerce this to a numberic calculation with formulae without possibly some heavy duty formula string parsing to separate numbers from operators (which is unlikley to flex as desired if you change the entry in B1 Sheet 1)
[Update 2: but fwiw I have done it with a named range]
I used this range name
RngTest
=EVALUATE(3*INDIRECT("rc[-1]",FALSE))
This is a global range name so it will work on any sheet, more powerful than my prior OFFSET effort. It multiplies the cell to the immediate left by 3
so entering =RngTest in B1:B3 (and then in this new example C1:C3 as well)
gives the output you want

I think you want to use this in your sheet two column.
Sheet1!B1 * Sheet2!A1

Entirely without VBA: expect lots of pain, I won't go there. But...
To substantially reduce the amount of pain, you could actually use this one tiny VBA user-defined function (not technically a "macro"), basically just a wrapper to make VBA's Evaluate function available in worksheet formulas:
Function eval(myFormula As String)
eval = Application.Evaluate(myFormula)
End Function
You could then use it like this in cell B1 on sheet 2:
=eval(SUBSTITUTE(Sheet1!$B$1,"A1","A"&ROW()))
Note that this requires Sheet 1 cell B1 to contain A1*3 and not =A1*3, i.e. no equal sign. Maybe with a bit more fiddling around, it can be made to work even with the = sign there...
EDIT: Actually, if you format Sheet 1 cell B1 as Text before typing in the formula, this will work even if your formula starts with a =.

Is it possible without macros?
Yes!
You can now use =LAMBDA for this.
Define your function using the name manager, then reference it in your second sheet's formula.
See syntax at Introducing the LAMBDA function.
For more information about how to use the LAMBDA function, see the support documentation.

Related

Is there a 2 Value Look up function in MS Excel that can perform the following?

I am going crazy over this. It seems so simple yet I can't figure this out. I have two worksheets. First worksheet is my data. Second is like an answer key. Upon checking checking, A1:B1 in Sheet 1 is a match with the conditions in Row 52 in SHEET 2, therefore, the value in Column C is "MGC". What is the formula that will perform this function? It's really hard to explain without the data so I pasted a link of the sample spreadsheet. Thank you so much in advance.
sample spreadsheet here. https://docs.google.com/spreadsheets/d/1_AjuNfCdGfEM-XkqPa6W4hSIxQg4NM2Vg4c2C1pQ_vQ/edit?usp=sharing
screenshot here. (wont let me post i have no reputation)
In Sheet2, insert a column in front of Column A and put the formula in A2 =C2&D2.
Then in Sheet1, Cell C2 the formula =vlookup(A2&B2,Sheet2!A:B,2,0).
the first make a concatenated key to lookup, then the second looks up that key.
How about a index(match())? If I've understood correctly you need to match across both the A and B column in sheet one, checking for the relevant values in B and C on sheet 2 to retrun worksheet 2 column a to worksheet 1 column c.
third version try:
=INDEX(Sheet2!$C$1:$C$360,MATCH(Sheet1!A1&Sheet1!B1,Sheet2!$B$1:$B$360&Sheet2!$C$1:$C$360,0))
Basically what this does is use concatenation, the & operator, to specify you are looking for "Criteria A" & "Criteria B" in sheet 1, which makes the string "Criteria A Criteria B", which is supplied in the first part of the match function.
In the second it then says match this against all of my variables in sheet 2 in the same way with concantenation.
The final part of match function (0) specifies you want an 'exact' match
It then supplied this as a reference to the index function, which then finds the row intersecting with the value you want, and returns that.
As noted here https://support.microsoft.com/en-us/kb/59482 this is an array formula, so it behaves differently, and must be input differently. https://support.office.com/en-za/article/Guidelines-and-examples-of-array-formulas-7d94a64e-3ff3-4686-9372-ecfd5caa57c7
There are (at least) 2 ways you could do this without VBA.
USING A SORTED LIST
The first relies on the assumption that your data can be re-sorted, so that everything "Unreported" is in the top, and everything "reported" is together below that (or vice versa). Assuming that this is the case (and it appears to already be sorted like this),we will use the function OFFSET to create a new range which shows only the values that align with either being "Unreported" or "Reported".
Offset takes a given reference to a point on a sheet, and then moves down/up & left/right to see what reference you want to return. Then, it returns a range of cells of a given height, and a given width. Here, we will want to start on Sheet2 at the top left, moving down until we find the term "Unreported" or "Reported". Once that term is found, we will want to move one column to the right (to pull column B from sheet 2), and then have a 'height' of as many rows as there are "unreported" or "reported" cells. This will look as follows in A1 on sheet 1, copied down:
=OFFSET(Sheet2!$A$1,MATCH(A1,Sheet2!A:A,0)-1,1,COUNTIF(Sheet2!A:A,A1),1)
This says: First, start at cell A1 on sheet2. Then find the term in A1 (either "unreported" or "reported", on sheet2!A:A (we subtract 1 because OFFSET starts at A1 - so if your data starts at A1 we need to actually stay at "0". If you have headers on sheet2, you will not need this -1). Then, move 1 column to the right. Go down the rows for as many times as Sheet2 column A has the term found in Sheet1 A1. Stay 1 column wide. Together, this will leave you with a single range on sheet2, showing column B for the entire length that column A matches your term in sheet1 A1.
Now we need to take that OFFSET, and use it to find out when the term in Sheet1 B1 is matched in Sheet2 column B. This will work as follows:
=MATCH(B1,[FORMULA ABOVE],0)
This shows the number of rows down, starting at the special OFFSET array created above, that the term from B1 is matched in column B from sheet2. To use this information to pull the result from column C on sheet 2, we can use the INDEX function, like so:
=INDEX([FORMULA ABOVE],MATCH(B1,[FORMULA ABOVE],0))
Because this would be fairly convoluted to have in a single cell, we can simplify this by using VLOOKUP, which will only require the OFFSET function to be entered a single time. This will work as follows:
=VLOOKUP(B1,[FORMULA ABOVE],2,0)
This takes the OFFSET formula above, finds the matching term in B1, and moves to the 2nd column to get the value from column C in sheet2. Because we are going to use VLOOKUP, the offset formula above will need to be adjusted to provide 2 columns of data instead of 1. Together, this will look as follows:
FINAL FORMULA FOR SHEET1, C1 & COPIED DOWN
=VLOOKUP(B1,OFFSET(Sheet2!$A$1,MATCH(A1,Sheet2!A:A,0)-1,1,COUNTIF(Sheet2!A:A,A1),2),2,0)
OPTION USING ARRAY FORMULAS
The above method will only work if your data is sorted so that the REPORTED and UNREPORTED rows are grouped together. If they cannot be sorted, you can use an ARRAY FORMULA, which essentially takes a formula which would normal apply to a single cell, and runs it over an entire range of cells. It returns an array of results, which must be reduced down to a single value. A basic array formula looks like this [assume for this example that A1 = 1, A2 = 2...A5 = 5]:
=IF(A1:A5>3,A1:A5,"")
Confirm this (and all array functions) by pressing CTRL + SHIFT + ENTER, instead of just ENTER. This looks at each cell from A1:A5, and if the value is bigger than 3, it gives the number from that cell - otherwise, it returns "". In this case, the result would be the array {"";"";"";4;5}. To get the single total of 9, wrap that in a SUM function:
=SUM(IF(A1:A5>3,A1:A5,""))
In your case, we will want to use an array formula to see what row in Sheet2 matches A1 from Sheet1, and B1 from Sheet1. This will look like this:
=IF(Sheet2!$A$1:A$100=A1,IF(Sheet2!$B$1:$B$100,ROW($B$1:$B$100),""),"")
This checks which rows in column A from sheet 2 match A1. For those that do, it then checks which rows in column B from sheet 2 match B1. For those, it pulls the row number from that match. Everything else returns "". Assuming no duplicates, there should only 1 row number which gets returned. To pull that number from the array of results, wrap the whole thing in a MATCH function. Now that you have the row number, you can use an INDEX function to pull the result in Column C with that row, like this:
FINAL ARRAY FORMULA METHOD
=INDEX($C$1:$C$100,MAX(IF(Sheet2!$A$1:A$100=A1,IF(Sheet2!$B$1:$B$100,ROW(Sheet2!$B$1:$B$100),""),"")))
Remember to confirm with CTRL + SHIFT + ENTER instead of just ENTER, when you type this formula. Note that I didn't refer to all of Sheet2!A:A, because array formulas run very slowly over large ranges.
The following formula should work without making any changes to the datasheets.
=INDEX(Sheet2!$A$1:$A$360,MATCH(Sheet1!A1,IF(Sheet2!$C$1:$C$360=Sheet1!B1,Sheet2!$B$1:$B$360),0))
Remember to save this formula as an array with CTRL+SHIFT+ENTER
Documentation on how to use INDEX and MATCH against multiple criteria can be found on Microsoft Support.
It's not clear what you want to do with the multiples that do not have corresponding matches. txed is listed as Unreported twice in Sheet1; kntyctap is listed as Unreported three times. There are only one corresponding match on Sheet2 for each of these.
Non-array Standard Formulas for multiple criteria matches
For Excel 2010 and above use this standard formula in Sheet1!C1:
=IFERROR(INDEX(Sheet2!$A$1:$A$999,AGGREGATE(15,6,ROW(1:999)/((Sheet2!$B$1:$B$999=A2)*(Sheet2!$C$1:$C$999=B1)), COUNTIFS(A$1:A1, A1, B$1:B1, B1))), "")
For version of Excel prior to 2010 use this standard formula in Sheet1!C1:
=IFERROR(INDEX(Sheet2!$A$1:$A$999, SMALL(INDEX(ROW($1:$999)+((Sheet2!$B$1:$B$999<>A1)+(Sheet2!$C$1:$C$999<>B1))*1E+99, , ), COUNTIFS(A$1:A1, A1, B$1:B1, B1))), "")
I've handled error with the IFERROR function in that latter formula. Excel 2003 and previous may have to use an IF(ISERROR(..., ...)) combination.

INDIRECT inside INDEX function giving #REF error

I'm have an excel workbook Spreadsheet.xlsx in which B2=MATCH(B1,'\\SERVER\Path\To\File\[Workbook.xlsx]Sheet1'!$A$1:$A$500,0) takes the string (a name) in in B1 and matches it to a column of row headers in Workbook.xlsx, to give the row number.
Currently B2 returns a value of 8, which is used in B3=INDEX('\\SERVER\Path\To\File\[Workbook.xlsx]Sheet1'!$A$8:$SD$8), MATCH($A4,'\\SERVER\Path\To\File\[Workbook.xlsx]Sheet1'!$A$2:$SD$2,0)).
B3 indexes a range of values $A$8:$SD$8 corresponding to the row number from B2 in Sheet1 in Workbook.xlsx, and returns the values matched to a date $A4 in the range $A$2:$SD$2.
Currently I am manually typing in the row number to B3 range `$A$8:$SD$8.
If I try to automate this using B3=INDEX(INDIRECT("'\\SERVER\Path\To\File\[Workbook.xlsx]Sheet'!$A$"&B2&":$SD$"&B2), MATCH($A4,'\\SERVER\Path\To\File\[Workbook.xlsx]Sheet1'!$A$2:$SD$2,0)), I get a #REF error.
I have used INDIRECT elsewhere e.g. =MAX(INDIRECT(K&"K1")) and it has worked just fine.
Also, Workbook.xlsx and Sheet1 in it definitely exist, and I am able to get data from them without using INDIRECT.
Why doesn't it work?
INDEX and MATCH functions, as used here, do work with closed workbooks - INDIRECT doesn't
...but you don't really need INDIRECT here - you can use this version with B2 defining the row number in the first range
=INDEX('\\SERVER\Path\To\File\[Workbook.xlsx]Sheet1'!$A$1:$SD$500),B2, MATCH($A4,'\\SERVER\Path\To\File\[Workbook.xlsx]Sheet1'!$A$2:$SD$2,0))
That should work even if the source workbook is closed, and is a "cleaner", more robust approach in any case.
Note that the first range in the formula is changed to be as long as your match range from B2
If you want you can cut out B2 altogether, just put the MATCH function from B2 in that formula in place of B2, i.e.
=INDEX('\\SERVER\Path\To\File\[Workbook.xlsx]Sheet1'!$A$1:$SD$500),MATCH(B1,'\\SERVER\Path\To\File\[Workbook.xlsx]Sheet1'!$A$1:$A$500,0), MATCH($A4,'\\SERVER\Path\To\File\[Workbook.xlsx]Sheet1'!$A$2:$SD$2,0))
[Note: as Jerry mentioned, your sheet names weren't consistent so I changed the first to Sheet1 to match the others]

Cell Referencing Formula

Was using this formula SheetName!CellAddress
I need to import Data that is available on other 2 sheets namely (sheet2 and sheet3) into sheet 1 in a way such that
the row values will be alternate i.e one value from sheet 2 and other value from sheet 3 respectively
Have tried like this
=Sheet2!C2
=Sheet3!D2
when i dragged for other values i was get only values in the even cell like(c4,d4,c6,d6)
If i change the for formula to
=Sheet2!C1
=Sheet3!D1
i was get only values in the even cell like(c3,d3,c5,d5)
But what i need is continous cells in row( c1,d1,c2,d2,c3,d3...)
So what formula i need to use for getting this result
I am still not 100% clear on what the question is asking, so let me know if the below answer doesn't work for you.
It sounds like what you're looking for can be accomplished with OFFSET and clever use of IF statement.
Suppose your formulas will be in column A, starting in A2. Then enter the following formula into A2 (line split added for readability; remove it):
= IF(MOD(COUNTA(A$1:A1),2)=0, OFFSET(Sheet2!$C$1, COUNTA(A$1:A1) / 2, 0),
OFFSET(Sheet3!$D$1, COUNTA(A$1:A1) / 2, 0))
Then drag the formula down.
What it does:
MOD(COUNTA(A$1:A1),2)=0 - checks whether we're in odd row or even row.
COUNTA(A$1:A1)/ 2 - takes half of the number of non-empty cells immediately above the current cell.
OFFSET(Sheet2!$C$1, COUNTA(A$1:A1) / 2, 0) - takes the cell which is COUNTA(A$1:A1)/ 2 cells below Sheet2!$C$1.
Here's a fairly basic method:
Enter the first two formulas as Text - you can either do this by formatting the cell number as text or preceding the formula by an apostrophe.
Select cells and fill down to get:
=Sheet2!C2
=Sheet3!D2
=Sheet2!C3
=Sheet3!D3
=Sheet2!C4
=Sheet3!D4
...
Select the column and choose Data|Text to Columns|Finish to change text to values.

Evaluating a formula defined in another cell

Say I've got a function name in cell A1, like SUM, and some data in B1 and C1. Is there any way to define a formula in one cell such that it calls the formula that is defined in A1 and have it work on B1 and C1 as data?
So something like:
=A1(B1:C1) should be equal to =SUM(B1:C1) since A1 contains the word SUM in it.
Essentially, something like preprocessor macros in C, or function pointers maybe.
You could do it using vba by creating a user defined function in a module:
Public Function applyFunction(functionName As Range, argument As Range) As Variant
applyFunction = Evaluate(functionName & "(" & argument.Address & ")")
End Function
If you put SUM in A1, and 1, 2, 3 in B1, B2, B3, =applyFunction(A1,B1:B3) will return 6. It is equivalent to calling =SUM(B1:B3).
EDIT
If you really don't want to use VBA, you can create a name (insert name in excel 2003 I think, Define Name in Excel 2010):
Define a new name (let's say eval1)
in the refers to area, enter =EVALUATE(A1&"(B1:B3)"), where A1 contains SUM and B1:B3 is the range with the numbers
in a blank cell, type =eval1 and it should return the result
But this approach is less flexible.
If you want to use a formula instead, you could possibly use the SUBTOTAL() function. However, it is a little limited.
Check out the image. It uses the reference to the function number for subtotal. You can expand this by creating a vlookup function if you want to use the name of the function, but you also have to provide a way to determine to use the regular function num or the 101-type values which ignores hidden values in the data range.
Check out this link for more info:
http://office.microsoft.com/en-us/excel-help/subtotal-function-HP010062463.aspx

Look up a value in a table based on two input values

I am very familiar with vlookup and hlookup functions in Excel. However, I am looking for a method of doing both. Take this example:
A B C
1 Resources
2 Task Mgr Sr. Mgr
3 -----------------------------
4 Task 1 30% 70%
5 Task 2 40% 60%
6 Task 3 50% 50%
7 Task 4 70% 30%
If I wanted to put a formula in a new cell to look up both a task and a resource type to return the appropriate percentage, how could I do this?
A combination of INDEX and MATCH will do the trick:
=INDEX($B$4:$C$7,MATCH("Task 3",$A$4:$A$7,0),MATCH("Mgr",$B$2:$C$2,0))
Another possibility:
=VLOOKUP(E3,A2:C7,MATCH(E2,A2:C2,0),FALSE)
Where
E3 contains the task to look up
E2 contains the header column name
(eg Mgr)
A2:A7 is the table of data
A2:C2 is the header
Okay, assume you have an Excel sheet with the following format where your lookup table occupies the cell range A1:E5
C1 C2 C3 C4
R1 R1C1 R1C2 R1C3 R1C4
R2 R2C1 R2C2 R2C3 R2C4
R3 R3C1 R3C2 R3C3 R3C4
R4 R4C1 R4C2 R4C3 R4C4
Also assume you want to enter the row header name and column header name into cells G3 and H3 respectively (which I have the text values "R3" and "C2").
In the cell you wish to display your output value, you could either use HLOOKUP like so:
=HLOOKUP(H3,A1:E5,MATCH(G3,A1:A5,0))
or VLOOKUP like so:
=VLOOKUP(G3,A1:E5,MATCH(H3,A1:E1,0))
Either displays the value "R3C2" in my output cell.
=OFFSET(A3,MATCH("Task 3", A4:A7, 0),MATCH("Mgr",B2:C2,0))
Of course, you're probably getting the things to look for from other cells, so replace "Task 3" and "Mgr" above with references to those cells.
Okokokok so
I just figured out an alternate, much simpler answer... its an IF function!
so okay, what I mean by this is the following;
you have 2 input cells, both formatted with data validation lists. One has the tasks, and one has the position, as shown in the question asked.
now we use a vlookup function to determine what row we are going to get, and then an IF function to determine the column!!
now lets say your input cells are next to each other at E1 and F1
So an example of this formula would be,
=vlookup($E$1,$A$4:$C$7,IF($F$1="MGR",2,3),FALSE)
This works so well and can even be used with more than 2 columns by using the IFS Function!
I Hope this helps some kid in the future who did exactly what I did and went to the internet for answers after being very confused hahaha

Resources