Proper Use of the Offset Function - excel

I have the following formula
=IFERROR(IF(FIND(OFFSET($B$2,1,0),$A3,1),VLOOKUP(OFFSET($B$2,1,0),'Keyword list'!B2:E316533,2,FALSE),""),"n/a")
which looks up a value associated with a word if the word is found and otherwise returns "n/a". I have included the OFFSET() function with the hope of making it so that when I move the formula to another column, say from column B to column C, the reference is not still $B$2, and not C2, but B3. Effectively I am trying to make it so that when the formula is dragged across the reference row changes instead of the column, and when I drag down the reference remains fixed at $B$2, $B$3 and so on. Is it possible to use the offset function to do this? Is there a clear mistake I've made in trying to apply it to the above formula? Thanks!

You could maybe try the following?
=IFERROR(IF(FIND(OFFSET($B$2,COLUMNS($A:A)-1,0),$A3,1),
VLOOKUP(OFFSET($B$2,COLUMNS($A:A)-1,0),'Keyword list'!$B$2:$E$31,2,FALSE),""),
"n/a")
I made a google spreadsheet so that you can try to drag the formula across.
The limitation of that formula is that it will rely on the column of the formula, and it cannot be dragged towards the left in Excel, since that will cause the reference COLUMNS($A:A) to go COLUMNS(#REF!). It can be put in any column then dragged to the right.

This is untested, but I think it does what you want, i.e., shift the reference down one row, for each column you drag to the right. It uses the COLUMNS function anchored at B in one half and relative in another:
=IFERROR(IF(FIND(OFFSET($B$2,COLUMNS($B:B),1),$A3,1),VLOOKUP(OFFSET($B$2,COLUMNS($B:B),1),'Keyword list'!B2:E316533,2,FALSE),""),"n/a")

I'd go with using INDIRECT to build a reference out of a computed string.
INDIRECT("B"&(2+COLUMN(<current cell>)-COLUMN($B$1)))
This way your reference gets calculated dependent from the offset to column B:
In cell D2 the referenced cell is "B"&(2+COLUMN(D2)-COLUMN($B$1)) = "B"&(2+4-2) = "B4"
In cell D3 the reference does not change, as only columns are taken into account.
Same for cell E2: "B"&(2+COLUMN(E2)-COLUMN($B$1)) = "B"&(2+5-2) = "B5"
If your calculation is that fixed, you could even only do with COLUMN(E2) as 2 and COLUMN(B1) cancel each other out: INDIRECT("B"&COLUMN(<current cell>)))

Related

Excel: dynamically calculate range next to a searched up cell

