Excel - Pick out a string from a range of strings - excel

I have 2 columns of data and I need to use one to pull out one element of the other.
I have a list of addresses, where the entire address is in one cell. There is no standard format or delimiter. I need to pull out the city only into a separate cell.
I also have a list of cities that can be used as a lookup.
What I need the formula to do is look in the address cell and pull out the city, where the city is within my list in point 2.
As an example here is the first 4 rows of addresses;
42493 CLONSILLA ROAD DUBLIN 15 DUBLIN
2 Glenavey Rd Company Antrim Antrim Ireland
Tesco Wexford Road Arklow n a Wicklow Ireland
GROVE SERVICE STATION BAYLOUGH ATHLONE WESTMEATH
And an extract of the towns list;
Duagh
Dualla
Dublin
Duhallow
Duleek
For row 1, the formula needs to look through the towns and bring back Dublin.
Any ideas on this one? I'm a bit lost!

I think you'll need to use an Array Formula
=IFERROR(INDEX($D$1:$D$5,MAX(IF(ISERROR(FIND(LOWER($D$1:$D$5),LOWER(A2))),-1,1)*ROW($D$1:$D$5))-ROW($D$1)+1),"")
would work in the following example, you willl need to use Ctrl + Shift + Enter to confirm the formula as opposed to just Enter
The formula is a bit involved, I've tried to break it down below:
$D1:$D$5 - represents the cities you want to find
LOWER is used to ignore uppercase v lowercase
The FIND formula searches the text in column A for any of D1:D5,
which errors for those not found
ISERROR returns TRUE if a city isn't found and FALSE otherwise
IF converts the TRUEs (not founds) to -1 and the FALSE (found) to 1
This is then multiplied by the ROW number, and MAX selects the
maximum number, which will be the row number of the found city
INDEX then returns the name of the city based on the row number it
receives
In the case where no match is found IFERROR returns a blank

Related

Nested Xlookup First Non-blank Cells

Name Day 1 Day2 Day 3
John 3 2
John 2 1 4
Using a double Xlookup, when I'm searching for John and Day 2, I cannot get the value 1 and I'm trying Index/Xmatch/xmatch to return me 1 but no luck. Any idea to go about it?
###Updated example picture here###
enter image description here
This is my current formula
=XLOOKUP("John",$A$2:$A$3,XLOOKUP("Day 2",$B$1:$D$1,$B$2:$D$3),,2)
Note that your comments show a different case (wildcard search in names) than your question.
The following formula will result in the first found value of the wildcard search for names starting with the search string in F2 and matching the date in F3:
=LET(range,A1:D3,
c,1-COLUMNS(range),
r,1-ROWS(range),
days,TAKE(range,1,c),
names,TAKE(range,r,1),
data,TAKE(range,r,c),
x,FILTER(data,days=F3),
TAKE(
FILTER(x,
(ISNUMBER(XMATCH(F2&"*",names,2)))*
(x<>"")),
1))
You cannot use XLOOKUP two-way exact match, because it returns the first match and you have duplicated values in column Name.
This solution returns the first non blank value from the input data based on the lookup values. In cell H2 put the following formula:
=LET(colIdx, XMATCH(G3,A1:D1), tb, A2:D5, lkCol, INDEX(tb,, colIdx),
INDEX(TAKE(FILTER(tb, (A2:A5=G2) * (lkCol<>0), "Not Found"),1),colidx)
)
and here is the output:
We use LET for easier reading and composition. First we need to identify the column of our interest. The name colIdx, has the column index. Notice in order to deal with only one data range (tb), I search in all column names including Name. Now we need to identify the corresponding column values. The name lkCol represents that.
Now we have all the elements we need to filter and select the information we are looking for:
FILTER(tb, (A2:A5=G2) * (lkCol<>0), "Not Found")
The output will be the rows from tb for name G2 and filtered for non empty rows from G3 column name. The output has all the columns, now we need to select the column of our interest and only the first non empty value. TAKE extracts only the first row and INDEX the corresponding column.

Relative cell position across worksheets with IF statement

