Matching, splitting, converting and summing string in Excel / Numbers - excel

I'm trying to do a match-and-calculate formula in Excel (or in Numbers for Mac, is the same for me: I try them both as they seem equal, also function names are equal!).
This is what I have:
| 1 | 2 | 3 |
|-----------+-----------+-----------|
| Category |other stuff| duration |
|-----------+-----------+-----------|
| A + .... ... + 00:01:23 |
|-----------+-----------+-----------|
| A + .... ... + 00:30:19 |
|-----------+-----------+-----------|
| B + ......... + ......... |
|-----------+-----------+-----------|
| A + .... ... + 00:22:12 |
... ... ....
So, in column 3 I have a duration in time in this format "hh:mm:ss" and in column 1 are stored all of my categories.
I want to search for all rows in my table that are matching with the category "A" in column 1 and take the relative column 3, splitting the string and converting chars to numbers (in particular I'm interested in converting them to secs, so hh*3600+mm*60+ss) and finally sum up all these values. Is it possible?
I'm new with Excel and Numbers, but I'm pretty familiar with coding in programming languages generally: this is what I'd do in programming:
global_secs=0;
for(row r=top to end){
if(r.get_column(1).content_equals("A")){
cell c=r.get_column(3);
string=split(c.get_content(),":")
global_secs+=int(string[1])*3600+int(string[2])*60+int(string[3])
}
}
Is there a way to achieve this in Excel sheet (or Numbers)?
I'd like to do all of this in one, or more, formula only in Excel or Numbers.
One more thing: I do not want to change cells format because this should be an automatic process without human interaction, so unless there is a function to change a range of cells format dynamically I prefer not to do that (I know I can make "duration" as format and sum up without converting to integer, but originally my data is in hh:mm:ss format)
Thanks so much!

The formula you are looking for is
=SUMIF(A2:A5,"A",C2:C5)
The easiest way to get the result in seconds would have been to format the cell as [ss] in Custom category. But as you don't want to do formatting , the other way could be
=HOUR(result) * 3600 + MINUTE(result) * 60 + SECOND(result)
So formula becomes
=HOUR(SUMIF(A2:A5,"A",C2:C5)) * 3600 + MINUTE(SUMIF(A2:A5,"A",C2:C5)) * 60 + SECOND(SUMIF(A2:A5,"A",C2:C5))
See image for referecne

Looks like a matrix formula
=SUM(N($A$2:$A$8="A")*$B$2:$B$8)
where column A contains the category and column C the duration. Note you need to press ctrl shift enter to make it work.
To convert the result to seconds, an alternative approach to #Mrig' solution would be to format the result and convert it back to a number, i.e.
=VALUE(TEXT(SUM(N($A$2:$A$8="A")*$B$2:$B$8),"[ss]"))

Related

Is there a way to find any one of a set of characters using an excel formula

I have data that uses a range, or a less than symbol to denote 'between 0 and number'. But multiple characters are used for the same purpose.
It looks like below (first two columns), plus a column showing the results I want:
Country
Average hotdog consumption
Desired output
Madeupaland
10-200
105
Exampledesh
50—1000
525
Republic of Notreal
<1000
500
Inventia
≤5000
2500
Plus many rows where the data in the second column is purely numerical and doesn't need finessing into a number
I can use this formula to calculate the midpoint where there is a range:
=IFERROR(AVERAGE(LEFT(C2,FIND("–",C2)-1),RIGHT(C2, LEN(C2)-FIND("–",C2))), A2)
But they only covers one kind of dash(- and not —). Similarly, if I want to halve the numbers in rows with < and ≤ I'd need to replicate a formula there.
Is there a way of finding multiple different characters from a set? My understanding is that find looks for the whole string of characters. substitute is a work around, but I'd have to substitute every different value in the 'character set'.
In regex this would just be [-—].
I'm using Excel 2013 if that matters
It's not a perfect solution but you can try the following. This replaces those patterns of text with replacements representing which formula to use:
Create a Reference Table (I have made this in I1:K5)
|Pattern |Pattern Name |Substitution Rule |
|------- |------------ |----------------- |
|— |double dash |/2+0.5* |
|- |dash |/2+0.5* |
|< |lt |0.5* |
|≤ |lte |0.5* |
In your third column enter the following array formula (Using Ctrl + Shift + Enter to confirm)
=IF(ISNUMBER(B2),B2,"'="&SUBSTITUTE(B2,INDEX($I$2:$I$5,MIN(IF(ISNUMBER(FIND($I$2:$I$5,B2)),ROW($I$2:$I$5)-1,99))),INDEX($K$2:$K$5,MIN(IF(ISNUMBER(FIND($I$2:$I$5,B2)),ROW($I$2:$I$5),99)-1))))
Copy your third column and past values into a fourth column
Replace all the ''s with nothing to evaluate the expressions using Ctrl + H
My Result:
Country
Average hotdog consumption
Desired output
Formula Paste
Output after replacing 's
Madeupaland
10-200
105
'=10/2+0.5*200
105
Exampledesh
50—1000
525
'=50/2+0.5*1000
525
Republic of Notreal
<1000
500
'=0.5*1000
500
Inventia
≤5000
2500
'=0.5*5000
2500

Excel - How to sum concatenated substrings

I've got a problem I'm trying to work out in excel, and I've only been able to find the solution to the opposite problem.
I've got a list of data in a form similar to the following:
A | 10
B | 15
C | 12
D | 17
And I want to be able to make a string of any of those strings once and get the sum. The results table would look something like this:
A | 10
A, B | 25
A, C | 22
A, C, D | 39
In all I've been able to find, I haven't been able to find a way to check if a string contains other strings as substrings, then adds an associated value to a total if that is true.
One approach, with SUMPRODUCT and SEARCH.
=SUMPRODUCT(ISNUMBER(SEARCH($A$1:$A$4,E1))*$B$1:$B$4)
Do be aware of pitfalls though when matching substrings; for example, AA in E1 would still return 10 in F1.
In addition to #BigBen, you could try in cell F1:
=SUMPRODUCT(SUMIF(A$1:A$4,FILTERXML("<t><s>"&SUBSTITUTE(E1,", ","</s><s>")&"</s></t>","//s"),B$1:B$4))
That should get rid of the possible false positives.

Excel two average formulas in one cell

I tried to find a solution for the following:
I have one row with five different cells.
For example:
cell 1 1:41:02
cell 2 1:42:00
cell 3 1:42:06
cell 4 1:41:06
cell 5 to calculate the average
The thing that I want is this. In last cell (cell 5) calculate the average times like:
Average(cell1, cell2) "some text" Average(cell3, cell4).
I've tried the following formulas:
= CONCATENATE(AVERAGE(C23;D23); " | "; AVERAGE(E23:F23))
= AVERAGE(C23;D23) & " | " & AVERAGE(E23:F23))
But on both of them I get weird times, well not even times but numbers.
0,0704976851851852 | 0,0705555555555556
Instead of what I want
1:41:34 | 1:41:36
Any ideas?
Your AVERAGE is returning a number. Use the TEXT function
=TEXT(AVERAGE(),"h:mm:ss")
Your local settings require that you use a semi-colon rather than a comma
=TEXT(AVERAGE(C23;D23);"h:mm:ss")&" | "&TEXT(AVERAGE(E23;F23);"h:mm:ss")
=CONCATENATE(TEXT(AVERAGE(C23;D23);"h:mm:ss");" | ";TEXT(AVERAGE(E23;F23);"h:mm:ss"))

