VLOOKUPs to Populate an Excel Table - database

I'm having trouble writing a VLOOKUP to sort some data.
I have one table that has data that looks like this:
MarkAsOfDate MaturityDate ZeroRate
05-May-15 05-May-15 0.006999933
05-May-15 06-May-15 0.006999933
05-May-15 05-Jun-15 0.008996562
05-May-15 06-Jul-15 0.008993128
... ....
I want to make a table with every instance where the interval between the dates in the first and second columns is exactly one month (such as 05 - May - 15 and 05 - Jun - 15), and with blanks where no such value exists.
So I made a second table which looks like:
MarkAsofDate MaturityDate Zero Rate 1M
5-May-15 5-Jun-15
6-May-15 6-Jun-15
7-May-15 7-Jun-15
8-May-15 8-Jun-15
9-May-15 9-Jun-15
.... ....
I want to populate this table using data from the first table. I've tried to write a VLOOKUP for it but I'm not sure how to do it with two columns instead of one.
Thanks in advance.

Vlookup has some limitations, as you're starting to see. Another suggestion is Index/Match. Use this in your second table.
Note: I assume your top table is in Sheet1. Put this in your C2, in the second table (under the "Zero Rate 1M" header):
=Index(Sheet1!$C:$C,match(A2&B2,Sheet1!$A:$A&Sheet1!$B:$B,0)) and enter by pressing CTRL+SHIFT+ENTER.