I have an Excel worksheet (Sheet 1) with a list of People's named and their responsible training groups... basically numbers assigned to different handlers.
I need to:
On Sheet 2, I need an IF statement that checks Sheet 1, Column B and if a certain person's name appears, it returns the value to the immediate left.
I have something like this on Sheet 1:
Group Name
101 Fred
102 Wilma
103 Fred
104 Fred
105 Barney
106 Wilma
On Sheet 2, I need this:
Barney Fred Wilma
105 101 102
&nbsp &nbsp103 106
&nbsp104
The equation I am trying to use in each cell on sheet 2 is"
=IF('Sheet 1'!B:B="Barney",relative position one cell to the left of name,"")
Thanks in advance.
No array formula needed:
MINIFS($A$2:$A$7,$B$2:$B$7,D$1,$A$2:$A$7,">" & MAX(D$1:D1))
Just a simple MINIFS. Then wrap it in an IF to remove the zeros:
EDIT: Further clarification in response to comment.
I have put both tables on the same sheet for ease, however, one could easily be moved onto a separate sheet if needed.
The formula works by selecting the group with the lowest value, which has the name which appears at the top of the column AND which has not already been listed.
So:
MINIFS($A$2:$A$7,$B$2:$B$7,D$1,$A$2:$A$7,">" & MAX(D$1:D1))
The first argument in the MINIFS formula is $A$2:$A$7. This is the column containing all the groups, which we want to split out and list against each name.
The 2nd and 3rd argument ($B$2:$B$7,D$1) is a criteria range and it's value. This is used to filter out any name we dont want to return in this particular cell (any that are not "Barney" in the case of D2). Notice that the D$1 in the formula does not start with a $, this means that we can just drag the formula across the other name columns and it will filter out the correct names automatically.
The 4th and 5th Arguments ($A$2:$A$7,">" & MAX(D$1:D1)) are also a criteria range and its value. Howevever, in the case of the value this time, we are looking for the max value within a range. We are looking at all the groups which have already been listed against a name and using MAX to select the highest one.Notice that there is a $ before the first "1" in the formula but not before the second. This means that as we drag the formula down, the range that it is looking for the MAX in, will automatically expand to include the cell just above the current one. Also note that there is no $before either of the "D"s, this is so that when you drag the formula to the right, the range it is checking also moves to the right. Once we have the MAX group which has already been listed against a name, we tell the MINIFS formula to only look at groups which are greater than that.
Once there are no groups for a name which are greater than the previously listed group, the MINIFS formula will return 0. To prevent the table from showing lot's of 0's, we simply say "If the MINIFS formula returns 0, then return an empty string instead:
=IF(<the result of the MINIFS>=0, "",<the result of the MINIFS>)
So the final formula would be:
=IF(MINIFS($A$2:$A$7,$B$2:$B$7,D$1,$A$2:$A$7,">" & MAX(D$1:D1))=0,"",MINIFS($A$2:$A$7,$B$2:$B$7,D$1,$A$2:$A$7,">" & MAX(D$1:D1)))
I hope that makes more sense for you. I am sorry if the explanation is a bit long winded, but as you didn't give me a specific area that you didn't understand, I just tried to expand my explanation generally. If there is any specific part you need me to explain further, please let me know.

How do I count the number of unique customers sold to, per sales person?

