what is the purpose of OFFSET in excel? - excel

In Excel, the Offset function returns a reference to a range that is offset a number of rows and columns from another range or cell.
can someone please tell me what that means?
for example in this formula:
=OFFSET($B$4,ROW()-ROW($F$4),0,1,1)
what is it doing?

The purpose of OFFSET(BASE, ROW-OFFSET, COLUMN-OFFSET, NUM-ROWS, NUM-COLUMNS) is to select the content of cells that are NUM-ROWS rows and NUM-COLUMS distant from the base cell. If the selected cells are just one, then the content of that cell will be used as result, otherwise the result will be an array that can be passed to functions as SUM.
In your example, the function is simply selecting the content of the cell B4.

That example formula is odd, because it references a cell to get the row then takes that away from the current row - this bit ROW()-ROW($F$4, which might as well be row()-4, but there you go.
Offset, works like this
A cell location to start at, how many rows away from this, cols away from the this, optional size(rows), optional size(cols).

Related

Is there a general way to process only visible cells in excel?

I am wondering, if there is a general way to express, that only visible rows of a formula should be taken into account.
If I have for example a formula sumif($E5:$E100; "ABC"; $F5:F100) it would be very helpful, if there would be a way to express, that the given ranges should only take visible cells into account. I could imagine that a kind of prefix can be specified to a range construct like % or that like. For example the formula then would look like sumif(%$E5:%$E100; "ABC"; %F5:%F100) to make clear, that in the given ranges only visible rows should be taken into account.
Same would then for example be for sum(%A1:%A100) which would mean, that in the range between A1 and A100 only visible cells should be taken to sum up the cells.
The point is, that this construct could be taken inside any kind of formula, no matter what it is.
Thanks in advance
Georg
Generically to sum sumrange based on a match in criteriarange.....but only for visible rows you can use this formula: =SUMPRODUCT((criteriarange=criteria)+0,SUBTOTAL(109,OFFSET(sumrange,ROW(sumrange)-MIN(ROW(sumrange)),0,1,1))) The first part (criteriarange=criteria)+0 just checks the criteria for each row and returns 1 for a match or 0 OFFSET returns an "array of ranges" with each range in this case being a single cell from the sum range. SUBTOTAL can process that and with the sum function (109) gives the "sum" (i.e. the value) of each cell, only when visible. – SUMPRODUCT then multiplies the two ranges and sums the result, effectively giving you the sum of visible rows where the criteria matches
Try This
=SUMPRODUCT(($E$5:$E$100="ABC")+0,SUBTOTAL(109,OFFSET($F$5:$F$100,ROW($F$5:$F$100)-MIN(ROW($F$5:$F$100)),0,1,1)))

sumproduct with duplicates - only want first instance

I am using the following formula to return the data in a cell from looking up a row number.
=INDIRECT("Sheet2!R"&SUMPRODUCT(--(Sheet2!S:S=Sheet3!D3),ROW(Sheet2!R:R)))
The sumproduct formula looks at the value in cell D3 and returns which row it is found on in Sheet2. When there are more than one cells with the value in D3, the row numbers get added together. How can I get it to return only the first instance if there is more than one cell with the lookup value? I think I need rank or something, but am a little lost.
First INDIRECT is volatile and should be replaced with INDEX.
Second use AGGREGATE to return the lowest row number
=INDEX(Sheet2!R:R,AGGREGATE(15,7,ROW(Sheet2!S:S)/(Sheet2!S:S=Sheet3!D3),1))
Note: I left the full column References, but it is better practice to limit both Sheet2!S:S references to that of just the data set. It will speed up the calculations.

Match value then return value of cell to left or right

I have a range of cells that have different values. I would like to match values of cell but return the values of cell either to the left or right. For simplicity, let's just say I want the cell 1 column to the left:
Would appreciate any pointers
use the following:
=INDEX($A$1:$F$8,INT(AGGREGATE(15,6,(ROW($A$3:$F$8)+(COLUMN($A$3:$F$8)/1000))/($A$3:$F$8=$B$10),ROW(1:1))),INT(AGGREGATE(15,6,(COLUMN($A$3:$F$8)+(ROW($A$3:$F$8)/1000))/(((ROW($A$3:$F$8)+(COLUMN($A$3:$F$8)/1000))=AGGREGATE(15,6,(ROW($A$3:$F$8)+(COLUMN($A$3:$F$8)/1000))/($A$3:$F$8=$B$10),ROW(1:1)))*($A$3:$F$8=$B$10)),1)-1))
Since VLookup only works if your key is the leftmost item in the range and even then only if the range is a flat table from top to bottom, I think you can only do this using VBA. If your data is always exactly that format, you could also simply hardcode one row at the bottom with a specific cell at the top, if it matches the lookup value write the data, then filter the rows to remove errors/empty cells.
In VBA you just specify the starting point of your lookup data, loop through the cells (either down or to the right, then wrap around when you reach emptyness until you're not finding any more data), compare the cell value to your lookup calue and if it matches, write the data entry at the bottom.

replace volatile OFFSET in an excel SUMPRODUCT

I'm using Frontline's solver in excel and in some models the whole process is slowed down probably due to the heavy use of the excel function OFFSET. According to my research this function is considered volatile and should be avoided. Apparently one can replace the use of offset by INDEX. What I need to offset is a vector rather than just a value, to be used in a SUMPRODUCT. Something like SUMPRODUCT(array,OFFSET(vector)). INDEX seems to only be able to output a value rather than a vector.
Attached is a screenshot of a minimal example showing what I have as a formula. The yellow and blue cells are all fixed whereas the formula is in the green cells. The value in cell B11 is 16.
So my question: How can one replace the volatile OFFSET by something that's not volatile?
You can use INDEX. Replace your function with the following
=SUMPRODUCT(B$6:B$8,INDEX($F$6:$I$8,0,1))
The INDEX function in this case returns the first column values of the area F6:I8. The 0 returns the all rows, and the 1 returns the 1st column. You probably want to replace the 1 with COLUMN()-1 so you can copy the formula across but ideally you would do this with an array formula, but that's another question.
One tip I find really useful when working with functions is the ability to highlight part of the function in the function bar and calculate just that part by pressing F9. So if you highlight "INDEX($F$6:$I$8,0,1)" and press F9 it will show you which value(s) it is using.
From https://support.office.com/en-gb/article/INDEX-function-a5dcf0dd-996d-40a4-a822-b56b061328bd
"If you set Row_num or Column_num to 0 (zero), INDEX returns the array of values for the entire column or row, respectively. To use values returned as an array, enter the INDEX function as an array formula in a horizontal range of cells for a row, and in a vertical range of cells for a column.

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