I have the following formula in the 'Available Staff' sheet:
=LET(AvailabilityCalc,FILTER(AllStaffProjectAllocationTbl, IF(ISBLANK($I$11),1,(AllStaffProjectAllocationTbl[Role]=$I$11))*IF(ISBLANK($I$8),1,(AllStaffProjectAllocationTbl[Employee]=$I$8))*IF(ISBLANK($I$14),1,(AllStaffProjectAllocationTbl[Discipline]=$I$14))* (AllStaffProjectAllocationTbl[End Date]<$I$2)*(TRANSPOSE(MMULT(SEQUENCE(1,ROWS(AllStaffProjectAllocationTbl),1,0),TRANSPOSE(AllStaffProjectAllocationTbl[End Date]>TRANSPOSE(AllStaffProjectAllocationTbl[End Date]))*(AllStaffProjectAllocationTbl[Employee]=TRANSPOSE(AllStaffProjectAllocationTbl[Employee]))*(1)))-MMULT((TRANSPOSE(AllStaffProjectAllocationTbl[Employee])=AllStaffProjectAllocationTbl[Employee])+0,SEQUENCE(ROWS(AllStaffProjectAllocationTbl),1,1,0))+1=0)),IFERROR(SORT(INDEX(AvailabilityCalc,SEQUENCE(ROWS(AvailabilityCalc)),{1,4,5,9}),4),""))
that sits in A2 and pulls in all staff that are available after a specific date defined in I2. This unfortunately has an issue as it pulls the data from the staff that have been allocated to a project previously from a 'Staff Project Allocation' sheet and doesn't incorporate the staff from the 'Staff Details' sheet that are yet to be allocated to a project.
The 'Staff Project Allocation' sheet :
The 'Staff Details' sheet :
Someone kindly helped me with the above function and I'm not sure how to modify it to do what I want. Could it be simpler to keep the above as is and create a new set of data to the right of it say, that pulls in the entries from the 'Staff Details' sheet that don't appear in the data created by the formula and are available from the date specified - whilst also being a development role, which I can do by checking their discipline against another table? Or is there a way to modifiy the formula above to incoporate the data? Something I also need to incorporate in the above function, which I overlooked originally, is to exclude any staff member that has had their employment terminated as noted in the Employment Status columns, so any suggestions on how to incoporate this too would be greatly appreciated.
I'm also starting to wonder whether a VBA solution maywell be a better approach, thoughts?
Edit 1
Adjusted function based on the suggestions from Max below. This now includes the ability to filter based on the employment status.
=LET(
staff, AllStaffProjectAllocationTbl,
employee, AllStaffProjectAllocationTbl[Employee],
role, AllStaffProjectAllocationTbl[Role],
discipline, AllStaffProjectAllocationTbl[Discipline],
endDate, AllStaffProjectAllocationTbl[End Date],
employmentStatus, AllStaffProjectAllocationTbl[Employment Status],
rowCt, ROWS(AllStaffProjectAllocationTbl),
roleSelection, $I$11,
employeeSelection, $I$8,
disciplineSelection, $I$14,
availableFromDate, $I$2,
empStatusSelection,"Employment Terminated",
mmult_1, MMULT(SEQUENCE(1,rowCt,1,0),TRANSPOSE(endDate>TRANSPOSE(endDate))*(employee=TRANSPOSE(employee))*(1)),
mmult_2, MMULT((TRANSPOSE(employee)= employee)+0,SEQUENCE(rowCt,1,1,0)),
roleCondition, IF(ISBLANK(roleSelection),1,(role=roleSelection)),
employeeCondition, IF(ISBLANK(employeeSelection),1,( employee=employeeSelection)),
disciplineCondition, IF(ISBLANK(disciplineSelection),1,(discipline=disciplineSelection)),
empStatusCondition, NOT(employmentStatus=empStatusSelection),
AvailabilityCalc,FILTER(staff,roleCondition*employeeCondition*disciplineCondition*empStatusCondition*(endDate<availableFromDate)*(TRANSPOSE(mmult_1)-mmult_2+1=0)),
IFERROR(SORT(INDEX(AvailabilityCalc,SEQUENCE(ROWS(AvailabilityCalc)),{1,4,5,10}),4),"")
)
Edit 2
I now have two tables, one from the Staff Details sheet, showing all staff who are development staff and still employed, this can be seen on the left in the following image (note this all staff allocated to a project or not) and defined by =FILTER(FILTER(StaffDetailsTbl,(StaffDetailsTbl[Employment Status]<>"Employment Terminated")*(StaffDetailsTbl[Dev Role]="Yes")),{1,1,1,0,0,0,1,0,0}), and a separate table defined by the Let function above in edit 1, showing all staff allocated to a project that are available based on a specified date, see table on the right.
I'd now like to merge the table on the left into the table on the right whilst also removing any duplicate entries. Would the most logical first step to be to adjust the filter for the left table to exclude entries that are in the right table? Then look to merge the two in to the right table somehow? Or is it possible to take the Filter defining the left most table and work it directly in to the function defining the right table?
Edit 3
The following function now filters out the entries from the StaffDetailsTbl Table that don't exist in the AllStaffProjectAllocationTbl Table:
=FILTER(FILTER(StaffDetailsTbl,(StaffDetailsTbl[Employment Status]<>"Employment Terminated")*(StaffDetailsTbl[Dev Role]="Yes")*(IF(ISERROR(VLOOKUP(StaffDetailsTbl[Employee], AllStaffProjectAllocationTbl, 1, FALSE)),1,0 ))),{1,1,1,0,0,0,1,0,0})
Giving the resulting table on the left for staff not allocated to a project and those allocated to a project and who are available after a specified date on the right:
I now need to figure out how to merge the filter formula from the left table in to the Let function above, or alternatively, build another table from the two that supports all the roleSelection, employeeSelection, disciplineSelection and availableFromDate functionality. Any thoughts on the best way I can do this please?
The formula logic is complex enough that it's unlikely someone here would be able to invest the time required to work through this on their own. It means someone has to "reverse engineer" the meaning of every reference, like "what does $I$11 really represent".
While not technically an answer, I can provide some help on how to simplify the problem, and then document the logic for your future reference. This won't meet the technical definition of a "proper" StackOverflow answer, but it's too much to fit in a comment and still better than leaving you empty-handed.
Use LET to simplify
You already have it, so let's go further with it, so we can simplify the formula as much as possible. Here's one example of using LET to further break down the formula, and using alt-Enter to create non-breaking returns in the excel formula:
=LET(
staff, AllStaffProjectAllocationTbl,
emp, AllStaffProjectAllocationTbl[Employee],
role, AllStaffProjectAllocationTbl[Role],
disc, AllStaffProjectAllocationTbl[Discipline],
endDate, AllStaffProjectAllocationTbl[End Date],
rowCt, ROWS(AllStaffProjectAllocationTbl),
mmult_1, MMULT(SEQUENCE(1,rowCt,1,0),TRANSPOSE(endDate>TRANSPOSE(endDate))*(emp=TRANSPOSE(emp))*(1)),
mmult_2, MMULT((TRANSPOSE(emp)=emp)+0,SEQUENCE(rowCt,1,1,0)),
roleCondition, IF(ISBLANK($I$11),1,(role=$I$11)),
empCondition, IF(ISBLANK($I$8),1,(emp=$I$8)),
discCondition, IF(ISBLANK($I$14),1,(disc=$I$14)),
AvailabilityCalc,FILTER(staff,roleCondition*empCondition*discCondition*(endDate<$I$2)*(TRANSPOSE(mmult_1)-mmult_2+1=0)),
IFERROR(SORT(INDEX(AvailabilityCalc,SEQUENCE(ROWS(AvailabilityCalc)),{1,4,5,9}),4),"")
)
This is still a lot to take in, but it separates the complexity of how we found/calculated the inputs from the actual Filter and Result logic at the end. if it was my sheet I'd go further and break the formulas down even more, like giving $I$8 or "transpose(emp)=emp+0" a name as well. The more granular, the better.
Then Document your LET formula right in excel
On another sheet, create an Excel table that documents the LET parameters:
Name
Equates to
Which means
disc
AllStaffProjectAllocationTbl[Discipline]
Discipline Col of Staff Table
roleCondition
IF(ISBLANK($I$11),1,(role=$I$11))
Role from I11, or 1 if I11 is blank
xyz
$I$11
describe what I11 is
I put "xyz" in row 3, but the point is to give a name to each thing, if you are not using name manager.
Hope this helps, either to add clarity for you, or to get someone else started creating a full answer.
I have been searching high and low for a way to solve my dilemma, in different ways, so I am trying to post both of the things I've been trying to do:
The challenge version 1:
I want to extract the entire row with information tied to the name which is the latest entry of that name in the table. So from the table below I would want to collect the entire row which contains the information: "A, Jack Black, 01.01.2029, 10:20". I simply want to copy the entire row to another sheet. But one important factor is that it has to happen automatically.
So i need functions which can check if: Is there another entry with the same name, higher up in the table? If so, DO NOT COPY THE ROW. If there ain't another entry with the exact same name higher up in the table, COPY THE ENTIRE ROW, to another table, within another sheet.
The challenge version 2:
What I really want to do is count the number of unique people(unique names) per. department, and summarize this in another table. Basically this means that "Jack Black" should be counted as 1 person, in department A.
So the result I want, is a table looking like this (the one beneath), where the number of people does not contain any duplicate people (names). OR it does not function with a dynamic table, which updates the information it contains on the fly. I can make this happen if I am copying from a static table, but as stated above, the table is dynamic and updates with new information every minute...
So far i've tried excel's built in filtering, but this does not work automatically. I've also tried using functions like in this guide: https://excel-bytes.com/how-to-extract-a-dynamic-list-from-a-data-range-based-on-a-criteria-without-filters-in-excel/. However every solution i find seems to need criteria for filtering out duplicates or does not function when copying information from a dynamic table.
Does anyone know how to reach my desired result, without implementing criteria for selecting the rows or counting rows as stated above? VBA code is not an option at the moment :(
In advance, THANK YOU, I've really tried solving this, but I feel like this just might break my head wide open soon if I can't solve it. HEEEEELP!
Sincerely
haakonlu
I'm all new to VBA and have mostly been trying to modify code after recording macros, so it's all pretty basic and the approach might not be as elegant as some of the stuff I've seen on here. So here we go.
I have coded (by brute force) my data to be arranged like a CAD design tree view with parent products/assemblies and constituent sub-assemblies/parts.
Column E contains Level 0 top assembly Part Number
Column F contains Level 1 items Part Number
... etc all the way to ...
Column M containing Level 8 items Part Number
As an example, cell G112 contains ASSY1; cells H113 to H134 contain its constituent items.
I would like to display in a new column (i.e. Column O) the value of cell G112 (ASSY1) for each of its constituents. So O113 to O134 would show the value of G112. That would need to be applied to every single level of the assembly.
I'm not sure I'm making much sense do please have a look at the picture linked below, it speaks a thousand words. I've highlighted and colour-coded the result I would like in column O.
ADDENDUM - To clarify things:
I don't know how else to explain my request but to post a simplified version of my original picture.
SIMPLIFIED EXCEL TABLE
.CSV available here WeTransfer
A very useful tool to retrieve VBA code for determined action is the macro recorder, in the ribbon, Developer -> RecordMacro, perform you action and stop recording and then you can check the code generated for the actions you recorded. Its not the cleanest code but you can find there the lines of code for the specific actions you want. Once you step into a one concrete problem with the code you tried, you can then ask for help regarding something more concrete, more than expecting that someone will code that for you.
Anyhow if you want someone to try to solve your problem, you need to post the table with the accessible data instead of the image, for the person whoever tries to approach your problem to have the data available.
Hope that helps
Here's the answer I got from somewhere else if anyone is interested:
Formula in Cell O3:
=IF(C3=0,"N/A , ALREADY TOP LEVEL",INDEX(D$2:D2,AGGREGATE(14,6,(ROW(D$2:D2)-ROW(D$2)+1)/(C$2:C2=C3-1),1)))
Copy/Paste down in every cell in column O
I am creating a spreadsheet to reconstruct an HTML export into an editable daily schedule.
The export contains info on what each person is scheduled to do throughout the day, and the spreadsheet turns it into a format with hourly columns.
Source data: https://imgur.com/6MAtxLA
Output: https://imgur.com/OI9RKC9
To do this, I've broken down what each person is doing into separate start and end columns, and used nested IF statements to piece it together.
The issue is that I've come up against the maximum amount of nesting, and I still need to add more, as there are more activities to cover. I'd like to know if there's another way I could go about it which wouldn't cause this issue.
The formula looks like this:
https://imgur.com/0R3FDhd
It's just saying that if the activity is on or before the current time, and hasn't ended yet, then it should show that activity.
Each line references a type of activity. The referenced cells look like this:
https://imgur.com/wjipfLT
There's a lot of repetition in the formula, and I hope there's a way to handle it so that each type of activity doesn't need it's own IF statement. However, I'm kind of stuck here. If there's anyone who knows a way I could change this, I'd really appreciate the help.
EDIT: Formula
IF(AND(OR(P[#6]=X!Z4, [#M]=X!Z4), S[#5] <> X!Z4), X!Z4,
IF(AND(OR(P[#6]=X!Z5, [#M]=X!Z5), S[#5] <> X!Z5), X!Z5,
IF(AND(OR(P[#6]=X!Z6, [#M]=X!Z6), S[#5] <> X!Z6), X!Z6,
...ad nauseam
I have a question that I a may not be thinking correctly about. But I have an a long excel file that I pull from somewhere else with the following columns:
Project_Name1, Employee_Name1, Date_Worked1, Hours_Worked1
In another sheet I have these columns
Project_Name2, Employee_Name2, Begin_Date2, End_Date2, Hours_Worked2
This second sheet is filled with data, and works just fine.
However, it turns out that I have some employee names that I do not know that are also working on the same project. I need to figure out the names of the employees and then sum the number of hours they worked for a given period.
So I need a lookup with three criteria:
Project_Name1 = Project_Name2
Employee_Name1 <> {Array of Employee_Name2}
Begin_Date2 <= Date_Worked1 > End_Date2
Returning Employee name.
Once I have the employee name, I can do a sumifs=() and get the total hours they worked no problem.
I have tried a number of combinations of Index Match functions, using ctrl-shift-enter... and have not been able to figure out it. Any help would be greatly appreciated.
What you're talking about doing is extremely complicated and a little bit past what Excel was designed to do by default. However, there are a few workarounds that you can use to attempt to get the information that you're looking for.
It's possible to do multiple-criteria VLOOKUPs and SUMIFs by concatenating fields to make a multi-part identifier (Ex: Insert a new column and have a forumla in it like =A1&B1)
Open a new workbook and use Microsoft Query (I'm not sure if you can select from more than one sheet, but if you can select from multiple sheets like tables you should be able to write a semi-complex query to pull the dataset you want.
http://office.microsoft.com/en-us/excel-help/use-microsoft-query-to-retrieve-external-data-HA010099664.aspx
Use the embedded macro feature and use visual basic script to write out your business logic. (Hotkey is ALT+F11)
One way to do this would be to first create an additional column to the right of entries on the sheet you're trying to pull employee_name from: =ROW()
You could then use an array formula like you were trying to implement to pull the corresponding 'match' row:
{=SUM((project_name1=projectname2)*(employeename1<>employeename2)*(begindate<=date_worked1)*(date_worked1>end_date2)*(match_column))}
You could then use this returned match_column entry within the index as you described to retrieve the appropriate entries.