I want to create a named dynamic array formula that will give me a spill showing a cumulative (running) total of another array. I want one that I can enter into any cell in my workbook and get the same results.
I have the following named formulas:
twelve: =ROW(OFFSET('CSM'!$A$1,0,0,12,1)) [EDIT: I realised later it's simpler just to define it as =SEQUENCE(12)] This generates an array of whole numbers from 1 to 12; I use it for a number of purposes, such as producing a list of months (=TEXT(DATE(2023,twelve,1),"mmm-yy").
FTE: ='CSM'!$B$3/12*(--(twelve=twelve)) This shows FTE's monthly salary (with cell B3 on sheet CSM providing the annual salary) over 12 months.
Now, if I enter =FTE on any cell, I'll get a 12-cell spill that shows the FTE's salary for each month. That's fine, but what I really need is a named formula that when it spills will show the FTE's cumulative salary (a running total).
I can do this with a formula that links to a specific cell...for example, if I want my display to start in row 2 I use:
=SUM((--(twelve<=ROW()-1))*FTE), and then drag the formula down the remaining 11 rows. But I have to adjust this formula if I use it somewhere else--for instance, if I want to start my spill on row 10 I have to write =SUM((--(twelve<=ROW()-9))*FTE). I really want a named formula that I can use anywhere on the sheet without modification, that will give me a spill showing cumulative monthly salary.
I see you can do this using the MMULT function when the data are all on a worksheet (see here), even when those data are a dynamic spilled array (see =MMULT(ROW(A1#)>=TRANSPOSE(ROW(A1#)),A1#), here). But when I use this approach on a named formula, I get a #VALUE error. I think the error actually comes from the ROW() function--it looks like I can use =ROWS(FTE) (returns 12), but not =ROW(FTE) (which returns the error).
So my question is: is there any way I can create a named formula that will give me a 12-month spill of FTE's cumulative salary by month? Maybe using SEQUENCE() or MMULT() or something else...(We haven't got Lambda yet, by the way.)
EDIT (in response to comments):
For example, if B3=$75,000, putting =FTE into any cell will produce this (spilling over into cells below):
$6,369.86
$5,753.42
$6,369.86
$6,164.38
$6,369.86
$6,164.38
$6,369.86
$6,369.86
$6,164.38
$6,369.86
$6,164.38
$6,369.86
What I want is a cumulative sum (running total) of the above; that is:
$6,369.86
$12,123.29
$18,493.15
$24,657.53
$31,027.40
$37,191.78
$43,561.64
$49,931.51
$56,095.89
$62,465.75
$68,630.14
$75,000.00
As I mentioned, we haven't got Lamda at this point, or any of those newer formulae.
OK, I've figured out a solution. For whatever reason, it seems you can't use ROW() with named dynamic array formulas, but it turns out I don't need to. I can simply use: =MMULT((--(twelve>=TRANSPOSE(twelve))),FTE) and I'll get the desired result (with 75000 being the value in B3):
6369.86
12123.29
18493.15
24657.53
31027.40
37191.78
43561.64
49931.51
56095.89
62465.75
68630.14
75000.00
I also found it useful to assign the above formula to a name, so I can conveniently enter it into any cell on the sheet and get the same output.
One more thing: I realised I can define the named formula twelve more simply by using =SEQUENCE(12), though the OFFSET approach still works. (Still getting used to some of there 'new' Excel formulas--not so new anymore, I guess.) I edited original question to mention this.
Related
I am new to excel formulas and vba etc. thats why i have no idea how to solve this problem.
Problem:
I want to create a dynamic chart using the offset function. Basically i want to show in my chart
the last 7 entries from the newest entry and insert all the data from the columns in it.
The current code that i used is this:
Bereich.verschieben is german for offset btw.
=BEREICH.VERSCHIEBEN(Historie!$C$307:$C$312;0,0;1;Charts!$B$58-1)
I want something like:
=BEREICH.VERSCHIEBEN(Historie!$C$307:$C$312;**0:5**;0;1;Charts!$B$58-1)
to show the data in the whole range. And i would like to add the part where i only show the last 5 entries from the current filled cell. In the picture below for example, from Col L to Col H all the data should be shown.
What i current got is this:
The Data in the chart is further on the back with the current date. Thats why the numbers dont match up exactly.
I recreated a data table similar to yours (the exact length and values are not important for the formulas):
I understand that you want to create a dynamic array similar to the one shown here:
The one shown here has been created using 3 formulas in the highlighted cells.
There are 2 ways to write these formulas that immediately come to mind. a) using INDEX() functions or b) using OFFSET() functions.
Starting with the INDEX() based formulas:
the formula for the machines is =TRANSPOSE(Historie!$B$307:$B$312)
for the last 5 dates =LET(Dates,Historie!$306:$306,INDEX(Dates,1,SEQUENCE(5,1,MATCH(MAX(Dates),Dates,0)-4)))
and for the values you can then use =LET(Data,Historie!$307:$312,Dates,Historie!$306:$306,INDEX(Data,SEQUENCE(1,COLUMNS(C3#)),MATCH(B4#,Dates,0)))
where the direct cell references correspond to the arrays as shown in the screenshot further below.
And the OFFSET() based formulas:
the formula for the machines is the same =TRANSPOSE(Historie!$B$307:$B$312)
for the last 5 dates you can use =LET(Dates,Historie!$306:$306,TRANSPOSE(OFFSET(Dates,0,MATCH(MAX(Dates),Dates,0)-5,1,5)))
and for the values =LET(Data,Historie!$307:$312,Dates,Historie!$306:$306,TRANSPOSE(OFFSET(Data,0,MATCH(MAX(Dates),Dates,0)-5,6,5)))
Both alternatives generate the same table as shown here below:
Note: In both alternatives, I hard wrote some numbers into the formulas that imply that you want to extract the values for exactly 5 dates and exactly 6 machines. If either one or both of those numbers shall be variable, adjustments have to be made accordingly.
Edit 1: Avoiding LET() function
When the LET() function is not available for your purposes, the above formulas can be rewritten. I will leave out the 1st of the 3 formulas since it doesn't use LET()
INDEX() based formulas:
the dates formula is =INDEX(Historie!$306:$306,1,SEQUENCE(5,1,MATCH(MAX(Historie!$306:$306),Historie!$306:$306,0)-4))
the formula for the values is =INDEX(Historie!$307:$312,SEQUENCE(1,COLUMNS(C3#)),MATCH(B4#,Historie!$306:$306,0))
OFFSET() based formulas:
the dates formula is =TRANSPOSE(OFFSET(Historie!$306:$306,0,MATCH(MAX(Historie!$306:$306),Historie!$306:$306,0)-5,1,5))
the formula for the values is =TRANSPOSE(OFFSET(Historie!$307:$312,0,MATCH(MAX(Historie!$306:$306),Historie!$306:$306,0)-5,6,5))
These adjusted formulas generate the exact same table as the LET-formulas above. See Screenshot
I have the following problem I need to address:
I have quotations from multiple vendors for multiple types of products. I need to find the product wise minimum and 2nd lowest quotations. The sheet looks somewhat like this:
I want the output in the following format:
Now, the problem is that the number of vendors is 300, and using the regular formula: min(number1,number2,number3,...) is very tedious and error prone as I have to manually click each entry for each vendor like min(B3,F3,I3,... 300 entries) for product 1.
Another problem is for 2nd Lowest Quote Here, excel does not accept discontinuous array like min function. Which means I cannot enter the formula small(B3,F3,I3,2) as it gives you have entered too many arguments error in this case.
I need to find some way to get around this problem. Please help me out with this problem.
Another option in non-array formula solution
Assume your data put in A1:P5
"Minimum quote" in K3, copied across to M3, and all copied down :
=AGGREGATE(15,6,$B3:$J3/($B$2:$J$2=K$2),1)
"2nd lowest quote" in N3, copied across to P3, and all copied down :
=AGGREGATE(15,6,$B3:$J3/($B$2:$J$2=N$2),2)
Data
You could try an array formula like so:
=MIN(IF($B$2:$J$2=K$2,$B3:$J3))
Make sure you hit Ctrl+Shift+Enter. What it does is it only extracts values corresponding to the specific product using the if statement, min then finds the minimum value out of that range.
Same applies to the SMALL function, it can take a range but we must filter that range using the IF function to get only the columns we want for that product, this also requires to be an array formula by entering it with Ctrl+Shift+Enter
=SMALL(IF($B$2:$M$2=N$2,$B3:$M3),2)
I have a spreadsheet that shows the actual dollars produced and the expected dollars produced for each employee, where each row is one day and each employee has two columns. I would like to count the number of times an employee came within 10% of their production goal without referencing specific columns. Please look at the example spreadsheet.
I want for the formulas in cells Sheet2!E4:E7 to do what the formulas in Sheet2!E10:E13 do.
I am trying to avoid using direct column references because it causes me to have to go in and update the columns in the formulas every time a new employee is added to the sheet.
I'm no stranger to using INDEX+MATCH, or to converting SUMPRODUCT formulas to INDEX+MATCH. What I can't get past are the formulas in cells Sheet2!E4:E7. If you evaluate the formula you can watch the INDEX+MATCH section on the left side of the formula work correctly, and then a nearly identical INDEX+MATCH section on the right side evaluate to 0 for no apparent reason.
The formula I'm having trouble with is in cell Sheet2!E4:
COUNTIF(INDEX(Sheet1!$A$2:$AZ$314,,MATCH($B4,Sheet1!$A$1:$AZ$1,0)),">"&(INDEX(Sheet1!$A$2:$AZ$314,,MATCH($B4,Sheet1!$A$1:$AZ$1,0)+1)))
The section to the left of the ">" will match with the correct range (Sheet1!B2:B314), however the section to the right of the ">" will evaluate to 0 instead of Sheet1!C2:C314.
This is strange to me because the only real difference between the two sections is the '+1' on the end of the MATCH function, and adding the '+1' to the section to the left of the ">" produces the expected result for the MATCH function (Sheet1!C2:C314) as seen by evaluating the formula in cell Sheet2!E5.
The formula that produces the correct result is in cell Sheet2!E10:
SUMPRODUCT(--(ISNUMBER(Sheet1!$B$2:$B$313)),--(Sheet1!$B$2:$B$313<Sheet1!$C$2:$C$313),--(Sheet1!$B$2:$B$313>=Sheet1!$C$2:$C$313*0.9))
I understand that if I exclude the '$' before the column references, any future additions/subtractions to the columns on Sheet1 will adjust the references accordingly. This solution is not ideal, because there are multiple data sheets (one for each year) where the columns are all different (Dan is column F for 2019, G for 2018, M for 2017, etc.), and the tables using these sheets are laid out in a way that would prevent me from easily being able to auto-update the formulas, so a solution that locates the correct column using the employee's name is preferred.
The correct result should be 2 for Allen and 3 for Torres, but I can only seem to get the INDEX+MATCH formulas to return 0, 12, 15, 16, or 17 (depending on what tweaks I make to the formula).
Any help with this would be greatly appreciated.
You can try this: ARRAY FORMULA CTRL + SHIFT + ENTER
=SUM(IF(ISNUMBER(INDEX($A$1:$E$30,2,MATCH(G9,$A$1:$E$1,0)):INDEX($A$1:$E$30,30,MATCH(G9,$A$1:$E$1,0))),INDEX($A$1:$E$30,2,MATCH(G9,$A$1:$E$1,0)):INDEX($A$1:$E$30,30,MATCH(G9,$A$1:$E$1,0))<INDEX($A$1:$E$30,2,MATCH(G9,$A$1:$E$1,0)+1):INDEX($A$1:$E$30,30,MATCH(G9,$A$1:$E$1,0)+1)*(INDEX($A$1:$E$30,2,MATCH(G9,$A$1:$E$1,0)):INDEX($A$1:$E$30,30,MATCH(G9,$A$1:$E$1,0))>=INDEX($A$1:$E$30,2,MATCH(G9,$A$1:$E$1,0)+1):INDEX($A$1:$E$30,30,MATCH(G9,$A$1:$E$1,0)+1)*0.9))*1)
and adapt the ranges to your needs. It is entered on the same sheet as the data.
Basically this approach uses ARRAY FORMULA CTRL + SHIFT + ENTER
INDEX($A$1:$E$30,2,MATCH(G9,$A$1:$E$1,0)):INDEX($A$1:$E$30,30,MATCH(G9,$A$1:$E$1,0)))
to get the needed ranges. MATCH looks for the right column. the row number can be set as needed, here its is from 2 to30 adapted to your provided data. My search term in this case is in G9 with Allen as content. The result of the formula is $B$2:$B$30. A +1 after Match gives the other range $C$2:$C$30. Both ranges can then be evaluated with the needed conditions
Pull it down and provide Torres in G10. Then the ranges will be adapted to $D$2:$D$30 and $E$2:$E$30.
I have a data in Excel as shown in attached image where in I've used named ranges.
Spends. Apr18. May18. Jun18
Category A. 120. 120. 120
Category B. 135. 125. 129
Category C. 110. 111. 112
Name Range: Spends
Range: =Sheet1!$A$1:$D$4
The average quarterly spends are calculated using named references as:
=AVERAGE(INDEX(Spends,2,2):INDEX(Spends,2,4))
This returns 119 in Cell E2
How can I drag this formula to subsequent cells so that it is applied automatically.
If you use the INDEX function with constants, of course these constants will not change when you drag the formula down and/or across.
You will need to learn about absolute and relative references and use something like Row(A1) and/or Column(A1) instead of the constants 2 and 2.
But maybe it does not have to be that complicated.
You could just add a column in the data table that calculates the Average and refer to that cell.
Or, in cell E2, use the formula =average(B2:D2).
I don't see the need for the named range at all in this scenario. It only complicates things.
It seems that you are struggling with appropriate data architecture concepts rather than with using formulas.
If in doubt, keep it simple. I don't see an application for copying the formula across, since you only have three months of data and you want to average these three months.
If your real scenario has more columns, then, please!!, update your question and post more relevant context. Then post a comment, so I can see you made a change.
Again, since you are new here: do not post updates into comments. Edit your question and then post a comment.
Use the ROW() function to return the relative position
E.g. in E2 and drag down
=AVERAGE(INDEX(Spends,ROW(),2):INDEX(Spends,ROW(),4))
Maybe you want to dynamically find the quarter start and end columns then you can use Match function to find the dates and return the position (column) where found. Then feed these into your formula:
Getting the columns by searching for qtr start and end:
Referencing those found positions as column arguments in your formula:
I've come across several discussions on using INDIRECT and 3D references, however none seem to address (or fix) this problem specifically.
I'm trying to count the position of a worksheet without using VBA. Each sheet represents a month, and has a standardized name (e.g. JAN-15, FEB-15, MAR-15, etc.). My idea is to find the position by counting the number of sheets between JAN-15 and the current sheet. A1 of each sheet = 1, which gets summed across the sheets using a 3D reference.
Using February as an example, I can hard code this with no problem:
=SUM('JAN-15:FEB-15'!A1)
When I do this, I get the expected result of 2. However, I want each month's sheet to dynamically generate its position without having to change the formula each time. So I tried this:
Cell named FIRSTMONTH ='JAN-15
Cell named CURRMONTH =RIGHT(CELL("FILENAME",A1),6)
N1 =CONCATENATE("'",FIRSTMONTH,":",CURRMONTH,"'!A1")
(N1 evaluates correctly as 'JAN-15:FEB-15'!A1)
When I try this formula to generate the position:
=SUM(INDIRECT(N1))
I get a #REF! error. I've also tried this variation:
=SUM(INDIRECT("N1"))
Which returns 0.
Anyone have an idea of how I can get this to work? Or is there a better way that doesn't use VBA?
-David
Assuming you won't have any gaps perhaps try counting the number of month between the first month and the current one, e.g.
=DATEDIF(FIRSTMONTH,CURRMONTH,"m")+1