There are a lot of ways to do it - if your data is sorted first by MarkAsofDate and then by Maturity date, the simplest method will be to add a helper column on your raw data tab - let's say column E. In column E, starting at E2 and copied down, type [Assuming MarkAsofDate is column A & MaturityDate is column E]:
=IF(MONTH(B1)-MONTH(A1)=1,A1,"")
This column will show the MarkAsOfDate for every item which has a MaturityDate 1 month after the MarkAsOfDate; for all other rows it will show "".
In your special data results tab, use the MATCH function to find the row in column E which matches your current row's MarkAsOfDate. We will also use the INDEX function to return the value from that row in column C. Assuming your first sheet with raw data is sheet1 and your special data results is on sheet2, type this into E2 on sheet2 and drag down:
=INDEX(Sheet1!C:C,MATCH(A2,Sheet1!A:A,0))
Another alternative (apart from BruceWayne's recommended Array Formula) would be to use the OFFSET function. OFFSET creates a new range based on a starting point, moving a number of cells to the right/left/up/down, for a given height and width. In this case, we will first use MATCH to find the first time that the MarkAsOfDate on Sheet1 matches Sheet2. We will use that info and the OFFSET function to create a new range which starts there, and ends at the bottom of your data, like so:
=OFFSET(Sheet1!A1,MATCH(A2,Sheet1!A:A,0),1,COUNT(Sheet1!C:C),2)
Then we just need to use VLOOKUP on the range we created above, like so:
=VLOOKUP(B2,OFFSET(Sheet1!A1,MATCH(A2,Sheet1!A:A,0),1,COUNT(Sheet1!C:C),2),0)
This second alternative avoids needing a helper column, but is more complex and could be prone to errors if your rows/columns change (because we had to hardcode a couple of things in the OFFSET function). Also, OFFSET is volatile, meaning it recalculates whenever any cell calculates, so it can slow down your workbook if you have a lot of rows of it. Based on that, I recommend you either use the helper column method above, or if you are comfortable with Array Formulas, using BruceWayne's answer.

Related

Arrays, SUM + INDEX/MATCH

Note: tried in Excel and Google Sheets, but I have a preference for Sheets.
Basically I want to get the sum of a group of data using INDEX and MATCH (because the parameters are going to be drop-down dependent):
The desired result is:
So this will require a few things:
Converting the cell D13(April) to a Month
Converting the "weekof" column to a Month
Using INDEX and MATCH and MATCH again, I'm assuming because it's multiple cell references.
Here's my solution currently below:
=SUM(INDEX(D5:I9, MATCH(MONTH(D13&1),ARRAYFORMULA(MONTH(C5:C9)),0), MATCH(E12,D4:I4,0)))
This returns the NEAREST value:
270
Instead of:
804
Why this value?
270+500+34 = 804
If you are not strict to use INDEX and MATCH, you may use the following solution:
Add extra column name it "Month", this column will extract the month name from the date column using TEXT function as the following:
=IF(C3<>"",TEXT(C3,"mmmm"),"")
The if statements ensures that only filled dates will have a month value, since you have to fill this column with the above formula for a certain amount of cells.
Now you can simply use the SUMIF function in cell E13 or where ever you want:
=SUMIF(B:B,D13,D:D)
If you don't want the Month column to appear within your data table you may put it at the end of your table and hide it.
You could directly use FILTER then SUM the result instead to simplify your formula to this one:
Formula:
=SUM(FILTER(D:D, TEXT(C:C,"MMMM") = E13))
Output:
UPDATE:
The above formula should also update when the value is dropdown. Dropdown is just data that can be changed with predetermined values, aside from that, it should be the same when using a normal cell.
To match columns, use MATCH and INDEX together with the formula above. See modified formula below.
Be careful of the circular dependency. make sure your ranges doesn't interfere with the actual cell where you put your formula.
Column Matching:
=SUM(INDEX(FILTER(D:E, TEXT(C:C, "MMMM") = E13),,MATCH(F12, D4:4, 0)))
You can use pivot table and group dates by year and month.

How to pull the most recent change on an item in Excel using arrays

I'm trying to pull the most recent change to an item from a list of values and dates.
I've pasted a URL below for the image of the spreadsheet I'm currently working on.
This is currently in the top left of the spreadsheet, starting in cell A1.
I am trying to display in column C the "New Value" where columns A and E match, and where it is the most recent date in column F before the date listed in column B.
For C2, it would be 1.99
For C3, it would be 2.99
For C4, it would be 3.99
I'm trying to use INDEX, MATCH, and MAX to create an array and return the row number,
This is what my formula currently looks like:
=INDEX($H$2:$H$4,MAX(MATCH(1,(($E$2:$E$4=A2)*($F$2:$F$4<B2)),0)),4)
However I can't quite get it to display the correct values.
When I evaluate the formula, it looks like the array is evaluating correctly,
However I am having a difficult time because where it says {1,1,0} for C3, it will only result in the first match.
How can I change this array formula to only look at the last match row?
Use MAXIFS inside a SUMIFS:
=SUMIFS(H:H,E:E,A2,F:F,MAXIFS(F:F,F:F,"<="&B2,E:E,A2))
IF one does not have MAXIFS, we can replace with AGGREGATE:
=SUMIFS(H:H,E:E,A2,F:F,AGGREGATE(14,7,$F$2:$F$4/(($F$2:$F$4<=B2)*(E2:E44=A2)),1))
or if one has the Dynamic Array Formula:
=INDEX(SORT(FILTER(E:H,(E:E=A2)*(F:F<=B2)),2,-1),1,4)

EXCEL: Create Array Formula out of INDEX/MATCH with multiple results

my aim is to convert a massive excel sheet with different projects, employees and hours worked per month into an overview per employee. It should be possible to display the projects the employee is involved in and how many hours he worked per project per month.
The original sheet looks something like this:
I managed to find the projects Person A worked in by filtering through the INDEX/MATCH function. I applied the formula to the whole row where the employees are listed and receive multiple results of projects. My question is how to transform the formula into something more effective to copy all of the matched results (projects) into a column (see 1).
This is what I have so far, if matches the employee name in a certain area; the output is the first match of the project he is involved in:
=INDEX(B2:J3;1;MATCH("Person A";Sheet1!B3:E3;0))
How can I copy this to the bottom cells to copy all of the matched results? Does it help to create an array formula with this?
You can use he following formula in cell B9:
=IFERROR(INDEX($2:$2,SMALL(IF($3:$3=$B$8,COLUMN($3:$3)-COLUMN(INDEX($3:$3,1,1))+1),ROWS(A$1:A1))),"")
It indexes row 2 and looks for the column number of the first match in row 3 that equals the value in B8 (=Person A). When dragging down it will look for the second match ROWS(A$1:A1) will become ROWS(A$1:A2) = 2.
For Person B you can use this formula in cell B14:
=IFERROR(INDEX($2:$2,SMALL(IF($3:$3=$B$13,COLUMN($3:$3)-COLUMN(INDEX($3:$3,1,1))+1),ROWS(A$1:A1))),"")
I hope this is what you where looking for.
PS
if you paste the following formula in cell C9 you will get the sum result for Person A on Project XY in month 10 2019:
=IF(OR($B9="",C$8=""),"",SUMPRODUCT(($B$2:$K$2=$B9)*($B$3:$K$3=$B$8)*($A$4:$A$6=C$8),B4:K6))
Note: That is provided that the value in cell C8 equals the value in cell A4.

How can I keep references to changing spreadsheet constant?

I have 2 columns in a sheet that are referencing another dynamic sheet which has new rows added at the top all the time.
I want column A to be a copy of column A in Sheet1, so this works to put in cell A1:
={Sheet1!A:A}
However, I want column B to a formula applied to every row in column B of Sheet1. Problem is, when I put in a a formula, e.g.
=formula(B1)
then it changes to
=formula(B30)
when 29 new rows added
I want it to stay as B1, but it won't. If I use an absolute reference $B$1 then I can't copy the formula down the column.
Any wizards out there to help me out?
If you want to get the matching row from a column of another worksheet, then use INDEX and ROW, like so:
=FORMULA(INDEX(Sheet1!$B:$B, ROW(), 1))
This will always return the value in Column B of Sheet1, on the same Row as the formula is in on Sheet2 - even if you insert rows at the top of Sheet1
You can do "partially absolute reference" (I don't know the correct way of saying this).
You can lock only the column so would be =$A1 which means that it will never change the column but when you drag down the formula, it will change to =$A2, =$A3...
Or you can lock only the row typing =A$1 This way it will be locked on the row only.
You can do this also by pressing F4 several times: 1 time will lock both, the 2nd time will lock the row only, the 3rd time the column only and the 4th time will delete the locking.
the proper way would be to use INDIRECT like:
=INDIRECT("Sheet1!B1:B")

Get column header of last non-empty cell in unknown row

I have a table in a sheet called "DATA" with the following headers:
Country, Code, Series, 2000, 2001, 2002, 2003, 2004, 2005, 2006.
In each row I have data for all columns always, except for years. Some rows have data for some years only, others all years.
In sheet "DATA AVAILABILITY" I want to build a formula which returns the most recent year for which there is available information in sheet "DATA", given a certain country and code. The relevant country and codes are in cells E2 and A3 of "DATA AVAILABILITY". Let's say, for argument's sake, that these are Country: Angola; Code: 3.
I have first built an array MATCH formula with two criteria:
={MATCH(1,('DATA AVAILABILITY'!E$2=Data!$B$1:$B$104701)*('DATA AVAILABILITY'!$A3=Data!$D$1:$D$104701),0)}
This has successfully given me the row in "DATA" in which there is information for Angola and code 3, which is row 1776.
Now I would like to get the header for the last non-empty cell of row 1776 in sheet "DATA". For this, I started by building a formula that would give me the column number of that cell:
=LOOKUP(2,1/(Data!1776:1776<>""),COLUMN(Data!1776:1776))
It successfully returned the number 53 which, after verifying on sheet "Data" is the correct number. I then added to the formula so that it would return the header, i.e., the year, instead of the column number:
=INDEX(Data!$A$1:$BE$104701,1,LOOKUP(2,1/(Data!1776:1776<>""),COLUMN(Data!1776:1776)))
Finally, I would like to combine both formulas (the MATCH and the INDEX formulas) so that the final result would be returned with one formula only. However, when I try to do it, something goes wrong and an error comes up - I am not even able to enter the formula. When I click ENTER, Excel returns an error that says there is a problem with the formula. what I have tried to do is to replace, in the LOOKUP within the INDEX, "Data!1776:1776" for the array MATCH formula that returns the row in which the information is - in my example, row 1776. The final formula which is not working is as follows:
=INDEX(Data!$A$1:$BE$104701,1,LOOKUP(2,1/(MATCH(1,('DATA AVAILABILITY'!E$2=Data!$B$1:$B$104701)*('DATA AVAILABILITY'!$A3=Data!$D$1:$D$104701)<>""),COLUMN(MATCH(1,('DATA AVAILABILITY'!E$2=Data!$B$1:$B$104701)*('DATA AVAILABILITY'!$A3=Data!$D$1:$D$104701))))
What may I be doing wrong?
Thank you
Hard to tell what is going on without at least some sample data (as a table or linked workbook -- NOT as a screenshot), and I would do it a bit differently.
You can simplify your formula to get the Header of the column that contains the last data in row 1776:
=LOOKUP(2,1/(Data!1776:1776<>""),Data!$1:$1)
To return the column number:
=LOOKUP(2,1/(Data!1776:1776<>""),COLUMN(Data!$1:$1))
To return the Appropriate Row Number (enter with CSE):
=MAX(($E$2=Data!$B$1:$B$104701)*(A3=Data!$D$1:$D$104701)*ROW($A$1:$A$104701))
To return the last filled in value, in the row that matches Country and Code, we make use of the fact that using 0 for the column number in the INDEX function returns all the columns in the designated row:
=LOOKUP(2,1/(INDEX(Data!$B$1:$BE$104701,MAX(($E$2=Data!$B$1:$B$104701)*(A3=Data!$D$1:$D$104701)*ROW($A$1:$A$104701)),0)<>""),INDEX(Data!$B$1:$BE$104701,MAX(($E$2=Data!$B$1:$BE$104701)*(A3=Data!$D$1:$D$104701)*ROW($A$1:$A$104701)),0))
entered with CSE.

Resources