Return values, based on value of an intersection of a row and column

I want to return a label(s) based on an intersection of a Row and Column equal to "Yes".
| Location |
ID | Tool | Wall | Bin | Toolbox | Count
---+--------+------+-----+---------+-------
1. | Axe | YES | | | 1
2. | Hammer | | | YES | 5
3. | Pliers | | | YES | 2
4. | Nails | | YES | | 500
5. | Hoe | YES | | | 2
6. | Screws | | YES | | 200
7. | Saw | YES | | | 3
What's in Toolbox? (Results wanted)
Axe,Wall, 1
Hammer, Toolbox, 5
Pliers,Toolbox, 2
Nails,Bin, 500
Hoe, Wall, 2
Screws, Bin, 200
Saw, Wall, 3
I also want to be able add Tools and Locations?
Without using VBA, this is going to be a bit of a pain, but workable if you don't mind helper columns. I don't advise trying to do this in a single Array Formula, because text strings are hard to work with in Array formulas. That is - if you have an array of numbers, you can turn that into a single result a lot of ways (MIN, MAX, AVERAGE, SUM, etc.). However with an array of strings, it's harder to work with. Particularly, there's no easy way to concatenate an array of strings.
So instead, use a helper column. Assume column A = toolname, column B = a check for being on the wall, column C = a check for being in the bin, column D for being in the toolbox, and column E for the number available.
FORMATTING SIDE NOTE
First, I will say that I recommend you use TRUE/FALSE instead of "yes"/"no". This is because it is easier to use TRUE / FALSE within Excel formulas. For example, if you want to add A1 + A2 when A3 = "yes", you can do so like this:
=IF(A3="yes",A1+A2)
But if you want to check whether A3 = TRUE, this is simplified:
=IF(A3,A1+A2)
Here, we didn't need to hardcode "yes", because A3 itself will either be TRUE or FALSE. Also consider if you want to make a cell "yes" if A3 > 5, and otherwise be "no". You could do it like this:
=IF(A3>5,"yes","no)
Or, if you used TRUE/FALSE, you could simply use:
=A3>5
However, I'll assume that you keep the formatting you currently have (I would also recommend you just have a single cell that says either "toolbox"/"bin" etc., instead of 4 columns where 1 says "yes", but we'll also assume that this needs to be this way).
BACK TO YOUR QUESTION
Put this in column F, in F2 for the first cell:
=Concatenate(A2," ",INDEX($B$1:$D$1,MATCH("yes",B2:D2,0))," ",E2)
Concatenate combines strings of text into a new single text string. You could also use &; like: A2 & " " etc., but with this many terms, this is likely easier to read. Index looks at your header row 1, and returns the item from the first column which matches "yes" in the current row.
Then put the following in F3 and drag down:
=Concatenate(F2," ", A2," ",INDEX($B$1:$D$1,MATCH("yes",B2:D2,0))," ",E2)
This puts a space in between the line above and the current line. If instead you want to make each row appear after a line-break, use this:
=Concatenate(F2,CHAR(10), A2," ",INDEX($B$1:$D$1,MATCH("yes",B2:D2,0))," ",E2)

