Copy data from one sheet (data) to another (summary) - excel

I am trying to populate one worksheet (summary) with data from a large data dump held in another worksheet (data).
This is going to be sent to budget holders within my organisation who will be able to filter on their cost centre and view their staff group.
Summary worksheet
This is structured as follows:
| | A | B | C | D |
| 1 | Please choose a cost centre: [Textfield] |
| 2 | | | | |
| 3 | POSITION | STAFF GROUP | PAY GRADE | |
| 4 | [Data will go here]
| 5 | [Data will go here]
| 6 | [Data will go here]
Data worksheet
This is structured as follows (although with 3,600 rows and not 4):
| | A | B | C | D |
| 1 | POSITION | STAFF GROUP | PAY GRADE | COST CENTRE |
| 2 | Typist | A&C | Junior | 3000 |
| 3 | Manager | A&C | Mgmt | 3200 |
| 4 | Typist | A&C | Junior | 3000 |
| 5 | Receptionist | A&C | Junior | 3000 |
The Exam Question
Using the textfield to select cost centre 3000, how can I populate the Summary worksheet with the two rows of data from the Data worksheet? Almost as if you could through a pivot table. Could this be done with formulae or will VBA be required?

METHOD #1
This is the formula way to achieve the filter.
On the Summary sheet, select the range A4:C22.
Click the Formula Bar at the top of the worksheet and paste the following formula:
=IFERROR(INDEX(Data!A2:C22,SMALL(IF($D$1=Data!$D$2:$D$22,ROW(Data!$D$2:$D$22)-ROW(Data!$D$2)+1),ROW()-3),{1,2,3}),"")
This is an array formula and must be confirmed with Ctrl+Shift+Enter.
Now, as you update the value in cell D1, the filtered results will appear.
Note: this assumes that you will have no more than 20 filtered results. If that assumption is incorrect then you will need to select a deeper range before you confirm the array-formula.
Note: this assumes that the data on the data sheet do not extend further down than row 22. If the data do, then change the references of 22 in the formula to a larger number.
METHOD #2
This is a VBA soltuion.
Place the following procedure in a standard code module:
Public Sub Barry()
Const DATA = "data!a1"
Const OUTPUT = "a3:c3"
Const FILTER_VALUE_ADDRESS = "d1"
Const FILTER_COLUMN = 4
Dim rCrit As Range, rData As Range
Set rData = Range(DATA).CurrentRegion
Set rCrit = rData.Resize(2, 1).Offset(, rData.Columns.Count + 2)
rCrit(1) = rData(1, FILTER_COLUMN): rCrit(2) = Range(FILTER_VALUE_ADDRESS)
rData.AdvancedFilter xlFilterCopy, rCrit, Range(OUTPUT)
rCrit.Clear
End Sub
Switch to the Summary sheet and press Alt-F8 to bring up the Macro Dialog.
Run Barry.

Related

Excel - Transpose data from multiple rows to single column with matched value

