I have an Excel document containing 2 sheets:
All purchases
Invoices
I would like to find a simple method to add items from 'All purchases' to 'Invoices' based on the date.
Example:
All purchases:
Date | Name | Sum
----------------------------------
2013-01-01 | Pottery | $12.00
2013-01-01 | Liquids | $1.00
2013-01-09 | Baby food | $12000.00 <
2013-01-02 | Car | $12.00
2013-01-09 | Lego | $50001.00 <
2013-01-02 | Car part | $10000.00
2013-01-09 | More Lego | $50001.00 <
Based on the date 2013-01-09 I want to automatically fill the 'Invoices' in the following way:
Date | Name | Sum
----------------------------------
2013-01-09 | Baby food | $12000.00
2013-01-09 | Lego | $50001.00
2013-01-09 | More Lego | $50001.00
Can this be done without macro?
I know about camera, pivot tables, lookups, indices, but I could not combine them into a usable solution.
My other plan is to look up the collection for every cell and retrieve the 1st one for the 1st row, 2nd for the 2nd row. Is there a simpler solution?
Related
I have Sale Invoices for bread, jam, etc. like this table.
+-------+--------+-------+
| Item | Date | Price |
+-------+--------+-------+
| Bread | 1-Dec | 5 |
+-------+--------+-------+
| Jam | 1-Dec | 5 |
+-------+--------+-------+
| Bread | 8-Dec | 6 |
+-------+--------+-------+
| Jam | 8-Dec | 4 |
+-------+--------+-------+
| Bread | 15-Dec | 4 |
+-------+--------+-------+
| Jam | 15-Dec | 7 |
+-------+--------+-------+
I want the highest price date for each item like
+-------+--------+---------------+
| Item | Date | Highest Price |
+-------+--------+---------------+
| Bread | 8-Dec | 6 |
+-------+--------+---------------+
| Jam | 15-Dec | 7 |
+-------+--------+---------------+
It is like finding Max Values depending on Lookup Values. It is very much like Group By and Max in SQL. How do I do it in excel? I've tried index match and also googling. Nothing helps. Please help me.
This is typically done through a pivot table:
Select your data.
Insert a pivot table.
In your case use "Item" & "Date" as rows.
In your case use "Price" as value.
Then click "Price" and under it's field settings choose "Max".
Then in the pivot table itself right any date, click "Filter" > "Top Ten" and make that top 1 based on the max price.
There are many ways to do this through formulae, but if one has Excel O365 it can be done through one single formula, for example:
Formula in E2:
=TRANSPOSE(CHOOSE({1,2,3},TRANSPOSE(UNIQUE(A2:A7)),TRANSPOSE(MINIFS(B2:B7,A2:A7,UNIQUE(A2:A7),C2:C7,MAXIFS(C2:C7,A2:A7,UNIQUE(A2:A7)))),TRANSPOSE(MAXIFS(C2:C7,A2:A7,UNIQUE(A2:A7)))))
Or:
=FILTER(A2:C7,ISNUMBER(MATCH(A2:A7,UNIQUE(A2:A7),0))*LET(X,MAXIFS(C2:C7,A2:A7,UNIQUE(A2:A7)),ISNUMBER(MATCH(C2:C7,MAXIFS(C2:C7,A2:A7,UNIQUE(A2:A7))))*ISNUMBER(MATCH(B2:B7,MINIFS(B2:B7,A2:A7,UNIQUE(A2:A7),C2:C7,X),0))))
I have an excel sheet (called Sheet1) with rows of data that look like this:
Unit | Names | Begin_Date | End_Date
-----------------------------------
A | Jones | 1/1/2016 | 1/4/2018
A | Frank | 2/11/2018 |
B | Adam | 3/5/2011 |
C | Jane | 6/9/2012 | 7/14/2016
C | John | 7/28/2016 | 9/22/2017
C | Joe | 12/31/2017 | 1/1/2019
C | Joe | 1/2/2019 |
I am trying to get it into a format that has the units as column headers and dates as rows. The idea is that for every day between the begin and end dates, the name of the person should be in the appropriate cell. If there is a gap between the end date of one person and the begin date of the next within the same unit, the formula will list "vacant". It is assumed each unit was vacant before the first "begin date" for that unit, and blanks for end dates mean that the person still occupies that unit. Ideally the completed data set would look like this, on Sheet2:
Date | A | B | C |
-------------------------------------
3/5/2011 | Vacant | Adam | Vacant
3/6/2011 | Vacant | Adam | Vacant
...
6/9/2012 | Vacant | Adam | Jane
...
1/1/2016 | Jones | Adam | Jane
...
7/14/2016 | Jones | Adam | Jane
7/15/2016 | Jones | Adam | Vacant
7/16/2016 | Jones | Adam | Vacant
...
7/28/2016 | Jones | Adam | John
...
1/4/2018 | Jones | Adam | Joe
1/5/2018 | Vacant | Adam | Joe
etc.
The formula I have thus far populates the first values, i.e. the first person to live in the unit or, if no one, then it lists "vacant" on Sheet2. However, I am not sure how to extend it to look for the next person. I've listed all the dates in column A and all of the unique Unit names in row 1. Any help or advice would be appreciated!
=iferror(if(index(Sheet1!Names,match(1,(Sheet2!A$2=Sheet1!Begin_Date)*(Sheet2!$A3=Sheet1!End_Date),0))=Index(Sheet1!Names,match($A2,ArrayFormula(min(Sheet1!Unit=B$2,Sheet1!Begin_Date)),"Vacant",Index(Sheet1!Names,match($A2,ArrayFormula(min(Sheet1!Unit=B$2,Sheet1!Begin_Date))),Index(Sheet1!Names,match($A2,ArrayFormula(min(Sheet1!Unit=B$2,Sheet1!Begin_Date)))
This uses aggregate and is basically an array formula but without having to be entered with
CtrlShiftEnter
=IF($F2="","",IFERROR(INDEX($B:$B,AGGREGATE(15,6,ROW($A$2:$A$10)/
(($A$2:$A$10=G$1)*($F2>=$C$2:$C$10)*(($F2<=$D$2:$D$10)+($D$2:$D$10=""))),1)),"Vacant"))
Aggregate(15,6...1) woks out the minimum value of the array inside it, ignoring any error values. This array consists of the rows 2-10 divided by the conditions on the rows. The conditions are set up (as you did) using * for AND and + for OR. Where the conditions are false, this leads to a division by zero which gives an error, so only the rows which satisfy the condition are taken into account.
You can also use this
=IF($F2="","",IFERROR(INDEX($B$2:$B$10,MATCH(1,
($A$2:$A$10=G$1)*($F2>=$C$2:$C$10)*(($F2<=$D$2:$D$10)+($D$2:$D$10="")),0)),"Vacant"))
entered as an array formula.
Within a resource planner, my data has a row for each employee, and columns detailing the team they work for. Another column details the available days they will work in the year. The teams are also displayed along a row at the top, see below :
A | B | C | D | E | F | G |
1 Employee | Team 1 | Team 2 | Days | Finance | Risk | IT |
2 Employee 1 | Finance | | 170 | | | |
3 Employee 2 | Risk | Finance | 170 | | | |
4 Employee 3 | Finance | | 170 | | | |
5 Employee 4 | IT | Risk | 170 | | | |
6 Employee 5 | IT | Finance | 170 | | | |
I want to use columns E:G as a supply calculator per team. Therefore, the formula in cell E2 would be "=IF(B2=E1,D2,0)" and copied along the row, returning the 170 days under Finance and 0 under the rest.
The issue lies where an employee divides his time between two different teams. As you can see, some employees can work for 2 different teams (Employee 2 works for both Finance and Risk, for example). The formula in E3 would therefore need to be some kind of IF AND, where if a value is present in the Team 2 column (C), the value in the Days column (D) would be divided by two and split across the relevent team columns.
I've tried a few options, IF AND, nested IFS etc but cant seem to get the syntax correct. Any help greatly appreciated.
=IF(ISNUMBER(MATCH(E$1,$B2:$C2,0)),$D2/COUNTA($B2:$C2),0)
You actually want OR and COUNTA:
=IF(OR($B2=E$1,$C2=E$1),$D2/COUNTA($B2:$C2),0)
I have sales data by customer as follows:
| - | A | B | C | D | E | F | G |
|---|---------------|--------|--------|--------|--------|--------|--------|
| 1 | Customer Name | Jan-18 | Feb-18 | Mar-18 | Apr-18 | May-18 | Jun-18 |
| 2 | Mr.A | 1000 | 500 | 0 | 200 | 0 | 0 |
| 3 | Mr.B | 0 | 300 | 200 | 0 | 0 | 100 |
I need the formula to know the last sales of the respective customer booked (the name of the month)
in this case, Mr. A last order is in Apr-18 while Mr.B is in Jun-18.
I have 2,000 plus customer and sales data since Apr 2016 up to last month, it will be a huge time saving to have a formula to help.
Assuming your 'months' are dates, not Text. Courtesy #barry houdini:
=LOOKUP(2,1/(B2:G2<>0),B$1:G$1)
in Row2 and copied down to suit, formatted mmm-yy.
Ref
An alternative to using LOOKUP() as in this answer, not sure what impact it has performance-wise as both need to create an array but I would take a stab in the dark that this is less performant:
=INDEX($B$1:$G$1,,MAX((B2:G2<>0)*COLUMN(B2:G2)-1)) - Ctrl+Shift+Enter
Ofcourse this could be edited to a dual lookup on the customer too:
=INDEX($B$1:$G$1,,MAX(INDEX(($B$2:$G$3<>0)*COLUMN($B$2:$G$3)-1,MATCH("Mr.B",$A$2:$A$3,0),0)))
This doesn't require the CSE as INDEX() handles the array manipulation
I have the following data in Excel Worksheet A, which is a basic ledger of expenses:
The initial data looks like:
Week | Amount | Payee | Category
1 | 10.00 | John | Cookies
1 | 12.00 | Bill | Cookies
3 | 7.08 | Jason | Oranges
...
And I have assigned categories and calculate subtotals like this on another sheet using SUMIF :
Category | Total | Include?
Cookies | 22.00 | True
Oranges | 14.87 |
...
I'm trying to get to a report that sums if that Include? boolean is set. By using SUMIF again, I can summarize by week:
Total IncludeSet?
1 100.06
2 100.3 22.00
3 80.07
4 77.29
...
I know I could create an Extra column, and I could also try a SUMIFS and apply multiple criteria, but I'm up for learning how the pros would tackle this. At some point, I should just put this into MATLAB or a database.