Related
I'm using the following formula to extract the number preceding an "x" from a string (e.g. ##x## where # equals a number 0-9) but with I have other words in the string that have an "x" in them, the formula doesn't work.
Here's the formula:
=IF(ISBLANK(A154),"",IFERROR(IF(VALUE(MID(A154,MIN(FIND({"1","2","3","4","5","6","7","8","9","0"},A154 & "(1,2,3,4,5,6,7,8,9,0")),FIND(INDEX(SET_TERMS,MATCH(1,COUNTIF(A154,"*"&$R$2:$R$5&"*"),0)),A154,1)-MIN(FIND({"1","2","3","4","5","6","7","8","9","0"},A154 & "(1,2,3,4,5,6,7,8,9,0"))))<=1,"",TRIM(MID(A154,MIN(FIND({"1","2","3","4","5","6","7","8","9","0"},A154 & "(1,2,3,4,5,6,7,8,9,0")),FIND(INDEX(SET_TERMS,MATCH(1,COUNTIF(A154,"*"&$R$2:$R$5&"*"),0)),A154,1)-MIN(FIND({"1","2","3","4","5","6","7","8","9","0"},A154 & "(1,2,3,4,5,6,7,8,9,0")))&" sets")),""))
Notes: SET_TERMS ($R$2:$R$5) is a list: rounds, set, sets, x.
Here are examples where the formula works fine:
Skater jumps 3x5 each side RESULT 3 sets
Russian Twist 3x30 seconds RESULT 3 sets
Push-ups 3x max RESULT 3 sets
Y holds 3x30 seconds RESULT 3 sets
Now, here are two examples of the strings that return a blank because Flexion and Extension have "x" in them:
Neck Flexion 3x20 seconds RESULT Blank
Neck Extension 3x20 seconds Result Blank
Any ideas on how to fix this?
Thanks
You just need to be more specific in what you are looking for.
For example, the following will return the digit prior to the x:
=MID(A1,MIN(FIND({0;1;2;3;4;5;6;7;8;9}&"x",A1&"0x1x2x3x4x5x6x7x8x9x")),1)
If you have Windows Excel 2013+ or O365, and you need to deal with multiple digit numbers, the following will extract space-separated "nodes" that have the pattern of ddx, where dd can be any number (including decimals). You can then use string functions to extract just the number.
=FILTERXML("<t><s>" & SUBSTITUTE(A1," ","</s><s>") & "</s></t>","//s[boolean(number(substring-before(.,'x')))]")
I am creating a Product Decoder for a project.
Lets say, Our product can have a code such as "ABCDE" OR a code like "BCDEF".
ABCDE has a table of data that I use to decode using a lookup. For example AB can decode into "Potato" and CDE can decode into "Chip". So any combination with AB can be Potato "Anything else".
BCDER, BC can decode into "Veggie" so DER can code into "Chip".
I also use the 1/search method to take placements for the decode. Example =IFERROR(LOOKUP(2,1/SEARCH($E$19:$E$23,N18),$E$19:$E$23), "")
I concatenate all the decodes using =S2&" "&T2&" "&U2&" "&V2
Question is...if we are getting a huge amount of product code coming that I want to decode into one single column... How do I tell excel to use this table of data for ABCDE if product starts with "A", if not, use table of data that correlates to BCDER when product starts with "B".
Edit 1:
Here is my table, right side is where i look up the Part Number column N"
As you can see on column "W" I concatenate the date is Look up from columns O~V.
Column O Function: =IFERROR(LOOKUP(2,1/SEARCH($C$1:$C$7,N2),$C$1:$C$7), "")
On column N, I have two parts. One that starts with M and one that starts with K which is pretty standard.
Image two is me trying to use the IF Left but, it doesn't really work
=IF(LEFT(AA4,10) = "M ", W2, W18)
So How can I tell my excel page to use Table A1:A12 if part starts with "M*" and vice versa?
Let me know if this is confusing, I will do my best to clear things up.
First, a possible correction
I think this function does not give you what you say it does:
= IFERROR(LOOKUP(2,1/SEARCH($E$19:$E$23,N18),$E$19:$E$23), "")
You might mean:
= IFERROR( LOOKUP( 2, 1/SEARCH( $E$19:$E$23, N18 ), $F$19:$F$23 ), "" )
Because you want to look up the value in column E and return the value in column F. If that's not true, then skip the rest of this answer.
Now the solution
What you're trying to do is change the lookup array if the part number starts with a different letter. So, the IF( LEFT( combo mentioned by #BigBen should be used to modify the lookup array. I think it would look like this:
= IFERROR( LOOKUP( 2
,1/SEARCH( IF( LEFT( AA4, 1 ) = "M"
,$C$2:$C$12
,$C$19:$C$23 )
,N2 )
,IF( LEFT( AA4, 1 ) = "M"
,$D$2:$D$12
,$D$19:$D$23 )
)
,"")
Say I have columns
/670 - White | /650 - black | /680 - Red | /800 - Whitest
These have data in their rows. Basically, I want to SUM their values together if their headers contain my desired string.
For modularity's sake, I wanted to merely specify to sum /670, /650, and /680 without having to mention the rest of the header text.
So, something like =SUMIF(a1:c1; "/NUM & /NUM & /NUM"; a2:c2)
That doesn't work, and honestly I don't know what i should be looking for.
Additional stuff:
I'm trying to think of the answer myself, is it possible to mention the header text as condition for ifs? Like: if A2="/650 - Black" then proceed to sum the next header. Is this possible?
Possibility it would not involve VBA, a draggable formula would be preferable!
At this point, I may as well request a version which handles the complete header name rather than just a part of it as I believe it to be difficult for formula code alone.
Thanks for having a look!
Let me know if I need to elaborate.
EDIT: In regards to data samples, any positive number will do actually, damn shame stack overflow doesn't support table markdown. Anyway, for example then..:
+-------------+-------------+-------------+-------------+-------------+
| A | B | C | D | E |
+---+-------------+-------------+-------------+-------------+-------------+
| 1 |/650 - Black |/670 - White |/800 - White |/680 - Red |/650 - Black |
+---+-------------+-------------+-------------+-------------+-------------+
| 2 | 250 | 400 | 100 | 300 | 125 |
+---+-------------+-------------+-------------+-------------+-------------+
I should have clarified:
The number range for these headers would go from /100 - /9999 and no more than that.
EDIT:
Progress so far:
https://docs.google.com/spreadsheets/d/1GiJKFcPWzG5bDsNt93eG7WS_M5uuVk9cvkt2VGSbpxY/edit?usp=sharing
Formula:
=SUMPRODUCT((A2:D2*
(MID($A$1:$D$1,2,4)=IF(LEN($H$1)=4,$H$1&"",$H$1&" ")))+(A2:D2*
(MID($A$1:$D$1,2,4)=IF(LEN($I$1)=4,$I$1&"",$I$1&" ")))+(A2:D2*
(MID($A$1:$D$1,2,4)=IF(LEN($J$1)=4,$J$1&"",$J$1&" "))))
Apparently, each MID function is returning false with each F9 calculation.
EDIT EDIT:
Okay! I found my issue, it's the /being read when you ALSO mentioned that it wasn't required. Man, I should stop skimming!
Final Edit:
=SUMPRODUCT((RETURNSUM*
(MID(HEADER,2,4)=IF(LEN(Match5)=4,Match5&"",Match5&" ")))+(RETURNSUM*
(MID(HEADER,2,4)=IF(LEN(Match6)=4,Match6&"",Match6&" ")))+(RETURNSUM*
(MID(HEADER,2,4)=IF(LEN(Match7)=4,Match7&"",Match7&" ")))
The idea is that Header and RETURNSUM will become match criteria like the matches written above, that way it would be easier to punch new criterion into the search table. As of the moment, it doesn't support multiple rows/dragging.
I have knocked up a couple of formulas that will achieve what you are looking for. For ease I have made the search input require the number only as pressing / does not automatically type into the formula bar. I apologise for the length of the answer, I got a little carried away with the explanation.
I have set this up for 3 criteria located in J1, K1 and L1.
Here is the output I achieved:
Formula 1 - SUMPRODUCT():
=SUMPRODUCT((A4:G4*(MID($A$1:$G$1,2,4)=IF(LEN($J$1)=4,$J$1&"",$J$1&" ")))+(A4:G4*(MID($A$1:$G$1,2,4)=IF(LEN($K$1)=4,$K$1&"",$K$1&" ")))+(A4:G4*(MID($A$1:$G$1,2,4)=IF(LEN($L$1)=4,$L$1&"",$L$1&" "))))
Sumproduct(array1,[array2]) behaves as an array formula without needed to be entered as one. Array formulas break down ranges and calculate them cell by cell (in this example we are using single rows so the formula will assess columns seperately).
(A4:G4*(MID($A$1:$G$1,2,4)=IF(LEN($J$1)=4,$J$1&"",$J$1&" ")))
Essentially I have broken the Sumproduct() formula into 3 identical parts - 1 for each search condition. (A4:G4*: Now, as the formula behaves like an array, we will multiply each individual cell by either 1 or 0 and add the results together.
1 is produced when the next part of the formula is true and 0 for when it is false (default numeric values for TRUE/FALSE).
(MID($A$1:$G$1,2,4)=IF(LEN($J$1)=4,$J$1&"",$J$1&" "))
MID(text,start_num,num_chars) is being used here to assess the 4 digits after the "/" and see whether they match with the number in the 3 cells that we are searching from (in this case the first one: J1). Again, as SUMPRODUCT() works very much like an array formula, each cell in the range will be assessed individually.
I have then used the IF(logical_test,[value_if_true],[value_if_false]) to check the length of the number that I am searching. As we are searching for a 4 digit text string, if the number is 4 digits then add nothing ("") to force it to a text string and if it is not (as it will have to be 3 digits) add 1 space to the end (" ") again forcing it to become a text string.
The formula will then perform the calculation like so:
The MID() formula produces the array: {"650 ","670 ","800 ","680 ","977 ","9999","143 "}. This combined with the first search produces {TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE} which when multiplied by A4:G4
(remember 0 for false and 1 for true) produces this array: {250,0,0,0,0,0,0} essentially pulling the desired result ready to be summed together.
Formula 2: =SUM(IF(Array)): [This formula does not work for 3 digit numbers as they will exist within the 4 digit numbers! I have included it for educational purposes only]
=SUM(IF(ISNUMBER(SEARCH($J$1,$A$1:$G$1)),A8:G8),IF(ISNUMBER(SEARCH($K$1,$A$1:$G$1)),A8:G8),IF(ISNUMBER(SEARCH($L$1,$A$1:$G$1)),A8:G8))
The formula will need to be entered as an array (once copy and pasted while still in the formula bar hit CTRL+SHIFT+ENTER)
This formula works in a similar way, SUM() will add together the array values produced where IF(ISNUMBER(SEARCH() columns match the result column.
SEARCH() will return a number when it finds the exact characters in a cell which represents it's position in number of characters. By using ISNUMBER() I am avoiding having to do the whole MID() and IF(LEN()=4,""," ") I used in the previous formula as TRUE/FALSE will be produced when a match is found regardless of it's position or cell formatting.
As previously mentioned, this poses a problem as 999 can be found within 9999 etc.
The resulting array for the first part is: {250,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE} (if you would like to see the array you can highlight that part of the formula and calculate with F9 but be sure to highlight the exact brackets for that part of the formula).
I hope I have explained this well, feel free to ask any questions about stuff that you don't understand. It is good to see people keen to learn and not just fishing for a fast answer. I would be more than happy to help and explain in more depth.
I start this solution with the names in an array, you can read the header names into an array with not too much difficulty.
Sub test()
Dim myArray(1 To 4) As String
myArray(1) = "/670 - White"
myArray(2) = "/650 - black"
myArray(3) = "/680 - Red"
myArray(4) = "/800 - Whitest"
For Each ArrayValue In myArray
'Find position of last character
endposition = InStr(1, ArrayValue, " - ", vbTextCompare)
'Grab the number section from the string, based on starting and ending positions
stringvalue = Mid(ArrayValue, 2, endposition - 2)
'Convert to number
NumberValue = CLng(stringvalue)
'Add to total
Total = Total + NumberValue
Next ArrayValue
'Print total
Debug.Print Total
End Sub
This will print the answer to the debug window.
Basically I have a long list of IDs (over 900) formatted as follows (example):
1.1.1
etc
I'd want this to display as:
01.01.01
How do I add the 0s without messing up requirement numbers like 10.10.10 (I don't want this to display as 010.010.010 for example).
This may be a simple one hopefully! Basically just want to add a leading 0 when the number is less than 10.
Cheers
Suppose your List of IDs in Column A is as follows
1.1.1
2.2.2
1.3.1
1.2.3
1.10.1
1.1.10
10.1.1
10.1.10
10.10.10
1.10.10
Simple Excel solution would be to
1 - Select the range in Column A. Go to Data --> Text to Columns --> Delimited --> Other --> Put . as delim text. This will divide your Column A data into 3 Columns as shown below
2 - In D1, enter =TEXT(A1,"00"). Drag and fill D1:F10
3 - Enter . in G1 and then drag and fill till G10
4 - In H1, enter =CONCATENATE(D1,G1,E1,G1,F1) and drag and fill till H10 and voilà !
VBA solution would be
Sub vbaSol()
For Each dataCell In Range("A1:A10")
splitData = Split(dataCell.Value, ".")
For i = 0 To UBound(splitData)
If CInt(splitData(i)) < 10 Then splitData(i) = "0" & CStr(splitData(i))
Next i
dataCell.Value = Join(splitData, ".")
Next dataCell
End Sub
Tackle it in 3 parts, and then concatenate the answer. For the left third, use the FIND() function to locate the first dot/period inside the LEFT() function inside the TEXT() function as so: TEXT(LEFT(A1,FIND(".",A1)-1),"00.") This will give you 01.->10.
For the right third, use the FIND() function with its optional 3rd argument to specify where to start looking for the dot. The 2nd dot can be no earlier than the 4th character. Subtract the FIND() from the length LEN() function, inside the RIGHT() function inside the TEXT() function as so: TEXT(RIGHT(A1,LEN(A1)-FIND(".",A1,4)),"00") This gives you 01->10.
For the middle third, use the MID() function with a combination of FIND() functions to get your numbers. It's more complicated, but looks like this:
TEXT(MID(A1,FIND(".",A1)+1,FIND(".",A1,FIND(".",A1)+1)-FIND(".",A1)),"00.")
Get the middle of A1 from 1 character past the first dot to a length of "find the second dot minus find the first dot." Turn it into text.
All together, looks like this:
=TEXT(LEFT(A1,FIND(".",A1)-1),"00.")&TEXT(MID(A1,FIND(".",A1)+1,FIND(".",A1,FIND(".",A1)+1)-FIND(".",A1)),"00.")&TEXT(RIGHT(A1,LEN(A1)-FIND(".",A1,4)),"00")
How to compare two sheet columns specied below, however only part of string in location(column)in sheet1 will matches only part of string with the Location(column) in sheet2?
1.only 1st two characters of location(column) in sheet1 and 1st two characters of location(column) in sheet2 should match.
2.only any two characters of location(column) in sheet1 and any two characters of location(column) in sheet2 should match. Please help
Location(sheet1) Location(sheet2)
____________________________________________
india- north USxcs
India-west Indiaasd
India- east Indiaavvds
India- south Africassdcasv
US- north Africavasvdsa
us-west UKsacvavsdv
uk- east Indiacascsa
uk- south UScssca
Africa-middle Indiacsasca
Africa-south Africaccc
Africa-east UKcac
For question 1 you can use MID function to extract the first two characters from each cell value and compare them.
For question 2 there is a solution if you can accept a predetermined maximum length of string. It is not a very nice solution! You can use nested if statements, basically 'unrolling the loop'. This example compares cell A1 and B1 for lengths of A1 up to 12 characters:
=IF(IFERROR(FIND(MID(A1,1,2),B1,1),0)>0,TRUE,
IF(IFERROR(FIND(MID(A1,2,2),B1,1),0)>0,TRUE,
IF(IFERROR(FIND(MID(A1,3,2),B1,1),0)>0,TRUE,
IF(IFERROR(FIND(MID(A1,4,2),B1,1),0)>0,TRUE,
IF(IFERROR(FIND(MID(A1,5,2),B1,1),0)>0,TRUE,
IF(IFERROR(FIND(MID(A1,6,2),B1,1),0)>0,TRUE,
IF(IFERROR(FIND(MID(A1,7,2),B1,1),0)>0,TRUE,
IF(IFERROR(FIND(MID(A1,8,2),B1,1),0)>0,TRUE,
IF(IFERROR(FIND(MID(A1,9,2),B1,1),0)>0,TRUE,
IF(IFERROR(FIND(MID(A1,10,2),B1,1),0)>0,TRUE,
IF(IFERROR(FIND(MID(A1,11,2),B1,1),0)>0,TRUE,
FALSE
)
)
)
)
)
)
)
)
)
)
)
Thanks to James Jenkins for this update
It seems older versions of Excel have a limit of 7 nested functions. You can work around this (if you don't mind making your spreadsheet even more ugly) by chaining together formulas in adjacent cells. In fact if you wanted to get really creative you could use the column index to calculate the offsets for the search, something like:
=IF(IFERROR(FIND(MID($A1,(COLUMN(C1) - 3) * 6 + 1, 2), $B1, 1),0)>0,TRUE,
...repeat with +2, +3, +4, +5
if(D2 = FALSE, FALSE, TRUE)
)))))))
Then the column can be copied right if you ever need more string length. Note the innermost 'if' should force a TRUE or FALSE value when the adjacent column is blank.