Ok, so I have some data that I want to convert from multiple rows to multiple columns.
My input data looks loosely like this -
+----------+----------------+-----------------+
| SKU | Attribute Name | Attribute Value |
+----------+----------------+-----------------+
| Product1 | Colour | Black |
| Product1 | Size | Large |
| Product1 | Height | 20cm |
| Product1 | Width | 40cm |
| Product2 | Colour | Red |
| Product2 | Width | 30cm |
| Product2 | Size | Large |
| Product3 | Height | 25cm |
| Product3 | Width | 30cm |
| Product3 | Length | 90cm |
| Product3 | Weight | 5kg |
| Product3 | Size | Large |
| Product3 | Colour | Blue |
+----------+----------------+-----------------+
What I want to achieve is an output like this -
+----------+--------+--------+--------+-------+--------+-------+
| SKU | Colour | Height | Length | Size | Weight | Width |
+----------+--------+--------+--------+-------+--------+-------+
| Product1 | Black | 20cm | | Large | | 40cm |
| Product2 | Red | | | Large | | 30cm |
| Product3 | Blue | 25cm | 90cm | Large | 5kg | 30cm |
+----------+--------+--------+--------+-------+--------+-------+
I've tried Pivot tables, but you can only return numeric values, rather than the text values I'm looking for.
I know I could probably achieve it using a number of step looking up values and filling them, but I feel like there should be a more simplistic way to achieve this. Maybe it's something better achieved in database rather than a spreadsheet.
Any help would be very much appreciated.
You can do this in ̶5̶ ̶s̶t̶e̶p̶s̶ 4 steps with Powerquery. This is in-built for 2016 and a free add-in from Microsoft from 2013 on wards ( or 2010 Professional Plus with Software Assurance). See info https://www.microsoft.com/en-gb/download/details.aspx?id=39379
The advantage is you can easily add rows to the source and simply refresh the query.
1) You select any cell in the range, then in 2016 Get & Transform tab, earlier version use the Powerquery tab, select data from table. A window will pop up with your range of data in:
2) Transform > Pivot column > Attribute Name column for Attribute Value in Values Column (used advanced options to select "Don't aggregate")
3) Drag columns around to desired arrangement
4) Home > Close and load to sheet
Here is a version without the column re-ordering
Edit:
Thanks to #Ron Rosenfeld for reminding me that truly null values don't need replacing with blanks as they will appear as blanks when written to the sheet.
So this step was removed:
4) Highlight columns to replace nulls in and go to transform > replace values > and
Value to Find: null
Replace With:
You could do this using a helper column and then match it using index + match. Not as simple as you thought, but does work.
1) Add helper column to your data (call it 'Helper'). =concat(SKU,'Attribute Name')
2) Use a pivot to get a unique list of SKUs in the rows so that it's easy to update once the data changes. (I'm assuming this is in column A and values start at row 4).
3) Use another pivot to get a unique list of Attributes in the columns next to the other pivot. Then you have the structure of your results. (I'm assuming the first value is in B3).
4) Index match the values of the table =index('Attribute Value', match(concat($A4,B$3),'Helper',0))
Note though that this only works when each combination of SKU and Attribute is unique.
This assumes that the data is in columns A through C:
Sub croupier()
Dim i As Long, N As Long, vA As String, vB As String, vC As String
Dim rw As Long, cl As Long
' setup column headers
Columns(2).SpecialCells(2).Offset(1).Copy Range("D1")
Columns(4).RemoveDuplicates Columns:=1, Header:=xlNo
Columns(4).SpecialCells(2).Copy
Range("E1").PasteSpecial Transpose:=True
Columns(4).SpecialCells(2).Clear
' setup row headers
Columns(1).SpecialCells(2).Copy Range("D1")
Columns(4).RemoveDuplicates Columns:=1, Header:=xlYes
' deal the data
N = Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To N
vA = Cells(i, 1)
vB = Cells(i, 2)
vC = Cells(i, 3)
cl = Rows(1).Find(what:=vB, after:=Range("A1")).Column
rw = Columns(4).Find(what:=vA, after:=Range("D1")).Row
Cells(rw, cl) = vC
Next i
End Sub

Using Slicers/Filters in a Table