I am an occasional Excel user and stuck how to create a dynamic range.
After looking up a text in a table, how can I calculate the range next to this cell, up to the next empty row? Not using VBA.
Thanks for your help.
In H4, formula copied down :
=IFERROR(INDEX(INDEX(C:C,MATCH(F4,A:A,0)):C$1000,MATCH(G4,INDEX(B:B,MATCH(F4,A:A,0)):B$1000,0)),"")
Should you want a dynamic range,
Change C$1000 to INDEX(C:C,MATCH(9.9E+307,B:B)
and
Change B$1000 to INDEX(B:B,MATCH(9.9E+307,B:B))
Then
The H4 copied down formula become :
=IFERROR(INDEX(INDEX(C:C,MATCH(F4,A:A,0)):INDEX(C:C,MATCH(9.9E+307,B:B)),MATCH(G4,INDEX(B:B,MATCH(F4,A:A,0)):INDEX(B:B,MATCH(9.9E+307,B:B)),0)),"")
Edit :
As per Ron Rosenfeld's comment, "should B11 change to 24 and G4 change to 24"
The "Source Table" set up in Excel Table type for dynamic range growing purpose
and
The H4 formula change to :
=IFERROR(LOOKUP(9^9,Table1[price]/(LOOKUP(ROW(Table1[texture]),ROW(Table1[texture])/(Table1[texture]<>""),Table1[texture])=F4)/(Table1[length]=G4)),"")
Combining the Index() and Match() functions usually works well when using two conditions. However, you will need to fill out the entire column A with the "texture" list in order for the below formula to work.
=INDEX(<P1>, MATCH(TRUE, (<T1>=<T2>) + (<L1>=<L2>) > 1,0))
Where <P1> is your entire price column (ex. C2:C15)
Where <T1> is your entire texture column (ex. A2:A15)
Where <T2> is your texture lookup value cell
Where <L1> is your entire length column (ex. B2:B15)
Where <L2> is your length lookup value cell
Let's say that you input your texture value into cell F3, and your length value into cell F4. With the remaining columns remaining as they are in your image, you would use the following formula:
=INDEX(C2:C15, MATCH(TRUE, (A2:A15=F3) + (B2:B15=F4) > 1,0))
Now last time I had to use Index/Match I thought I had to place the formula into an array. However, the above seems to work without it.
If you notice that it's not working as expected, you can place into an array formula by clicking the cell that contains the formula, then clicking the formula box at the top. While in the formula box, simultaneously press Ctrl + Shift + Return. This should then place curly brackets around your entire formula if done properly, as such:
If you have O365 with the SEQUENCE function, you can use, for price:
=IF(G4="","",VLOOKUP(G4,INDEX($B:$C,SEQUENCE(MATCH(TRUE,ISBLANK(INDEX($B:$B,MATCH(F4,$A:$A,0)):INDEX(B:B,ROWS(B:B)-MATCH(F4,$A:$A,0))),0)-1,,MATCH(F4,$A:$A,0)),{1,2}),2,FALSE))
explanation:
get starting row:
MATCH(F4,$A:$A,0)
ending row will be the first blank row after the starting row:
MATCH(TRUE,ISBLANK(INDEX($B:$B,MATCH(F4,$A:$A,0)):INDEX(B:B,ROWS(B:B)-MATCH(F4,$A:$A,0))),0)
Construct the relevant array:
INDEX($B:$C,SEQUENCE(MATCH(TRUE,ISBLANK(INDEX($B:$B,MATCH(F4,$A:$A,0)):INDEX(B:B,ROWS(B:B)-MATCH(F4,$A:$A,0))),0)-1,,MATCH(F4,$A:$A,0)),{1,2})
The above might reduce (with wavy) to:
index(b:c,{9,10,11},{1,2}
Then it's just a matter of applying the VLOOKUP
A more understandable, but longer with more operations, formula available in O365 makes use of LET. The advantage is that one can use names which indicate what each section of the formula does.
For example:
=IF(G4="","",LET(startRow,MATCH(F4,$A:$A,0),numRows,MATCH(TRUE,ISBLANK(INDEX($B:$B,startRow):INDEX($B:$B,ROWS($B:$B)-startRow)),0)-1,
arr,INDEX($B:$C,SEQUENCE(numRows,,startRow),{1,2}),price,XLOOKUP(G4,INDEX(arr,0,1),INDEX(arr,0,2)),price))
Or, using VLOOKUP
=IF(G4="","",VLOOKUP(G4,LET(startRow,MATCH(F4,$A:$A,0),numRows,MATCH(TRUE,ISBLANK(INDEX($B:$B,startRow):INDEX($B:$B,ROWS($B:$B)-startRow)),0)-1,arr,INDEX($B:$C,SEQUENCE(numRows,,startRow),{1,2}),arr),2,FALSE))
Finally, for earlier versions of Excel, you can use this whopper where we replace the SEQUENCE function with a construct like: ROW(INDEX(A:A,firstRow):INDEX(A:A,lastRow))
=IF(G4="","",VLOOKUP(G4,INDEX($B:$C,ROW(INDEX($A:$A,MATCH(F4,$A:$A,0)):INDEX($A:$A,MATCH(F4,$A:$A,0)+MATCH(TRUE,INDEX($B:$B,MATCH(F4,$A:$A,0)):INDEX($B:$B,ROWS($B:$B))="",0)-2)),{1,2}),2,FALSE))

fix a formula against targets move in MS Excel

I am making a simple Expense report with columns as shown in
The formula # D3 and on is D3 = =D2-B3
the problem comes when, sometimes, i need to feed in a previous dates,
then i am required to move/insert a row in the Range A1:C#!
this result in shifting the values of B# in Column D ... formulas
lookie result:
Even if i manually enter = $D$2 - $B$3 for the entire Column D,
when i move B3 to B4... the D formula gets messed up.
How can i fix the formulas to always be = D[previous row] - B[current row]?
Try this in D3 and fill down.
=INDEX(D:D, ROW()-1)-INDEX(B:B, ROW())
You may try to indirectly reference the cells using INDIRECT function like this:
=INDIRECT("D"&(ROW()-1))-INDIRECT("B"&ROW())
The concatenated text string "D" and the output of ROW function inside the parentheses form a reference-like string (i.e. D3, D4, D5, etc.) that is evaluated by INDIRECT function to display their values. Very useful if you'd like to use it in such a way as you describe it. Use sparingly, though as it is a volatile function and could be slow in large workbooks.
Hope this helps..
References:
INDIRECT function

Use string value from a cell to access worksheet of same name

I have 2 worksheets: Summary and SERVER-ONE.
In cell A5 on the Summary worksheet, I have added the value SERVER-ONE.
Next to it, in cell B5, I would like a formula that uses the value in A5 to display the value of G7 in the worksheet of the same name (SERVER-ONE).
I could manually use:
='SERVER-ONE'!G7
However I would like this to be dynamic, so I can easily add more worksheets.
I tried the obvious with no joy:
='A5'!G7
Any suggestions?
You can use the formula INDIRECT().
This basically takes a string and treats it as a reference. In your case, you would use:
=INDIRECT("'"&A5&"'!G7")
The double quotes are to show that what's inside are strings, and only A5 here is a reference.
You need INDIRECT function:
=INDIRECT("'"&A5&"'!G7")
not sure if you solved your question, but I found this worked to increment the row number upon dragging.
= INDIRECT("'"&$A$5&"'!$G"&7+B1)
Where B1 refers to an index number, starting at 0.
So if you copy-drag both the index cell and the cell with the indirect formula, you'll increment the indirect.
You could probably create a more elegant counter with the Index function too.
Hope this helps.
Here is a solution using INDIRECT, which if you drag the formula, it will pick up different cells from the target sheet accordingly. It uses R1C1 notation and is not limited to working only on columns A-Z.
=INDIRECT("'"&$A$5&"'!R"&ROW()&"C"&COLUMN(),FALSE)
This version picks up the value from the target cell corresponding to the cell where the formula is placed. For example, if you place the formula in 'Summary'!B5 then it will pick up the value from 'SERVER-ONE'!B5, not 'SERVER-ONE'!G7 as specified in the original question. But you could easily add in offsets to the row and column to achieve the desired mapping in any case.
By using the ROW() function I can drag this formula vertically. It can also be dragged horizontally since there is no $ before the D.
= INDIRECT("'"&D$2&"'!$B"&ROW())
My layout has sheet names as column headers (B2, C2, D2, etc.) and maps multiple row values from Column B in each sheet.
INDIRECT is the function you want to use. Like so:
=INDIRECT("'"&A5&"'!G7")
With INDIRECT you can build your formula as a text string.
Guess #user3010492 tested it but I used this with fixed cell A5 --> $A$5 and fixed element of G7 --> $G7
=INDIRECT("'"&$A$5&"'!$G7")
Also works nested nicely in other formula if you enclose it in brackets.
This will only work to column Z, but you can drag this horizontally and vertically.
=INDIRECT("'"&$D$2&"'!"&CHAR((COLUMN()+64))&ROW())

Excel Row() and Column() Function

I have a simple question:
How do I reference a row combined with a column or vice versa?
e.g.
I have a table like this:
|A|B|C|D|
1 |1|0|1|
2 |4|4|2|
3 |7|2|3|
4 |5|7|2|
5 |3|9|1|
To reference A1, how do I reference it using the Row() function
I want the column to remain a constant but the row be varaible according to which row I am on.
If I am on D5, for instance, I want something like: =SUM(ARow(), CRow()) which is equivalent to =SUM(A5, C5) which returns 4.
Thanks.
... Sorry For the previous answer, given you want to change row but keep column constant, you could use the $ reference in the formula.
For example, if your formula in D5 was:
= Sum($A5, $C5)
That would keep the column constant and the row would change.
Similarly, $A$5 would force the formula to ALWAYS use A5 and A$5 would force the formula to always use row 5, but change the column.
Hope this helps :)
the ROW() and COLUMN() function reference rows and columns, not single cells...
You might be helped with the ADDRESS() function, where you can use row and column numbers as parameters.
And to the basics to reference a column-row combination without explaining further on the logic of your function you could simply use the cell address itself:
D5 : =SUM(A5, C5)

Drag down formula and change COLUMN references instead of ROWS

I have this formula in Excel, in row E5:
=SUM(Banco!H$5;Banco!H$6;Banco!H$8;Banco!H$9;Banco!H$10;Banco!H$11)
I need it to change the COLUMN references instead of ROWS when I drag it down (basically behave like I was dragging it across)... For example:
=SUM(Banco!I$5;Banco!I$6;Banco!I$8;Banco!I$9;Banco!I$10;Banco!I$11)
=SUM(Banco!J$5;Banco!J$6;Banco!J$8;Banco!J$9;Banco!J$10;Banco!J$11)
=SUM(Banco!K$5;Banco!K$6;Banco!K$8;Banco!K$9;Banco!K$10;Banco!K$11)
Any clues?
Thanks a lot!
... Use the offset function.
For example - Suppose you had a formula in row 1 and you wanted to reference Banco!H5, you could do something like:
=OFFSET(Banco!$G$5,0,ROW())
Now, as you drag it down, it will offset by the number of rows down you go.
So your new formula would look as follows:
=SUM(OFFSET(Banco!$G$5,0,ROW()),OFFSET(Banco!$G$6,0,ROW()),OFFSET(Banco!$G$8,0,ROW()),OFFSET(Banco!$G$9,0,ROW()),OFFSET(Banco!$G$10,0,ROW()),OFFSET(Banco!$G$11,0,ROW()))
Again, this assumes you are pasting this formula in row 1 (I know it's ugly, but you specified specific cells, so you have to specify each one separately)
Hope this makes sense
Use a combination of the OFFSET and the COUNTA function. The OFFSET function will give the offset of COUNTA columns each time you go down a row. Make the counta function count the number of rows above the row that you're dragging the entire function into (aka each time you drag the function to an extra row, it will add 1)

Resources