Destination, prefix lookup via Phone number - Excel

I have two tables.
Table one contains: phone number list
Table Two contains: prefix and destination list
I want look up prefix and destination for phone number.
Given below Row data table and result table
Table 01 ( Phone Number List)
Phone Number
------------
12426454407
12865456546
12846546564
14415332165
14426546545
16496564654
16896546564
16413216564
Table 02 (Prefix and Destination List)
PREFIX |COUNTRY
-------+---------------------
1 |Canada_USA_Fixed
1242 |Bahamas
1246 |Barbados
1268 |Antigua
1284 |Tortola
1340 |Virgin Islands - US
1345 |Cayman Island
144153 |Bermuda-Mobile
1473 |Grenada
1649 |Turks and Caicos
1664 |Montserrat
Table 03 (Result)
Phone Number | PREFIX | COUNTRY
--------------+--------+-------------------
12426454407 | 1242 | Bahamas
12865456546 | 1 | Canada_USA_Fixed
12846546564 | 1284 | Tortola
14415332165 | 144153 | Bermuda-Mobile
14426546545 | 1 | Canada_USA_Fixed
16496564654 | 1649 | Turks and Caicos
16896546564 | 1 | Canada_USA_Fixed
16643216564 | 1664 | Montserrat
Lets assume phone numbers are in column A, now in column B you need to extract the prefix. Something like this:
=LEFT(A1, 4)
However your Canada_USA_Fixed creates problems as does the Antigua mobile. I'll let you solve this issue yourself. Start with IF statements.
Now that you have extracted the prefix you can easily use VLOOKUP() to get the country.
Assuming that the longest prefix is 6 digits long you, can add 6 columns (B:G) next to the column with the phone numbers in table 1 (I assume this is column A). In column B you'd show the first 6 characters using =LEFT(A2,6), in the next column you show 5 chars, etc.
Then you add another 6 columns (H:M) , each doing a =MATCH(B2,Table2!A:A,0) to see if this prefix is in the list of prefixes.
Now if any of the 6 potential prefixes match, you'll get the row number of the prefix - else you'll get an #N/A error. Put the following formula in column N: {=INDEX(H2:M2,MATCH(FALSE,ISERROR(H2:M2),0))} - enter the formula as an array formula, i.e. instead of pressing Enter after entering it, press Ctrl-Shift-Enter - you'll see these {} around the formula then, so don't enter those manually!.
Column N now contains the row of the matching prefix or #N/A if no prefix matches. Therefore, put =IF(ISNA(N2,'No matching prefix',INDEX(Table2!B:B,N2)) in the next column and you'll be done.
You could also the above approach with less columns but more complex formulas but I wouldn't recommend it.
I'm also doing longest prefix matches and, like everyone else that Google has turned up, it's also for international phone number prefixes!
My solution is working for my table of 200 prefixes (including world zone 1, ie. having 1 for US/Canada and 1242 for Bahamas, etc).
Firstly you need this array formula (which I'm going to call "X" in the following but you'll want to type out in full)
(LEFT(ValueToFind,LEN(PrefixArray))=PrefixArray)*LEN(PrefixArray)
This uses the trick of multiplying a logical value with an integer so the result is zero if there's no match. You use this find the maximum value in one cell (which I'm calling "MaxValue").
{=MAX(X)}
If MaxValue is more than zero (and therefore some sort of match was found), you can then find the position of the maximum value in your prefix array.
{=MATCH(MaxValue,X,0)}
I've not worried about duplicates here - you can check for them in your PrefixArray separately.
Notes for neophytes:
PrefixArray should be an absolute reference, either stated with lots of $ or as a "named range".
I'm assuming you'll make ValueToFind, MaxValue and the resultant index into PrefixArray as cells on the same row, and therefore have a $ against their column letter but not their row number. This allows easy pasting for lots of rows of ValueToFind.
Array formula are indicated by curly braces, but are entered by typing the text without the curly braces and then hitting Ctrl-Shift-Enter.

Resources