To get the number of customers sold to by salesperson, my guess is I could either count the number of sales orders per salesperson per unique customer (i.e. not counting more than the first sale per customer)...
Or, count the number of unique customers per salesperson, where at least one sale is present.
I have done some research but I am still not sure which formula to use and/or how to write it. Here are some examples of what I found.
Excel sumproduct with countifs
count-unique-values-in excel-with-a-contition
count-unique-values-in-excel-with-two-conditions
excel-forumla-countifs-multiple-criteria-distinct-count
Image of my Excel File
Link to my Excel Example File
The most efficient formula AFAIK is with FREQUENCY function, similar to my formula suggestion in your third link "count unique values in excel with 2 conditions" i.e. this formula in D10
=SUM(IF(FREQUENCY(IF(B$16:B$21=B10,IF(E$16:E$21>0,MATCH(C$16:C$21,C$16:C$21,0))),ROW(C$16:C$21)-ROW(C$16)+1),1))
confirmed with CTRL+SHIFT+ENTER and copied down to D11
If you want it to work with filtered data try this version
=SUM(IF(FREQUENCY(IF(B$16:B$21=B10,IF(SUBTOTAL(9,OFFSET(E$16:E$21,ROW(E$16:E$21)-ROW(E$16),0,1)),MATCH(C$16:C$21,C$16:C$21,0))),ROW(C$16:C$21)-ROW(C$16)+1),1))
Explanation:
The MATCH function is the crucial part, that will return the same relative row number for repeated values. For your data MATCH function returns the following array:
{1;2;3;3;5;6}
Notice that the repeated 3 corresponds to your repeated customer Smith
The internal IF function returns the MATCH values only for rows where B10 matches (i.e. correct salesperson) and column E > 0 (there's a sale) so for your data the above array becomes this:
{1;2;3;3;FALSE;FALSE}
The first four values are the same as above because those 4 rows match salesman and have sales value > 0, rows 5 and 6 are FALSE because one or both conditions is FALSE
So, for our unique count we need to count the number of different numbers in that array (3)
FREQUENCY does that by assigning that “data array” to the “bins array” returned by
ROW(C$16:C$21)-ROW(C$16)+1
…. which evaluates to the following: {1;2;3;4;5;6}
So when the above data array is distributed into the bins (see FREQUENCY function for help on how this happens) you get this array, finally from FREQUENCY
{1;1;2;0;0;0;0}
[bin 1 gets 1 number, bin 2 gets 1 number but bin 3 gets 2 (the 2 threes)]
Now the external IF function assigns 1 to every non-zero value in that array, and SUM sums those 1s so the result is 3
Where A contains targeted salespersons initials (can be dragged down), B contains range of all initials, and C contains range of all amounts:
=SUMIF($B$4:$B$8,$A1,$C$4:$C$8)

Sum every 11 rows excel

I have a table with 2600+ rows, related to towns in my region and their population; each town has 11 rows, one for each age class (0-9, 10-19, and so on).
I need to get the sum of the population of each town; of course I can do it manually but it's a never ending job; I wonder if there's some kind of command that tells excel to do the sum every 11 rows and do it for all the towns.
I think it's a kind of loop but I have no idea about how to do it.
The problem can be reduced by using the SUMIF function. The question then becomes how to apply this to your dataset.
Assuming one of the columns in your 2600+ rows contains the town name (or another unique identifier), and you have a list of towns (or other unique identifier), the below method can be used.
The formula in E2 is =SUMIF(A:A,D2,C:C), and in E3 =SUMIF(A:A,D3,C:C). A to C is the list of all data, D is a list of towns.
For a VBA solution, you should be able to use a step in the loop.
So if you wish to step by 11 rows at a time.
Public Sub IterateRows()
Dim rData As Range, rPtr As Range
Dim dSum As Double
Dim i As long
Set rData = Sheet1.Range("A1:A1000")
For i = 1 To rData.Rows.Count Step 11
Set rPtr = rData(1).Resize(11).Offset(i - 1)
dSum = Application.WorksheetFunction.Sum(rPtr)
Next
End Sub
If you want a worksheet function solution, you will probably have to use the MOD operator and check for when the value is zero..
You can also try this manual method which is not a never ending job; i.e.:
in E11 put your formula as =SUM(C1:C11)
copy range E1:E11
select range E12:E2600 and paste special function
Do you have any reference columns? As in...say for example Column A has the Town Name, and Column B has the Age Class, and Column C has the values.
Going down the rows Column A will have repeating town names, yes?
Like this:
Town - Age Class - Pop
Wherever - 0-9 - 1000
Wherever - 10-19 - 2000
Wheverer - 20-29 - 2500
Assuming you have maintained the data structure (NO GAPS) a possible solution in Column D (or whatever column just make sure you change the references) could be (putting this in D2 and dragging it down the length of your sheet):
=IF(A1<>A2,SUM(INDIRECT("C"&ROW(A2)&":C"&SUMPRODUCT(MAX((A:A=A2)*(ROW(A:A)))))),D1)
This works if you have any amount of rows per town, so long as you SORT by town name so the same names are next to each other in the list and there are no gaps.
In the above test data set I subtracted 250 from each Values count per Town going down (each class has 250 less than the previous city) just to show some variation in the output...you can see each city has 2750 (250 * 11) less pop than the previous.
Basically it builds an array with a starting position of "not the town above" in the first row it encounters a new town name to an ending position of "last (max) position of new town in same list" so that is how it doesn't matter how many rows you have per town. From 1 to memory limit basically, I think. :)
ALTHOUGH, this also works:
=SUMIF(A:A,A2,C:C)
Yep. Not kidding just drag that down Column D...
Assuming the following structure
This is a very easy task using a pivot table.
For LibreOffice Calc:
Just select the complete data area including the column headers (in my example: A1:C13);
Menu Data -> Pivot Table;
Current selection;
Following settings for Pivot table:
(drag the Town field into the Row Fiels area, and the Count field into the Data fields area. LO Calc will offer to calculate the Sum of the count entries by default).
Hit OK - the resulting pivot table will look like this:
This solution has the advantage that the source data area hasn't to be sorted by town, and it doesn't matter if some towns don't have nine value rows each. Additionally, you don't need any formulas.
EDIT:
You can work with the contents of the pivot table the same way as with calculated results. For example, you could use the pivot table values to calculate the sum for some of the towns (in my example, calculate the sum for town B and C based on the pivot table values B3 and B4 respectively):
You could do this with the MOD function, which gives the remainder of division. You could look at each row number and if its MOD of 11 equals zero, then it's the row you're looking for.
I am counting 10 items in each section in your example so I'm not sure I completely understand. Let's assume you need to sum every row that ends in a 9 (A9, A19, A29, etc.). You can replace the 9's below with an 11.
=ROW(A9) gets you the row number.
=MOD(ROW(A9),9) gets you a TRUE or false on weather that number is divisible by 9. If it is a multiple of 9, it will return the number 0.
Now use the SUM function and hit CONTROL+SHIFT+ENTER to complete it. Note that the formula bar indicates that this is an array function by using curly braces. You don't need to type those in yourself.
{=SUM(A1:A9*(MOD(ROW(A1:A9),9)=0))}

Excel: Copy cell info based on string match from another sheet

This is sort of a complex worded question, but I have created a sign-up sheet for my dorm's intramural teams, and the responses are listed on an Excel sheet with:
Sheet 1, cell B: Full Name
Sheet 1, cell C: Email Address
Sheet 1, cell E: The sports they wish to play on (there are four)
On sheet 2, I want to organize who and how many people want to play on each team. So I have a column for each sport, and under those are two columns (Full name and email address).
What I want to do is to parse through Sheet 1, cell E for each person who signed up, and if they have the instance of one of the four sports listed (Soccer, Dodgeball, Volleyball, or Bowling), add their Full name and email address under the correct column in sheet 2.
This is an image of sheet 2.
Is there a way/formula to be able to do this? Also, if the person signed up for multiple sports, they should be listed under each one. All the sports they want to play will be listed under a single cell (Sheet 1, cell E).
There is a way, with an array formula (entered with Ctrl+Shift+Enter)... In cell A3:
=IFERROR(INDEX(Sheet1!$B$1:$B$500,SMALL(IF(ISERROR(SEARCH(A$1,Sheet1!$E$1:$E$500)),9999,ROW(Sheet1!$A$1:$A$500)),ROW()-2)),"")
Let me explain from the inside out...
ISERROR(SEARCH(A$1,Sheet1!E10)) would give us FALSE if the value in E10 has the name of the sport (in our header cell: A$1), TRUE otherwise
Rather than just giving a single value, we are working on the array of cells Sheet1!$E$1:$E$500 (which could be extended as you needed) - so this gives us an array of TRUE and FALSE values
IF(ISERROR(...),9999,ROW(...)) means that if there was not the sport we will get the value 9999, otherwise we get the row number of the cell in the array - so this gives us an array of a mix of 9999 and row numbers
SMALL(...,ROW()-2) lets us pick out one of those values from the array - in this case the items in size order, and we are using ROW()-2 as our counter (i.e. in Sheet2!A3 - ROW()-2 is 1 and we get the smallest value from the array)... the -2 deals with the header rows... Effectively we are indexing through a sorted list of row numbers in Sheet1 that match our condition
INDEX(Sheet1!$B$1:$B$500,...) is going to give us the value from column B in Sheet1 relating to our position in the list of matching rows - i.e. the Name
Sometimes we have our 9999 (for all the cells that didn't match the condition - these are sorted to the end of the list with SMALL) and so the INDEX will give us an error... the index is outside the range. So we can replace it with a blank.
In cell B3 we would do the same, but with =IFERROR(INDEX(Sheet1!$C$1:$C$500,... so that we get the email... We still need to reference A$1 for the sport name. These two cells can then be copied across and down...
Hope this makes some sense! Good luck! And remember to enter array formulas with Ctrl+Shift+Enter...

Resources