Example I will be using is a list of people who I buy sweets off, tabled into preference and sortable by category. I have a table of values in the format:
Option 1|Option 2|Option 3|Catagory 1 | Category 2 |
--------|--------|--------|-----------|------------|
Bob | Mary | Jane | Candy | Sherbert |
James | Bob | Jane | Choc | Cadbury Bar|
Jane | | | Candy | Haribo |
Jane | Mary | James | Candy | Millions |
... | ... | ... | ... | ... |
I want to be able to use dropdown boxes or slicers to pick the name and first category and show a filtered list of the final category (2) and the "rank" based on them being primary, secondary or tertiary option, for example as I select Jane:
Name |^| Catagory 1|^| Category 2 | Rank |
-------|-------------|------------|-------|
Jane | Candy | Sherbert | 3 |
| Haribo | 1 |
| Millions | 1 |
or:
Name |^| Catagory 1|^| Category 2 | Rank |
-------|-------------|------------|-------|
Jane | Choc | Cadbury Bar| 3 |
(depending on how it is picked)
Comment Questions:
What Excel version are you using? 2013
Is this no-vba task? Preferably no-vba, if you chose to answer in VBA please consider that it needs to be tailored to explaining how to implement the solution to someone with limited excel-vba experience.
Can you use two tables (1 input, 1 output) or you want the layout to change dynamically? Using 2 tables is fine, feel free to impress by using dynamic tables if you so wish (dynamic tables may win the bounty over an answer without them)
Can you explain how field Rank is calculated? For example Rank=3 in case of Jane | Choc | Cadbury Bar ? In the row for Cadbury bar, Jane is the 3rd option, hence rank 3. If she was second she would be rank 2 or if first, rank 1.
You have Name (Jane) in the first three columns. May the same Name (Jane) appear in any of the three columns? Can you explain the reason of having names in three columns? If the name may appear in any of the column then they have to be unique - is that so? Consider the data as lines first, perhaps reading right-to-left may help. The Category 2 column is the only column that contains unique values. Any name can appear any number of times in the first 3 columns but none of the names can be duplicated in the same row: Jane cannot be the option 1, 2 and 3 for a single item (for example)
Here's a VBA solution which uses standard Excel components
Your workbook should have two sheets named SourceData and Calculation with two tables having the same names as in pictures below:
Now add VBA code that will process your data. Press Alt+F11 to open the code editor. Add a new module:
Now in that module insert this code:
Const SOURCE_DATA_SHEET As String = "SourceData"
Const SOURCE_DATA_TABLE As String = "SourceData"
Const CALCULATION_SHEET As String = "Calculation"
Const CALCULATION_TABLE As String = "Calculation"
Const S_OPTION_1 As Integer = 1
Const S_OPTION_2 As Integer = 2
Const S_OPTION_3 As Integer = 3
Const S_CATEGORY_1 As Integer = 4
Const S_CATEGORY_2 As Integer = 5
Const C_WIDTH As Integer = 4
Const C_NAME As Integer = 1
Const C_CATEGORY_1 As Integer = 2
Const C_CATEGORY_2 As Integer = 3
Const C_RANK As Integer = 4
Function GetTable(sheetName As String, tableName As String) As ListObject
Set GetTable = Worksheets(sheetName).ListObjects(tableName)
End Function
Sub ClearTable(dataTable As ListObject)
dataTable.AutoFilter.ShowAllData
dataTable.Sort.SortFields.Clear
If dataTable.ListRows.Count >= 1 Then
dataTable.DataBodyRange.Delete
End If
End Sub
Sub InsertRow(ByRef dataTable As ListObject, ByRef dataRow As Variant)
dataTable.ListRows.Add
dataTable.ListRows(dataTable.ListRows.Count).Range = dataRow
End Sub
Sub CalculateRanks(ByRef dataTable As ListObject, ByRef destinationTable As ListObject)
Dim newRow(1 To C_WIDTH) As Variant
Dim nameValue As Variant
For Each dataRow In dataTable.ListRows
With dataRow
newRow(C_CATEGORY_1) = .Range(S_CATEGORY_1).Value
newRow(C_CATEGORY_2) = .Range(S_CATEGORY_2).Value
For Each optionNumber In Array(S_OPTION_1, S_OPTION_2, S_OPTION_3)
nameValue = .Range(optionNumber).Value
If nameValue <> "" Then
newRow(C_NAME) = nameValue
newRow(C_RANK) = optionNumber
InsertRow destinationTable, newRow
End If
Next optionNumber
End With
Next dataRow
End Sub
Sub Main()
Dim sourceTable As ListObject
Dim destinationTable As ListObject
Set sourceTable = GetTable(SOURCE_DATA_SHEET, SOURCE_DATA_TABLE)
Set destinationTable = GetTable(CALCULATION_SHEET, CALCULATION_TABLE)
ClearTable destinationTable
CalculateRanks sourceTable, destinationTable
End Sub
On your Calculation sheet, add a button that you will use to run the code. Under "Developer" tab (if you don't see this tab, go to Excel Options / Customize Ribbon / Check the "Developer" checkbox in "Main Tabs" list) insert a button form control:
And link your macro Main to the button:
You're done! Now every time you click the button, the Calculation table will get refreshed. You may use filters to show the desired content.
Here's your dynamic table, no VBA solution. You just need to add a single helper column.
First, pick some sort of delimiter. I chose "!". .
Next, in an adjacent column put the following big honking formula:
[Name of person]|
----------------|
=IFERROR(LEN(LEFT(CONCATENATE("!",A2,"!",B2,"!",C2,"!"),FIND(CONCATENATE("!",$F$1,"!"),CONCATENATE("!",A2,"!",B2,"!",C2,"!"))-1))-LEN(SUBSTITUTE(LEFT(CONCATENATE("!",A2,"!",B2,"!",C2,"!"),FIND(CONCATENATE("!",$F$1,"!"),CONCATENATE("!",A2,"!",B2,"!",C2,"!"))-1),"!",""))+1,"")|
...|
What this does is tell you how many exclamation points occurred in the concatenated list of names before the value in F1 (which, in my workbook is the column header where I put "Jane"). (It then adds one, so that the top spot is "1", and not "0"). If the name in the header row is not found, the cell is left blank.
Once you've got this in place, your process for getting your filtered list is:
1. Enter the name of the person in F1.
2. Filter out blanks from F1.
3. Filter Category 1 as desired.
Note that in my formulas, the columns match up as follows:
Col A |Col B |Col C |Col D |Col E |Col F |
Option1|Option2|Option3|Category1|Category2|[Name of person]|
These formulas produce the following output:
Option 1|Option 2|Option 3|Category 1 | Category 2 |Jane |
--------|--------|--------|-----------|------------|-----|
Bob | Mary | Jane | Candy | Sherbert |3 |
James | Bob | Jane | Choc | Cadbury Bar|3 |
Jane | | | Candy | Haribo |1 |
Jane | Mary | James | Candy | Millions |1 |
... | ... | ... | ... | ... |... |
Or, for James...
Option 1|Option 2|Option 3|Category 1 | Category 2 |James |
--------|--------|--------|-----------|------------|----- |
Bob | Mary | Jane | Candy | Sherbert | |
James | Bob | Jane | Choc | Cadbury Bar|1 |
Jane | | | Candy | Haribo | |
Jane | Mary | James | Candy | Millions |3 |
... | ... | ... | ... | ... |... |
If you are familiar with using SQL statements in Excel, it is very easy. You can use the approach I presented here Filter ShowDetails of PivotTable. If you are not, do not worry, just download my file, feed your table and use it.
The idea in SQL is:
Select Name=[Option 1],[Category 1],[Category 2],Rank=1 union all
Select Name=[Option 2],[Category 1],[Category 2],Rank=2 union all
Select Name=[Option 3],[Category 1],[Category 2],Rank=3
* I changed the headings for using SQL statements in Excel does not allow column names ending with numbers - stupid bug learnt the hard way.
It produces the following output table:
With such an output table the following part is very easy. You do not even need slicers. Just use filters of the table to get the desired results:
You might be willing to have your output table without rows which do not contain names (i.e. row 7 or 11). Then simply use SQL clause:
WHERE Name is not null
You can adjust this code so that the output table generates automatically on file open.

How Do I Implement Excel Filter Function Through Formula?

I have a table of data, and some of the data is garbage. There's about 30000 entries sorted by unit. I only care about 20 of those units. I can easily sort the data by applying a filter, but it's tedious to click the 23 or so times and I'm going to have to manage this report weekly.
I've captured the relevant criteria into a different sheet, all non-repeating values sorted into a column. I'd like to arrange another sheet so that it only displays the rows from my table if the data in their unit column matches the criteria column.
I know I need to use VLOOKUP... somehow, but I haven't stumbled across any tutorials that compare a cell's value to a table.
In case that was all very confusing:
My table:
Action | Job Desc | Dept
XFR | IT Guy | Home Office 1
POS | Security Guy| Satellite Office
TTL | Analyst Guy | Home Office 2
I want to have a new sheet that only contains 3 rows:
Action | Job Desc | Dept
XFR | IT Guy | Home Office 1
TTL | Analyst Guy | Home Office 2
I have the values "Home Office 1" and "Home Office 2" stored elsewhere (there are actually 28 different office values). How do I build this sheet so it only displays these values - similar to the stock Excel filter function?
I think the easiest way to do this is by creating a tab of "interesting" units and vlookup to this. In the new interesting tab you would list the 20 items you are interested in column A.
In the data tab with all 30,000 rows you need to add a new column to check each row if it exists in the interesting tab. I assume the units are in column C and you are entering this formula in cell D1 =NOT(ISERROR(VLOOKUP(C1,InterestingTab!A:A,1,0))).
The result of the formula is TRUE or FALSE, which can easily be filtered on. Then you can easily add new items to the interesting tab and it will update automatically.
A very common question.
Assuming that:
1) You are using Excel 2010 or later
2) The original table is in Sheet1!A1:C10 (with headers in row 1)
3) The table to house the (filtered) results is in Sheet2 and of an identical layout to the original table
4) The list of (28) criteria is in Sheet3!A2:A29
then enter this single formula in Sheet2!J1:
=SUMPRODUCT(COUNTIF(Sheet3!A2:A29,Sheet1!C2:C10))
Of course, the choice of cell here does not have to be J1, though, whatever you choose, make sure that it is a cell which is external to your results table. This formula is a one-off, and, unlike those in the main results table, NOT designed to be copied to any further cells; it simply determines the number of expected returns, and will be referenced in the main table formulas, thus avoiding resource-heavy IFERROR set-ups.
The formula in cell A2 of the results table is then:
=IF(ROWS($1:1)>$J$1,"",INDEX(Sheet1!A:A,AGGREGATE(15,6,ROW(Sheet1!B$2:B$10)/MATCH(Sheet1!$C$2:$C$10,Sheet3!$A$2:$A$29,0)^0,ROWS($1:1))))
and copied down and to the right as required.
Obviously if the upper row reference in your original table is not actually 10 then you will need to amend that part within these formulas accordingly. However, be sure not to choose an arbitrarily large value, since, for each additional cell referenced, extra calculation will be required (and that applies whether those additional cells are technically beyond the last-used cells in those ranges or not.)
As such, I recommend that you either choose a suitably low, though sufficient, upper bound for the end row being referenced or, even better, make your ranges dynamic, such that they automatically adjust as your data expands/contracts.
Regards
Here is my anser...
Sub takeMyValus()
Dim r1
Dim r2
Dim c
Dim rng1 As Range
Dim rng2 As Range
Dim sht1 As Worksheet
Dim sht2 As Worksheet
Dim sht3 As Worksheet
Dim List()
Dim i
Dim j
r1 = Range("A1").End(xlDown).Row 'to know the last row
c = Range("A1").End(xlToRight).Column 'to know the last colum
Set sht1 = Sheets("Data") 'this is the name I used, but you
'put the name of your data sheet
Set sht2 = Sheets("List") 'the sheet with the sorted list of the data you want
sht1.Activate 'Just in case
Set rng1 = Range(Cells(1, 1), Cells(r1, c)) 'set just the range with data
rng1.AutoFilter 'set the autofilter
'is better if the data has no autofilter
'when you begin to run the macro
sht2.Activate
'imagine that you got the list in column A and is just 5 items in your data
'With no header
'+---------+
'| Office3 |
'| Home5 |
'| Office8 |
'| Home8 |
'| Sat2 |
'+---------+
'List for my example...
r2 = Range("A1").End(xlDown).Row 'to know the total item on the list
'in this case will be 5
Set rng2 = Range(Cells(1, 1), Cells(r2, 1)) 'set the range of the list
'that is Range("A1:A5")
j = 0 'ini the counter
For Each i In rng2 'for every cell in Range("A1:A5")
j = j + 1 'increase the j to 1 every time
ReDim Preserve List(1 To j)
'redimension the var...
List(j) = i.Value 'store every cell (just the data) into an array
Next i 'next one.
sht1.Activate 'go to sheet with all the data
rng1.AutoFilter Field:=3, Criteria1:=Array(List), Operator:=xlFilterValues 'set the filter with the list
rng1.SpecialCells(xlCellTypeVisible).Copy 'copy just the cells that you can see, this is the filter
Sheets.Add after:=Sheets(Sheets.Count) 'add a new sheet
ActiveSheet.Name = myTime 'put a diferent name, see the function below
Set sht3 = ActiveSheet 'store the new sheet into this var
sht3.Activate 'go to the new sheet... is already activate, but just in case...
Range("A1").PasteSpecial xlPasteAll 'paste all in Range("A1")
Application.CutCopyMode = False 'is like press ESCAPE in the keyboard
End Sub
Function myTime() As String 'the function a told you
Dim HH
Dim MM
Dim SS
Dim TT
HH = Hour(Now)
MM = Minute(Now)
SS = Second(Now)
myTime = Format(HH, "00") & Format(MM, "00") & Format(SS, "00")
End Function
Here is the example of my data...
+--------+---------+----------+
| Action | Job Des | Dept |
+--------+---------+----------+
| XFR | IT | Office1 |
| POS | Sec | Office2 |
| TTL | Analyst | Office3 |
| XFR | IT | Office4 |
| POS | Sec | Office5 |
| TTL | Analyst | Office6 |
| XFR | IT | Office7 |
| POS | Sec | Office8 |
| TTL | Analyst | Office9 |
| XFR | IT | Office10 |
| POS | Sec | Home1 |
| TTL | Analyst | Home2 |
| XFR | IT | Home3 |
| POS | Sec | Home4 |
| TTL | Analyst | Home5 |
| XFR | IT | Home6 |
| POS | Sec | Home7 |
| TTL | Analyst | Home8 |
| XFR | IT | Home9 |
| POS | Sec | Home10 |
| TTL | Analyst | Home11 |
| XFR | IT | Home12 |
| POS | Sec | Sat1 |
| TTL | Analyst | Sat2 |
| XFR | IT | Sat3 |
| POS | Sec | Sat4 |
| TTL | Analyst | Sat5 |
| XFR | IT | Sat6 |
| POS | Sec | Sat7 |
| TTL | Analyst | Sat8 |
| XFR | IT | Sat9 |
| POS | Sec | Sat10 |
| TTL | Analyst | Sat11 |
| XFR | IT | Sat12 |
| POS | Sec | Sat13 |
| TTL | Analyst | Sat14 |
+--------+---------+----------+
The list
+---------+
| Office3 |
| Home5 |
| Office8 |
| Home8 |
| Sat2 |
+---------+
The result:
+--------+---------+---------+
| Action | Job Des | Dept |
+--------+---------+---------+
| TTL | Analyst | Office3 |
| POS | Sec | Office8 |
| TTL | Analyst | Home5 |
| TTL | Analyst | Home8 |
| TTL | Analyst | Sat2 |
+--------+---------+---------+

