Summing the results of a lookup when the function arguments contain functions - excel

my question is pretty specific, and I haven't been able to find a solution. Here's a sample dataset that illustrates the problem:
First Last Sales Months
Kevin Smith $500 10
Joe Stevens $400 6
Frank Doe $600 4
I am looking for a solution that doesn't involve any computation columns or cells in the final result.
Now lets say I had this list
Kevin Smith
Frank Doe
I want to sum their sales/month in a separate cell.
I've tried:
=SUM(SUMIF(CONCATENATE(First, " ", Last),FullNames,Sales/Month))
Data is stored in rows 1-3 where column A is first name, Column B is last name, Column C is sales, and column D is months. The full names are in A5 and A6.
When I apply the function I have tried both Enter and Ctrl+Shift+Enter
Strangely enough, this formula works:
=SUM(SUMIF(First,FirstNameSubSet,Sales))
When I don't do any array concatenation or division in the formula.
Unfortunately, in my real life problem, I can't use this workaround.
I tried posting a picture, but even though I've been reading the answers on this site for a long time, I've never posted anything so I have no 'reputation.'
Thank you in advance for you help.

It would be a lot simpler if the full name were also in two separate cells. You could use a simple SUMIFS. But for the problem you present, if I understand it, given the following:
First is the named range containing the first names
Last is the named range containing the last names
Sales is the named range containing the Sales amounts
Month is the named range containing the number of months.
Fullnames is the named range containing the full name (combined first and last name)
Then the following array-entered formula (formula entered by holding down ctrl-shift while hitting enter) should produced the sales per month
=SUM(SUMIFS(Sales,First,LEFT(FullNames,FIND(" ",FullNames)-1),Last,MID(FullNames,FIND(" ",FullNames)+1,99)))
/SUM(SUMIFS(Months,First,LEFT(FullNames,FIND(" ",FullNames)-1),Last,MID(FullNames,FIND(" ",FullNames)+1,99)))
If you need the name comparisons to be case insensitive then change FIND to SEARCH in the formula.

Do you want the result to be all in one cell, or in one cell per row? If not, I am unsure why you are adding down a column (A1:A3).
As another note, if you are only avoiding computational cells/columns for appearance, you could put them on a separate sheet that is hidden.
I would've added this as a comment, but don't have enough reputation.

Related

Count How Often One List Item is Found in Another List

