Use cell X3 in function with lookup - excel

Hey guys I have a bunch of strings in a column and I am getting the row number of the last string by using the following:
=MATCH(REPT("z",255),StaticData!G:G)
It gives me a number 256 and it is in cell X3.
I am using a lookup and I would like to specify this number in cell X3:
=IFERROR(VLOOKUP(A2,Sheet1!$C$4:$D$256,2,0),"")
Where the 260 is right now I would like to place X3 but it is giving me errors.
So like:
=IFERROR(VLOOKUP(A2,Sheet1!$C$4:$D$X3,2,0),"")
Anyone know how I can do this? Thanks!

You are looking for Offset:
=IFERROR(VLOOKUP(A2,Sheet1!$C$4:OFFSET($D$1,$X$3-1,0),2,0),"")

In most cases INDEX is preferable to OFFSET because OFFSET is a volatile function - try this version
=IFERROR(VLOOKUP(A2,Sheet1!$C$4:INDEX(Sheet1!$D:$D,$X$3),2,0),"")

Related

Counting if part of string is within interval

I am currently trying to check if a number in a comma-separated string is within a number interval. What I am trying to do is to check if an area code (from the comma-separated string) is within the interval of an area.
The data:
AREAS
Area interval
Name
Number of locations
1000-1499
Area 1
?
1500-1799
Area 2
?
1800-1999
Area 3
?
GEOLOCATIONS
Name
Areas List
Location A
1200, 1400
Location B
1020, 1720
Location C
1700, 1920
Location D
1940, 1950, 1730
The result I want here is the number of unique locations in the "Areas list" within the area interval. So Location D should only count ONCE in the 1800-1999 "area", and the Location A the same in the 1000-1499 location. But location B should count as one in both 1000-1499 and one in 1500-1799 (because a number from each interval is in the comma-separated string in "Areas list"):
Area interval
Name
Number of locations
1000-1499
Area 1
2
1500-1799
Area 2
3
1800-1999
Area 3
2
How is this possible?
I have tried with a COUNTIFS, but it doesnt seem to do the job.
Here is one option using FILTERXML():
Formula in C2:
=SUM(FILTERXML("<x><t>"&TEXTJOIN("</s></t><t>",,"1<s>"&SUBSTITUTE(B$7:B$10,", ","</s><s>"))&"</s></t></x>","//t[count(.//*[.>="&SUBSTITUTE(A2,"-","][.<=")&"])>0]"))
Where:
"<x><t>"&TEXTJOIN("</s></t><t>",,"1<s>"&SUBSTITUTE(B$7:B$10,", ","</s><s>"))&"</s></t></x>" - Is the part where we construct a valid piece of XML. The theory here is that we use three axes here. Each t-node will be named a literal 1 to make sure that once we return them with xpath we can sum the result. The outer x-nodes are there to make sure Excel will handle the inner axes correctly. If you are curious to know how this xml-syntax looks at the end, it's best to step through using the 'Evaluate Formula' function on the Data-tab;
//t[count(.//*[.>="&SUBSTITUTE(A2,"-","][.<=")&"])>0]")) - Basically means that we collect all t-nodes where the count of child s-nodes that are >= to the leftmost number and <= to the rightmost number is larger than zero. For A2 the xpath would look like //t[count(.//*[.>=1000][.<=1499])>0]")) after substitution. In short: //t - Select t-nodes, where count(.//* select all child-nodes where count of nodes that fullfill both requirements [.>=1000][.<=1499] is larger than zero;
Since all t-nodes equal the number 1, the SUM() of these t-nodes equals the amount of unique locations that have at least one area in its Areas List;
Important to note that FILTERXML() will result into an error if no t-nodes could be found. That would mean we need to wrap the FILTERXML() in an IFERROR(...., 0) to counter that and make the SUM() still work correctly.
Or, wrap the above in BYROW():
Formula in C2:
=BYROW(A2:A4,LAMBDA(a,SUM(FILTERXML("<x><t>"&TEXTJOIN("</s></t><t>",,"1<s>"&SUBSTITUTE(B$7:B$10,", ","</s><s>"))&"</s></t></x>","//t[count(.//*[.>="&SUBSTITUTE(a,"-","][.<=")&"])>0]"))))
Using MMULT and TEXTSPLIT:
=LET(rng,TEXTSPLIT(D2,"-"),
tarr,IFERROR(--TRIM(TEXTSPLIT(TEXTJOIN(";",,$B$2:$B$5),",",";")),0),
SUM(--(MMULT((tarr>=--TAKE(rng,,1))*(tarr<=--TAKE(rng,,-1)),SEQUENCE(COLUMNS(tarr),,1,0))>0)))
I am in very distinguished company but will add my version anyway as byrow probably is a slightly different approach
=LET(range,B$2:B$5,
lowerLimit,--#TEXTSPLIT(E2,"-"),
upperLimit,--INDEX(TEXTSPLIT(E2,"-"),2),
counts,BYROW(range,LAMBDA(r,SUM((--TEXTSPLIT(r,",")>=lowerLimit)*(--TEXTSPLIT(r,",")<=upperLimit)))),
SUM(--(counts>0))
)
Here the ugly way to do it, with A LOT of helper columns. But not so complicated 🙂
F4= =TRANSPOSE(FILTERXML("<m><r>"&SUBSTITUTE(B4;",";"</r><r>")&"</r></m>";"//r"))
F11= =TRANSPOSE(FILTERXML("<m><r>"&SUBSTITUTE(A11;"-";"</r><r>")&"</r></m>";"//r"))
F16= =SUM(F18:F21)
F18= =IF(SUM(($F4:$O4>=$F$11)*($F4:$O4<=$G$11))>0;1;"")
G18= =IF(SUM(($F4:$O4>=$F$12)*($F4:$O4<=$G$12))>0;1;"")
H18= =IF(SUM(($F4:$O4>=$F$13)*($F4:$O4<=$G$13))>0;1;"")