Changing the format/layout of an excel worksheet

I have a worksheet with over 3 months worth of data entry. My coworker claims she can't understand the layout. She wants me to change it from example 1 to example 2. Is there any easy way to do this without re-entering 3 months worth of work?
Example 1
WK# | DATE | ACCT NAME
1 | 7/09/15 | MY PLACE
2 | 8/06/15 | MY PLACE
3 | 8/13/15 | MY PLACE
4 | 8/20/15 | MY PLACE
5 | 8/27/15 | MY PLACE
Example 2
Acct Name | Wk 1 | Wk 2 | Wk 3 | Wk 4 | Wk 5 |
-----------|-----------|-----------|------------|-----------|-----------|
My Place | 7/9/15 | 8/6/15 | 8/13/15 | 8/20/15 | 8/27/15 |
Yes, it can be done.
For every processing worksheet:
Create new worksheet
Populate layout (header) cells of new created worksheet
Read cell values from old worksheet and put these values to the new worksheet cells.

Extract data from two tables to summary report based on primary key

I have two Excel sheets, one called plan and other one called sewing data. I want to extract data from sewing data sheet to a summary report. Both sheet contain primary key and some data comes from plan sheet and others come from sewing data.
Sample data:
[plan]
ID | Style | SO | QTY
---+-------+-------+------
1 | a | 20050 | 100
2 | b | 20051 | 100
[sewing data]
ID | Day1in | Day1out | Day2in | Day2out | Day3in | Day3out
---+--------+---------+--------+---------+--------+-----------
1 | 20 | | 10 | 25 | |
2 | | | 50 | | |
2 | | | | | 50 | 70
1 | | | | | 70 | 75
And my output should be like:
[summery report]
ID | Style | SO | Qty | Day1in | Day1out | Day2in |Day2out|Day3in| Day3out
---+-------+------+-----+--------+---------+--------+-------+------+-----------
1 | a |20050 |100 | 20 | | 10 | 25 | 70 | 75
2 | b |20051 |100 | | | 50 | | 50 | 70
On the [plan] sheet, create a named range 'plandata' to cover the plan
data
On the [sewing data] sheet, add 3 columns, headed Style, SO, Qty, with
formulas
=vlookup(A2, plandata, 2, false)
=vlookup(A2, plandata, 3, false)
=vlookup(A2, plandata, 4, false)
respectively (here A2 is the reference to the ID cell, plandata is the named range from the [plan] sheet you created in step 1, numbers 2/3/4 are the column numbers you need for the lookup, i.e. Style, SO, and Qty, and false means exact match for the lookup).
Copy these formulas down the entire [sewing data] sheet
Select any cell in [sewing data], then Insert > Pivot Table (select 'new worksheet')
In the Pivot Table wizard, drag ID, Style. SO and Qty as row labels,
and Day1In..Day3Out as ∑ values.
You can create a one-size-fits-all formula by wrapping the first VLOOKUP function in an IFERROR function which passes control over to a second SUMPRODUCT function if the VLOOKUP cannot find the column header label in the first. In B15 as,
=IFERROR(VLOOKUP($A15, $A$3:$D$4, MATCH(B$14, $A$2:$D$2, 0), FALSE), SUMPRODUCT($B$8:$G$11, ($A$8:$A$11=$A15)*($B$7:$G$7=B$14)))
Fill right and down as necessary.
        
It is critically important that the column header labels match exactly; no leading spaces on one or the other.

Resources