Make formula Indirect - excel

How can this formula be made with INDIRECT function so that there are no #REF errors when rows are deleted and shifted up. Here is my code:
=IFERROR(INDEX(G5:BL5, MATCH(REPT("z",255),G5:BL5)),0)

You don't need INDIRECT; INDEX will do just as well and is non-volatile.
=IFERROR(INDEX(index(G:BL, 5, 0), MATCH(REPT("z",255), index(G:BL, 5, 0))), 0)
Hard-coding row 5 will stop #REF! errors on row insertion/deletion.

Related

How to SUMIFS horizontally with a criteria and offset

I'm having trouble with an excel formula where i'm trying to get the sum of all numbers in the row which are at 1 column offset with the criteria.
Eg. A1 = Price | B1 = $1000| C1 = Price| D1 = $1500 and so on....
Answer should be 1000+1500= $2500
I tried =SUMIF(1:1,"Price",OFFSET(1:1,0,1)) but gives me error!
I am guessing you have the cell with your formula in the same row, so it is a cyclic reference that gives you the error.
You can cut 1:1 before the cell with the SUMIF:
=SUMIF(OFFSET(1:1, 0, 0, 1, COLUMN() - 2), "Price", OFFSET(1:1, 0, 1, 1, COLUMN() - 2))
a possible solution is to offset your reference ranges. This means you will not be able to do an entire row reference. In your limited example your formula would wind up looking like this:
=SUMIF(A1:Q1,"price",B1:R1)
so you sum range will be limited to one less column than what is available to the sheet to allow for the second range (equal in size range) to be shifted one column to the right.
SIDE NOTE
Idealy you would want to arrange your data in a table. I understand this may not always be possible when dealing with 3rd party data dumps, limited VBA knowledge, and large amounts of data.
SUMIF(A20:ZZ20, "Price", OFFSET(20:20, 0, 1, 1, COLUMN() - 2))

How can I redistribute a range of values without duplicates between 1 and 100?

I have a list of values between 1 and 100, essentially a sort of ranking that occassionally skips a few numbers (for example, the first ten values are 2, 6, 6, 10, 10, 10, 10, 11, 12, 13). They're ordered ascendingly, so every number will be either higher than or equal to the number above it. Now, I wish to remove all the duplicates from this list while remaining between 1 and 100. So, for example, for the values above, something like 2, 6, 7, 10, 11, 12, 13, 14, 15, 16 would work or 2, 6, 7, 8, 9, 10, 11, 12, 13, 14. However, the formulas I've tried so far will either go over 100, go under 1, or create circular references.
Given the nature of the list, there's very little chance of the amount of values exceeding 100, so if that possibility can be accounted for, it'd be a nice bonus, but it's not required.
Please create a named range for all your numbers and name it Source. As an alternative, replace the named range Source in my formulas below with the sheet address of the range where you have your numbers.
[C2] =INDEX(Source,MATCH(0,COUNTIF($C$1:$C1,Source),0))
This is an array formula and needs to be confirmed with Ctl + Shift + Enter. Observe that the COUNTIF range is defined one row above the row in which the formula resides. Its formulated with one absolute and one relative end. The end of the range will expand as you copy the formula down.
You can achieve a similar result using the LOOKUP() function. But since MATCH() finds the first instance, LOOKUP() returns the last. Therefore the formula below will return the same sequence in descending order. LOOKUP() is capable of looping on its own and the formula doesn't require array enabling. Just confirm it normally, with only Enter.
[E2] =LOOKUP(2,1/(COUNTIF($E$1:E1,Source)=0),Source)
Observe that the result range is defined with an absolute and relative end, starting above the row of the formula as explained above.
In B2, formula copied down :
=IF(A2="","",IF((COUNTIF(B$1:B1,A2)>0)+(A2=A1),B1+1,A2))
Edit #1
If data have repeated 100 as per OP's comment, then B2 formula become :
=IF((COUNTIF(B$1:B1,100)>0)+(A2=""),"",IF((COUNTIF(B$1:B1,A2)>0)+(A2=A1),B1+1,A2))
Thank you everyone for posting! Thanks to Bosco's original reply, I managed to fiddle around and find the answer myself. The biggest issue I was facing was getting a circular formula error, but by using Bosco's formula as a help column I was able to get it all worked out.
So, the solution holds 3 different columns: Original Data (column A), Help Column (column B) and Final Result (column C).
In the Help Column, I did as suggested, in cell B2 and copied down:
=IF(A2="","",IF((COUNTIF(B$1:B1,A2)>0)+(A2=A1),B1+1,A2))
This would occassionally create results over 100, so in the Final Column I placed the following array formula, which incidentally also accounts for lists longer than 100 entries, in C2 and copied down:
=IF(B2="","",IF(ROW(C2)>101,ROW(C2),IF(AND(B2>=100,B3=""),100,IF($B2:$B$1000>=C3,C3-1,B2))))
As an array formula, this needs to be entered using Ctrl+Shift+Enter.
Thank you very much to everyone who posted replies, I'm sorry for my lack of clarity!