Complicated counting in excel

I have the following columns in Excel
a b c
1 SUM 1st 2nd
2 0 2/2 2/4
3 0 1/1 3/4
b2 is defined as "=CONCATENATE(TRUNC(2);"/";TEXT(('Other sheet'!B2);0))"
and similar to b3,c2,c3.
Column |SUM| should count sum from |1st| to |2nd| but only the first numbers before "/".
for example: b2+c3+... = 2+2+... = 4+... so a2=4+...
any ideas how to do that? :)
Use the below formula with feature shift+ctrl+enter:
=SUM(TRUNC(MID(B2:C2,1,SEARCH("/",B2:C2,1)-1)))
You can use the 'left' function
Use it like this
A2=left(B2;1)+left(C2;1)
Here's a simple way to do it
=SUMPRODUCT(INT(SUBSTITUTE(B2:C2,"/",".")))
Extend your range as far as you need by changing B2:C2 to B2:X2, for example.
I think this might work for your system.
=SUMA.ILOCZYNÓW(ZAOKR.DO.CAŁK(PODSTAW(B2:C2;"/";".")))

How do I constrain a value to a range in excel?

In C++ I would use boost::clamp for this. Basically I have some excel function
A1*B2+C3+D4
I want to do constrain it to +/- some number, call it X1. The obvious way is this:
MAX(-X1, MIN(X1, A1*B2+C3+D4))
But I want to be able to do this:
CLAMP(A1*B2+C3+D4, -X1, X1)
Does this or something similar exist? I'm just curious - obviously the workaround works, it's just ugly.
This can be done using MEDIAN. MEDIAN picks the middle of the three values, thus effectively restricting the lower and upper limits.
For example say your minimum is 5 and your maximum is 10:
=MEDIAN(5,0,10) is 5
=MEDIAN(5,7,10) is 7
=MEDIAN(5,12,10) is 10
With spreadsheet formulas I don't think that you can do much better than that min/max construct. You could write clamp in VBA:
Function clamp(x As Double, lower As Double, upper As Double) As Double
If x < lower Then
clamp = lower
ElseIf x > upper Then
clamp = upper
Else
clamp = x
End If
End Function
If you enter that in a standard code module then you could e.g. do something like this:
In column A I have values in the range 0 to 2*pi. In C2 I have the value 0.5. In B1 I entered
=clamp(SIN(A1),-$C$2,$C$2)
and copied down. The graph shows the result.
(Since I gave a VBA solution I'll add the Excel-VBA tag. Even if you prefer a non-VBA solution, it is possible that others in the future might search the question and be comfortable with a VBA solution).

Why does my Excel function have too many arguments?

Can anyone tell me what is wrong with this function? Thanks so greatly!!
=IF(B4<7500, "POOR",IF(B4<10000, "GOOD","GREAT",IF(B4>12500,"EXCELLENT"))
Here you go:
=if(B4 < 7500, "POOR", if(B4 < 10000, "GOOD", if(B4 < 12500, "GREAT", "EXCELLENT")))
Note, this assumes that your B4 values are numbers, so you can add error handling if needed.
You could use a lookup function instead of nested IFs. Either store the values in a table in a spreadsheet (easy to maintain) or write the value pairs into the formula:
=LOOKUP(B4,{0,7500,10000,12500},{"poor","good","great","excellent"})

Extracting decimal numbers from a string in Excel

I've tried lots of searches for this but I'm still not coming up with anything that works.
I have a range of strings in Column A
Amend.Clause_1.1.AddMCQ
Amend.Clause_1.1.AddNo
Amend.Clause_1.1.AddRepeat
Amend.Clause_1.13.AddRepeat
Amend.Clause_1.13.AddTitle
Amend.Clause_1.13.AddUTQ
Amend.Clause_2.8.Heading_Edit
Amend.Clause_2.8.MCQ
Amend.Clause_2.8.Remove
Amend.Clause_4.26.AddUTQ
Amend.Clause_4.26.Heading_Edit
Amend.Clause_4.26.MCQ
Amend.Clause_5.15.AddMCQ
Amend.Clause_5.15.AddNo
Amend.Clause_5.15.AddRepeat
As you can see, the numbers always start in the same place, after the underscore "_" at position 13.
I need to extract the decimal numbers from these strings into a new column so I'm left with 1.1, 1.13, 1.14, 4.26 etc.
I've tried all sorts of combos of MID, LEFT, LEN, RIGHT but to no avail, trying to find the position of the last period.
Could anyone explain how to accomplish this? Ideally I'd like to do this without VBA.
Thanks
Here you are:
=VALUE(MID(A1,SEARCH("_",A1)+1,SEARCH(".",A1,SEARCH(".",A1,SEARCH("_",A1)+1)+1)-(SEARCH("_",A1)+1)))
Here's what inside =VALUE(MID(...)):
A1 - the whole string itself
SEARCH("_",A1)+1 - find the number starting position - right after "_".
SEARCH(".",A1,SEARCH(".",A1,SEARCH("_",A1)+1)+1)-(SEARCH("_",A1)+1) - find number length - position of second "." after first "." minus number starting position.
Try with three functions:
=MID(A1,14,FIND("#",SUBSTITUTE(A1,".","#",3))-14)
Try this - If the position of _ is not necessarily 13.
=MID(A1,FIND("_",A1,1)+1,FIND("¬¬",SUBSTITUTE(A1,".","¬¬",LEN(A1)-LEN(SUBSTITUTE(A1,".",""))))-FIND("_",A1,1)-1)
Or this if the _ is always 13
=MID(A1,14,FIND("¬¬",SUBSTITUTE(A1,".","¬¬",LEN(A1)-LEN(SUBSTITUTE(A1,".",""))))-14)
Use This:
=VALUE(TRIM(LEFT(SUBSTITUTE(RIGHT(A1;LEN(A1)-FIND("_";A1));".";REPT(" ";LEN(A1));2);LEN(A1))))
assuming value is in A1
Far from ideal, but with a shorter formula than the solutions offered so far:
=SUBSTITUTE(A1,".","_",3)
Catch is that formulae would then need to be converted to values, parsed with delimiter _ (being careful to ensure Column data format is Text) and surplus columns deleted.
When the string Amend.Clause_1.1.AddMCQ is in A1
=Find(".",A1,Find(".",A1)+1)
will give the position of the second decimal point, then you should be able to extract the decimal number.
The syntax is
FIND(find_text, within_text, [start_num])

Resources