I have 3 sheets.
Sheet 1 has a column, with the named range PayCode, of about 200 records, each containing a string. Each cell only contains one specific string, but each string can be found in multiple cells. A few of these strings represent if an employee is absent.
Sheet 2 has a list of six unique strings of interest, with the named range Absent. These six strings are the possible Pay Codes that represent if an employee is absent, and they are what I am looking for in the PayCode column.
On Sheet 3, I would like to count how many times a string from Absent is found in PayCode.
Every suggestion I've found online has me doing a COUNTIF next to the list on Sheet 2 to count how often each list item shows up, but I just want a count in one cell on Sheet 3 of the total number of appearances of Absent list items in the PayCode column.
=COUNTIF(Paycode,INDEX(Absent,1))+COUNTIF(Paycode,INDEX(Absent,2))+COUNTIF(Paycode,INDEX(Absent,3))+COUNTIF(Paycode,INDEX(Absent,4))+COUNTIF(Paycode,INDEX(Absent,5))+COUNTIF(Paycode,INDEX(Absent,6))
This method is ok since you are only dealing with 6 entries in your absent range. Basically you do a count if for each entry which is taken care of by the index then add the value for the next entry. Hence the change of 1 to 2 to ...6 in the index.
Update
Thanks to Scott Craner's comment, the above formula can be simplified as:
=SUMPRODUCT(COUNTIF(Paycode,absent))
Alternatively if you want a true array formula enter the following using CSE:
=SUM(COUNTIF(paycode,absent))
I believe COUNTIF may actually be the solution. You just need to set up Sheet 3 with the COUNTIF statements. These statements will reference to Sheet 2 to identify what you are looking for and then to Sheet 1 for the data that you will search through.
Your formula on sheet 3 would look something like this
=countif(Sheet1!A:A,Sheet2!A1)
In this scenario A:A denotes the area that you're searching through and A1 is the specific reference that you are looking for.
Option 2)
If your search term may be confined within a longer string (ex, you are looking for "apple" but the string may be "an apple a day..." then you can use this formula:
=countif(Sheet1!A:A,"*apple*")
Hope this helps!
It sounds like something you could do with the frequency function. You can find instructions here:
https://support.office.com/en-us/article/frequency-function-44e3be2b-eca0-42cd-a3f7-fd9ea898fdb9

excel Sum every other column up to certain month

I have a Simple spreadsheet with 2 rows:
ActualJAN | BudgetJAN | ActualFEB | BudgetFEB | ActualMAR | BudgetMAR ....
100 200 300 400 500 600 ....
I'd like to sum ONLY the Budget columns up to the current month (Month(Today()).
Same for the Actual columns.
So if we're currently in February,
Budget to date would be: 600=200+400
Actual to date would be: 400=100+300
I just can't seem to get there, at least simply and elegantly.
This is a non array formula that performs array like operations. As such large range references should be avoided or you will experience a slow down or potential crash of your system. For a small defined range works great so long as the formula is not repeated too many times either.
Additionally TODAY() is a volitile function which means the formula will recalculate whenever anything in the spreadsheet changes, not just when something related to the formula changes.
This formula is generalized a bit so your data can be located anywhere on your sheet and does not require rearrangement of your data.
To get your actual sum use the following:
=SUMPRODUCT($C$4:$H$4*(COLUMN($C$4:$H$4)-COLUMN($C$4)+1<=MONTH(TODAY())*2)*(LEFT($C$3:$H$3)="A"))
To get your Budget sum use the following:
=SUMPRODUCT($C$4:$H$4*(COLUMN($C$4:$H$4)-COLUMN($C$4)+1<=MONTH(TODAY())*2)*(LEFT($C$3:$H$3)="B"))
Change C4:H4 to suit your number range. ChangeC3:H3 to suit your column title range. Change C4 to be the first cell of your number range.
Caveat: Assumes maximum 12 months starting at January
Proof of concept:
I would recommend structuring your data differently. It would be an easier task if you arrayed everything vertically and divided your data into three columns. The first would be Category, which would be populated with either "Budget" or "Actual." The next column would be Month. After that, of course, you have the Value column. Then, use a basic SUMIF, like "=SUMIF(A1:A6,"Budget",C1:C6)." A1:A6 is the range Excel will scan for the desired variable. In this case, that variable is "Budget." Then, C1:C6 is the value that corresponds to a "Budget" month. That formula will give you the answer you want as long as you expand the SUMIF formula to include the full range of values, e.g., "SUMIF(A1:A317,"Budget",C1:C317)."
So I think I understand what you're trying to do, I cannot make the entire formula without the rest of the spreadsheet but this is working currently:
For the Actual:
=IF(MONTH(TODAY())=1,A2,IF(MONTH(TODAY())=2,A2+C2,IF(MONTH(TODAY())=3,A2+C2+E2,"")))
For the Budget:
=IF(MONTH(TODAY())=1,B2,IF(MONTH(TODAY())=2,B2+D2,IF(MONTH(TODAY())=3,B2+D2+F2,"")))
Here is the spreadsheet I created to test:
If you give me the rest of the data I can complete the formula, basically all you would need to do is add more months to the formula and change the amounts it adds.
I am sure there is probably a more efficient way to accomplish this but this way works.
I suggest a hidden row to control your dates. Say, January is in column C, enter [C1] =1, [D1] =C1, [E1] =C1+1, [F1] =E1. Select E1:F1 and copy to the right until December. Hide row 1.
In row 2 use these two formulas.
[C2] ="Actual" & UPPER(TEXT("1/" & C$1,"mmm"))
[D2] ="Budget" & UPPER(TEXT("1/" & D$1,"mmm"))
Select C2:D2 and copy to the right until December. This exercise isn't required because the resulting display is exactly what you already have. But producing this result with the help of formulas ensures freedom from error, and it is faster. As an added bonus you get a visual check of what's in the hidden row.
Now you can use this formula to extract totals from row 3 where you have your values.
=SUMIFS($C3:$Z3,$C$2:$Z$2,"Budget*",$C$1:$Z$1,"<="&MONTH(TODAY()))
Change "Budget" to "Actual" and the same formula will extract the actual amounts.

how to create new list in excel after comparing duplicates for unique values

I have a excel problem which has been racking my brain.
I have a list of 1740 student names on a master list (ML) and 956 student's names (PT) who took their yearbook photos. I need to compare the two to form a new list (NL) that I can export into a text file to import into a InDesign file for a no-picture list.
Also, the names in J and K are not side by side but might be shifted in some areas. They are also in different cases one is upper and the other is proper. They are also full names [First Last].
I've tried working with if and countif functions with no avail.
I want to do this:
(ML) (PT) (NL)
J K M
1 Alex James Alex
2 James Alex John
3 John Jason Jamie
4 Lexie Lexie
5 Jamie Austin
6 Austin
7 Alex
I need at least a solution that can give me a new list that can be alphabetized eventually by their surname if it requires more steps however if it can be achieved in a single function that would be great.
A single formula that addresses the end requirement might be possible, but it would be a nasty formula indeed. A couple simple formulae and short workflow might suffice:
In a blank column e.g. M2 write formula
=VLOOKUP(J2,K:K,1,FALSE)
and fill down as far as values go in column J. The result will be #N/A wherever there is no match--these are the people with no picture. VLOOKUP will ignore case differences, and the formula doesn't care if the matching name is on a different row.
Since you want to order by surname you will need a way to get that information out of the [First Last] format. In another blank column, write formula
=MID(J2,FIND(" ",J2,1)+1,30)
and again fill down.
The whole thing can now be sorted on two keys: primary on the VLOOKUP column, and secondary on the surname column. The #N/A people will sort to the bottom of the list, making the full names easy to copy off for further processing.
Edit: In pictures:
Step 1: I added surnames because that's the real use case. Note there are two different people named "Alex". Now add the formulae I gave above (shown in red here):
Step 2: Sort the range as described above.
Step 3: The people shaded in green are not in the PT column. We know this because the lookup column returned #N/A. Also, their names are sorted by surname.
Hope this helps to clarify.

How to get the newest value from a column with conditions

I have a table in Excel which has the columns:
Date
Person Name
Amount (£)
The table is used to record when people pay me money. Typically, I can get more than one person paying me on the same day. Also, the same person will pay me on many days over the course of time.
Records are added to the bottom of the table so the ordering will be on date but no further ordering on name or amount.
Using formulas, is there a way I can retrieve the most recent amount for a specific person?
If this is too complicated or not possible then I can settle for the following work around:
Add a 4th column to the table called "Last". This will display TRUE if it is the last entry for a specific person, FALSE if it is not.
It felt like there should be a fairly straight-forward answer to this but I found it quite a head scratcher so was interested to see an answer.
Having done some googling I came across a solution posted on a dedicated excel site (view here). [NB - look under the header 'Arbitrary Lookups']
Applying it to your example, suppose your data is in A1:C10 and in cell D2 you want to type a name and return the most recent payment in cell D3:
1 Date Name Amt EnterName
2 20 Jul Bob 50 <enter name here>
3 13 Sep Susan 20 = enter formula here (see below)
4 06 Jan Xavier 100
In cell D3 enter the following as an array formula (i.e. type in formula and then press CTRL + SHIFT + ENTER
=INDEX($B$2:$C$10,SMALL(IF(OFFSET($B$2:$C$10,0,0,ROWS($B$2:$C$10),1)=$D$2, ROW(OFFSET($B$2:$C$10,0,0,ROWS($B$2:$C$10),1))-ROW(OFFSET($B$2:$C$10,0,0,1,1) )+1, ROW(OFFSET($B$2:$C$10,ROWS($B$2:$C$10)-1,0,1,1))+1),COUNTIF(OFFSET($B$2:$C$10,0,0,ROWS($B$2:$C$10),1),$D$2)),2)
It would recommend checking out the link I provided if you want more detail. For clarity, I have merely adapted the formula (changed cell references) from the link provided.
Here's one way to do it based on an answer I gave in a previous SO post.
=INDEX($C$1:$C$19,MATCH(MAX(IF($B$1:$B$19="PersonNameHere",$A$1:$A$19,0)),IF($B$1:$B$19="PersonNameHere",$A$1:$A$19,"")))
Where A is the Date column, B is the Person Name column, and C is the Amount column. You must enter this as an array formula by pressing Ctrl+Shift+Enter.
I can't see right here an easy way to do it in only one formula.
If you have your data from A2 to C11.
You can add this formula on the 4th column (let say in cell D2):
{=MAX(IF($B$2:$B$11=B2,$A$2:$A$11,0))}
This is an array formula you have to validate with Ctrl-Shift-Enter
This will tell you what is the last date for the current person.
And then find the last amount with another column (let say in cell E2) and use this formula:
=INDEX($C$2:$C$11,MATCH(D2,$A$2:$A$11,0))
[EDIT] I've just tried to combine the formulas into one and that simply works:
{=INDEX($C$2:$C$11,MATCH(MAX(IF($B$2:$B$11=B2,$A$2:$A$11,0)),$A$2:$A$11,0))}
and this is still an array formula.
Alas, #Excellll was smarter (and faster) and gave the solution at first shot

Formula to follow addition of rows

New to VBA, please help. My apologies. I have not done a good job of making myself clear. Let me try one more time.
My sales reps enter every call into a call sheet. They call on 50-60 people a week; some they will see more than once a week, some only a couple of times a year. On this call sheet are 4 columns; date of call, customer, numerical date, and days since last call. This sheet may have hundreds of rows, many are duplicate customers called on a different date.
I have written code that will eliminate duplicates as needed (works fine). New calls are added using NextRow=_ (also works fine). $C$2 is set at TODAY().
Formula in column C is $C10=$A10(Column C is formatted to number). Column D is number of days since last call; $C$2-$C10 etc. Simple and works fine.
Issue is that say I have 50 rows (all different customers) sorted ascending and a new customer is added, key being new. I need the formulas in C and D to drop down one row automatically when the new customer is added. I can drag the formulas down a head of time and everything will work until I sort, then my data is a the bottom of my sort because all rows in column A without a date will produce a 0 in both C and D. My finished product should be a range of different customers (no duplicates); with the customer that has not been called on the longest at the top.
I hope this is a better explanation. Can I write code to ignore the 0's?
I am going to go a little out on a limb here and say maybe your formulas need refactoring...
For instance. If the aim is to calculate the days since the last call was made to a customer, a simple formula such as this would work
=(max(C:C)-Today())
This gets the largest value in column C and subtracts today from it.
If you want to get the value in column D which corresponds to this entry then VLOOKUP() is your friend. you would use it as such:
=VLOOKUP(MAX(C:C),C:D,2,FALSE)
Hope this helps.
Incidentaly, the best way to do your problem in VBA, the simplest way would be to create a Named Range. You can then replace the $C$2-$D11 with the name of the named range. The simplest way to do this would be to say:
Range(Range(C2),Range(C2).End(xlDown)).Name = NAmeOfYourRange
This effectively just gets cell C2, goes to the last non blank cell in the downward direction and names that range NameOfYourRange
Hope this helps :)

Resources