How to get a cell reference programatically

I want to use a specific range reference programmatically to sum (next 25 cells), for which I'm using OFFSET(), which requires a cell reference. However, most lookup functions return indexes, or values, not cell references, so I have to use INDEX().
I find it a bit ridiculous that I have to do this just to find the cell reference of a cell programatically:
INDEX(A:A, MATCH(C2, A:A, 0), 1)
Is there a better way to get a cell reference programmatically?
The whole thing looks like:
=SUM(OFFSET(INDEX(A:A, MATCH(C2, A:A, 0), 1), 0, 1, 25, 1))
You will want to utilize multiple Match() and their offsets... see:
=SUM(OFFSET(A1,MATCH(C2,A:A,0)-1,0):OFFSET(A1,MATCH(C2,A:A,0)+24,0))
Broken down:
First cell in your range to sum in column 1 (A), have to subtract 1 from it so you're using your actual match reference:
OFFSET(A1,MATCH(C2,A:A,0)-1,0)
Final cell in your range to sum in column 1 (A), have to subtract 1 from the desired offset (25) similar to the first cell:
OFFSET(A1,MATCH(C2,A:A,0)+24,0)
You can then sum between the offsets
It may seem ridiculous to you but the best non-volatile option is a pair of INDEX/MATCH functions that define the start and stop of your sum range in column B and dispense of OFFSET altogether.
=sum(INDEX(B:B, MATCH(C2, A:A, 0)):INDEX(B:B, MATCH(C2, A:A, 0)+24))

Why do I get a #N/A error on some rows and others works fine

I have this formula expanding to the entire column
=IF(F2=LOOKUP(F2,NR_infra!A:A),1,0)
However I am getting a N/A in return up to row 3211. From 3212 up to the last row it works fine.
Any ideas?
I just want to add that NR_infra Sheet was imported from a CSV.
LOOKUP doesn't appear to be the best function for this. If you receive an #N/A error, that will be the result from the formula. VLOOKUP would be better with error control.
=IF(F2=IFERROR(VLOOKUP(F2, NR_infra!A:A, 1, FALSE), ""), 1, 0)
'alternate
=--isnumber(match(F2, NR_infra!A:A, 0))

Excel OFFSET and IFERROR in a table

I have a table in excel with two columns [RunningTotal] and [Change].
I have a formula like this for [RunningTotal]
=IFERROR(OFFSET([#RunningTotal];-1;0);100)+[#Change]
Its a table with two columns, one for a running total and the other for the change. The IFERROR is for the first row since it cannot be offset because there are no rows before it.
My table looks like this.
3 , #VALUE!
4 , 104
2 , 106
5 , 111
etc...
First row throws a error, the second row to reference the first row produce an error but then fallback's to the value 100 + change.
Have i done something wrong?
In fact, you are accessing the cell one above the top of the tables's data body. It is the header string value (e.g. RunningTotal) and you receive the #VALUE! error when you try to use the string mathematically with the #Change number.
However, the SUM of a string is zero so that could be checked for.
=IF(SUM(OFFSET([#RunningTotal], -1, -1, 1, 2)), OFFSET([#RunningTotal], -1, 0), 100)+[#Change]
That formula checks that the row being examined will SUM to zero for both #Change and #RunningTotal.
        
After rereading your original formula it has occurred to me that you could also use your original if you brought the +[#Change] into the error evaluation.
=IFERROR(OFFSET([#RunningTotal], -1, 0)+[#Change], 100+[#Change])

Resources