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
Related
I am wondering if there is a way to do what I want more automatically, i've been doing it with good old regular copy paste but it's taking a lot of time, I need to take the horizontal data I have currently and put it vertically while keeping the first column for each rows, the first column is my "main" part number and I need to link all the other numbers starting from column B to this main part number, example below,
I sometimes have hundreds of rows and columns to do this for, here is what i'm working with
[1]: https://i.stack.imgur.com/dIyZv.png
And here's what the end result needs to look like;
[2]: https://i.stack.imgur.com/PvxGh.png
Thank you in advance!
It can be achieved either with VBA Code or with formulas. I did it with formulas and will try to show you how below.
I have one sheet with all the data, lets call it Sheet1. It looks like this:
Then, I have another sheet which returns what you want (Sheet2). It looks as follows:
Note that the first two columns are necesary for the formulas to work. The actual result is on Columns C and D.
Now, below are the formulas (or values) you would need to put in Sheet2 to make it work:
Cell A1: 0
Cell B1: 1
Cell A2: IF(B2=1,A1+1,A1)
Cell B2: IF(B1+1=$G$1,1,B1+1)
Cell C1: OFFSET(Sheet1!$A$1,A1,0)
Cell D1: OFFSET(Sheet1!$A$1,A1,B1)
Cell G1: The number of columns in the data on Sheet1
Then, just drag the formulas (not the values in A1, B1), until you have the expected result.
I would suggest you try to implement this simple example first, and then move it to your actual spreadsheet.
Let me know how it goes.
EDIT: Regarding your comment, we could do a trick to make it work for a variable number of columns.
First, lets add some variability to the number of columns in Sheet1. This is how my new Sheet1 looks like:
On Sheet2 I added a formula to count the number of columns per row. See Column F below:
Then, the trick is to change the formulas in Column B in Sheet2:
Before: Cell B2: IF(B1+1=$G$1,1,B1+1)
After: Cell B2: IF(B1+1=OFFSET($F$4,A1,0),1,B1+1)
Note: My formula to count the number of columns per row is:
Cell F4: COUNTA(Sheet1!A1:D1)
Note: Change D1 to the max column in Sheet1. Eg. M1.
Note2: You can get rid of cell G1 now.
Start with column B and everything else becomes a doddle. I only use 1 formula for column B and no more than 1 or 2 for column A (there are 3-4+ methods, no need to duplicate yourself but choose any of them to construct A).
I'm only using 1 formula to make each column. Entire job task done in a minute-5.
Column B. Do this first for all your "column B's":'
=IF(ROW(A1)=1,INDEX(A$1:T$1,INT(((ROW()-20)/20+1-ROW($A$1))/COLUMNS(A$1:T$1))+1,MOD(ROW()-20-ROW($A$1),COLUMNS(A$1:T$1))+1),INDEX(A$1:T$1,INT(((ROW()-20)/20+1-ROW($A$1))/COLUMNS(A$1:T$1))+1,MOD(ROW()-20-ROW($A$1),COLUMNS(A$1:T$1))+1))
So all you have to do is drag down. Change only the row references to refer to your 100's if different rows you need to do this for. 1 minute. Job done
for 30 columns/cells change T to AD, for 200 cells , change T to GR, etc. You can also force it to stop at number of your choice.
If you put it anywhere else, it will still work, but your going to have to jiggy with the math a bit to get it to start from the the first entry in the row ( or the specific Wherever you want). Its up to you.
It acts like a modular clock. Been using it for a few years. Ticker tape. Rolling slabs of concrete laying out for you.
here, this is what I get when I plug it into the first row of any column , referring to a 20 field length header on my sheet.
Etc... It continues forever (or for however long you want it). (and you can change the mod anytime).
The first argument you could change to whatever your requirements are , for instance , if(LEN(F8)<1, or whatever, to Start/"Set the clock."
And For any corresponding ranges (your first column for each) (** Your "Column A's" **):
=IF(LEN(H20)<1,K21,H20)
or you can use this logic. It Becomes elementary.
=IF(J21=K21,J21,J20)
Better if you use this starting from row 2 on each column A: if(and(j1=it's next door neighbour, row(it's next door neighbour cell=1)), it's self j1,.. blah blah blah blah
OR AM I MISSING THE POINT ?
Method for getting column A;
Since you already have B, A becomes a simple trivial matter. Like cell =$fixed$cell , i.e. A1=$B$1 and drag down.
simple. headache over. game over. Its all effortless.
But if you want me to elaborate more ,
method 2 for getting 1st column, column A's;
=IF(LEN(AV1)>1,IF(ROW(AV1)=1,AV1,INDIRECT("Av"&1)),"")
=IF(ROW(B1)=1,B1,INDIRECT("B"&1)) <---- drag down from row 1
Method 1 for getting 1st column;
=IF(LEN(AV1)>1,$AV$1,"") <----- drag down from row 1
Method 3, below was my favourite:
=$B$1 <---- from row1 drag down (where row1 was just = column B, cell b1, a1=b1) easy peasy .
You could always demand a further simplification of M3:
A1=if(len(b1)>1,$b$1,"") <--drag down from b2 (where b1 was already set) *probably best because only returns a value as long as column B is .otherwise returns blank.
It's like handling duplicates by formula. Similar .
there was a method 4 too. bUt its late. (Written # 02:00)
Or did I miss the point? It's easy. Imo
Im only using 2 formulas. 1 for each column you need done . do column B first, and colimn A becomes a matter of fact . A doddle.
method 1 is my new favourite.
Its late, my naighbours have pissed me off again. Pardon my fonts and writing but seriously. didnt expect this. some people need to go to jail.(my naighbours)
So in the end: 1 formula for B. 1 for A (any one of any the 4+ methods. There are more also) , plug in and scroll for all the rows you need this done for . takes you 30 seconds? 5 minutes tops for all your rows.
IFERROR(INDEX($I$7:$I,MODE(IF($I$7:$I<>"",MATCH($I$7:$I,$I$7:$I,0)))),"No data")
With this formula, which calculates the most common text value, I need to have the 2nd most common.
Column I content:
Apple
Orange
Apple
Apple
Orange
In this example, I need to get Orange. How is that possible? I can't figure how.
A PivotTable might suit:
and copes with ties for rank.
You can extract the most frequent item in the list with an array formula.
=INDEX(MyList,MATCH(MAX(COUNTIF(MyList,MyList)),COUNTIF(MyList,MyList),0))
Note that an array formula must be confirmed with Shift+Ctl+Enter instead of the customary singular Enter required for normal formulas. When entered wrongly it will display a #NUM! error.
For simplicity's sake I have used a named range MyList in the formula. However, if you prefer, you can replace the name with something like $I$7:$I$1000.
To extract the second-most frequent expression in the list you could use a formula constructed analogue to the above.
=INDEX(MyList,MATCH(LARGE(COUNTIF(MyList,MyList),MAX(COUNTIF(MyList,MyList))+1),COUNTIF(MyList,MyList),0))
This formula is built on the logic that n equals the highest number of occurrences. Therefore the second highest must rank as n + 1, being MAX(COUNTIF(MyList,MyList))+1) in the above formula. By the same method the third ranked could be extracted.
You can embed these formulas in an IFERROR() function.
I found this on Mr Excel
Return most common, 2nd most common, 3rd most common, etc. text string in an array
Spreadsheet Formulas
Cell ___ Formula 'Notice that the cells are B2, D2, E2. Column C is blank
B2 =IF(A2="","",IF(COUNTIF(A$2:A2,A2)=COUNTIF($A$2:$A$100,A2),COUNTIF($A$2:$A$100,A2)+(ROW()/1000),""))
D2 =IF(ROWS($1:1)>COUNT(B:B),"",INDEX(A:A,MATCH(LARGE(B:B,ROWS($1:1)),B:B,0)))
E2 =IF(D2="","",COUNTIF($A$2:$A$100,D2))<br><br>
Results
___ A ________ B ___C ___D _________E
1 Data Set:___Helper ____ Name ____ Occurrences
2 Harmon _____________ Williams ______4
3 Smith _______________ Smith ________3
4 Smith _______________ Harmon ______2
5 Harmon_____ 2.005
6 Williams
7 Williams
8 Smith _______3.008
9 Williams
10 Williams ____4.010
you can try to tie this all together in a single formula but it's simpler and more agile in a spreadsheet environment to just break out the problem in a few separate steps.
take a given column of values you're wanting to count/rank - i'll call it RankList in examples below.
if you're not setting named ranges (do yourself a favor and use named ranges) you'll want this to be your column range - i.e. A:A
now in another column use
=unique(RankList)
there's your list of unique values, now we just need to count the instances of each unique value in the original RankList - this is simple - in the next column over simply use
=countif(RankList,B1)
B1 above represents the cell adjacent to the formula, wherever that might be on your sheet. now autofill the formula in with the relative cell value for each item. now all of your items are counted by instance.
now we want to sort them by value, highest to lowest. create another named range, selecting the two columns containing the =unique(RankList) and =countif(RankList,B1) formulas that were just created, i'll refer to it as UniqueCount
use the following
=sort(UniqueCount, 2, false)
that's it. again you can accomplish this by stacking formulas like in the above examples, but in practice i've found that you won't know what you'll want to do additionally with your data/sheet later on. keeping it broken up in discrete steps like this makes it much easier to make adjustments.
I am trying to create a decoding macro. I have different combinations of letters in each cell on one sheet. For example, in cell B2 I would have something like "ABC." On a different sheet I have a table that matches letters to numbers, so I want the output in the new cell to be "123" in that case. I know how to use VLOOKUP on an entire cell, but cannot figure out how to use it on individual parts and then concatenate the results back together in the new cell.
This is what I've figured out so far. I think I need INDIRECT as part of it so I can reference the cell, but I cannot figure out how to look up the different portions of the cell. I do not want to create new columns to split the letter combinations up if possible.
=IFERROR(VLOOKUP("not sure??",'Conversion Table'!A4:B19,2,FALSE),"")
Thanks!
I'm assuming your cell B2 is limited to 3 chars only, and it's the same everywhere. In this case, you can do:
=CONCATENATE(VLOOKUP(MID(B2,1,1),'Conversion Table'!$A$4:$B$19,2,0),VLOOKUP(MID(B2,2,1),'Conversion Table'!$A$4:$B$19,2,0),VLOOKUP(MID(B2,3,1),'Conversion Table'!$A$4:$B$19,2,0))
If you have more chars, only add them using concatenate and select them one by one using MID.
Edit - locked the lookup table.
I think what you may be looking for is this:
A B C D
1 =""
2 ABC =IFERROR(VLOOKUP( =D1&C2
B2,
'Conversion Table'!$A$4:$B$19,
2,FALSE),"")
3 XYZ =IFERROR(VLOOKUP( =D2&C3
B3,
'Conversion Table'!$A$4:$B$19,
2,FALSE),"")
4 PQR =IFERROR(VLOOKUP( =D3&C4
B4,
'Conversion Table'!$A$4:$B$19,
2,FALSE),"")
5 DEF =IFERROR(VLOOKUP( =D4&C5
B5,
'Conversion Table'!$A$4:$B$19,
2,FALSE),"")
The "Final Answer" appears in cell D5
I need a formula that will look up a value in a 2-dimensional range and return the coordinates or cell address of the matching cell. For example:
R A B C
1 John Matt Pete
2 Sara Bret Chad
3 Lila Maya Cami
I want to search the range A1:C3 for Chad and return C2 or 2,3. How can I accomplish this using Excel formulas? (I'll actually end up applying this to Google Sheets).
Thanks!
Old question, but I thought I'd share a much simpler and elegant answer here that doesn't involve helper columns or complicated formulas, so that more people will get things done easier. Assuming that the table contains unique values and that you use E1 to store your search string Chad and E2 to display the result:
if you want the row and column result of 2,3 in E2:
=SUMPRODUCT((A1:C3=E1)*ROW(A1:C3)) & "," & SUMPRODUCT((A1:C3=E1)*COLUMN(A1:C3))
if you want the R1C1 style cell address string of C2 in E2:
=ADDRESS(SUMPRODUCT((A1:C3=E1)*ROW(A1:C3)),SUMPRODUCT((A1:C3=E1)*COLUMN(A1:C3)))
if you want the found cell's contents of Chad in E2:
=INDIRECT(ADDRESS(SUMPRODUCT((A1:C3=E1)*ROW(A1:C3)),SUMPRODUCT((A1:C3=E1)*COLUMN(A1:C3))))
How things work:
SUMPRODUCT returns in this case the sum of the products between a boolean array of TRUE (searched value found in cell) and FALSE (searched value not found in cell) for every cell in the table and the corresponding row/column (absolute) numbers of those cells in the sheet; thus, the result is essentially the row/column (absolute) number of the cell where the value has been found, since TRUE=1 and FALSE=0 in mathematical terms
ADDRESS returns a cell's address as text (not as reference!)
INDIRECT returns the reference corresponding to a cell's text address
Source and credit goes to: this answer by XOR LX. Could have added the link in a comment, mentioning the duplicate question, but I wanted to expand and explain the answer a little bit, therefore more characters were needed.
Assuming you're using Excel 2007 and above.
You will need a helper column. If your table looks like in your example, in cell D1 write:
=IFERROR(MATCH($E$1,$A1:$C1,0),0)
And drag it down. Then in cell E1 write your search value ("Chad" for instance). Then you have your search result in cell E2 with this formula:
=IF(MAX($D:$D)=0,NA(),MATCH(MAX($D:$D),$D:$D,1)&","&MAX($D:$D))
If you want a simpler solution, it is possible to use only one helper (or not at all, at the cost of a complicated formulae).
Let's say I take your example. I will use the D column to display result :
In D1, I put the name I want to find : Chad
In D2, I put the helper that will return an Index of the value searched (-1 if not found) : =IFERROR(MATCH(D1,SPLIT(TEXTJOIN(";",TRUE,A1:C3),";"),0),-1)
In D3, I put the formulae to get the row,column value (FALSE if not found) : =IF(D2<>-1,ROUNDUP(DIVIDE(D2,COLUMNS(A1:C3))) & "," & IF(MOD(D2,COLUMNS(A1:C3))=0,COLUMNS(A1:C3),MOD(D2,COLUMNS(A1:C3))))
If you really want to use only one formulae, it is possible in D3 to replace all references to D2 by the formulae used in D2.
This formula returns the row and column number of a given value in a two-dimensional array.
=LET(
array, B2:D4,
findvalues, C7,
arrayrows, ROWS(array),
arraycols, COLUMNS(array),
rowindex, SEQUENCE(arrayrows*arraycols,,1,1/arraycols),
colindex, MOD(SEQUENCE(arrayrows*arraycols,,0),arraycols)+1,
flatarray, INDEX(array,rowindex,colindex),
valueflatindex, MATCH(findvalues,flatarray,0),
valuerow, ROUNDUP(valueflatindex/arraycols,0),
valuecol, MOD(valueflatindex-1,arraycols)+1,
absvaluerow, MIN(ROW(array))+valuerow-1,
absvaluecol, MIN(COLUMN(array))+valuecol-1,
CHOOSE({1,2},absvaluerow,absvaluecol)
)
A B C D E
1
2 John Matt Pete
3 Sara Bret Chad
4 Lila Maya Cami
5
6
7 find: Chad
8 formula: 3 4
More precisely, this formula scans a given array row by row and returns the address of the first occurrence of a given value.
If you need the row and column numbers relative to the array's top left cell, then in CHOOSE(...), instead of absvaluerow/absvaluecol, use valuerow/valuecol.
If you want the values to be comma separated and in one cell, instead of CHOOSE(...), use absvaluerow & "," & absvaluecol
If your Excel version does not support the latest functions, such as LET, the formula should still work if you rewrite it so that it does not use the LET variables.
Find Multiple Values
You can also find multiple values in an array using this formula as explained in my answer in this thread.
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.