EXCEL: Counting worksheets dynamically using INDIRECT - excel

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

Related

Running total from a named array formula in Excel

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.

How to automatically change reference based on variable in excel

So I'm trying to create a Forecast using historic data from 2 years. Each year's data is broken down into weeks and weeks that haven't occurred yet are set to 0. I'm struggling trying to create a formula that will automatically run a Forecast on only the weeks in the year that have occurred. I created this formula which Excel won't execute:
=UNIQUE(FILTER(WkSht!G:(VLOOKUP(F1,DH2:DI54,2)),(WkSht!A:A)=(B1)))
I'm trying to use VLOOKUP to replace the second part of a cell reference based off a lookup table. So if F1 is 25, for example, then the Filter function will be:
=UNIQUE(FILTER(WkSht!G:AE,(WkSht!A:A)=(B1))
That second formula works on its own as intended, but I'm trying to create this excel file so that it requires minimal work to update in the future and manually changing the range seems like a bit too much work to expect other people to do.
So I guess my question is:
How do I change part of the reference automatically?
Maybe I could do:
=UNIQUE(FILTER(VLOOKUP(F1,DH2:DI54,2)),(WkSht!A:A)=(B1)))
And have to lookup values contain the reference text?
Alternatively, is there a way to filter out the last of the 0's in the FORECAST.ETS function (as some values might intentionally be 0s in earlier weeks)?
To get a variable width range, you can use the construct
SomeRange:INDEX(MaxRange,,NumberOfColumns)
In your case SomeRange would be
WkSht!G:G
MaxRange would be something like
WkSht!G:Z
where you replace Z with a column that comfortably covers all your (future) data
NumberOfColumns is your VLookup (You probably want an exact match?, If so include the 4th parameter =0)
Demo:
=UNIQUE(FILTER(WkSht!G:G:INDEX(WkSht!G:Z,,VLOOKUP(F1,DH2:DI54,2,0)),WkSht!A:A=B1))
Sample data on sheet WkSht

Execute excel formula only for specific cells

I am trying to create a formula that checks for several things at the same time but I am having trouble with one part of it.
The formula is the following:
=IF(COUNTIFS($N$2:$N$17095,N3,$K$2:$K$17095,"<>"&"")>6,
IF((SUMPRODUCT(--(ROUND($K$2:$K$49,2)=ROUND(K3,2)))>9),"Always Late / Possible Automation",
IF(COUNTIFS($N$2:$N$17088,N3,$K$2:$K$17088,"<3.5")>0,"Delivered Earlier At Least Once",IF(COUNTIFS($N$2:$N$17088,N3,$K$2:$K$17088,">3.5")>6,"Always Late","False"))))
The first part checks how many entries in the range having the same value as it is in cell N3 have values different to blank and we want those to be more than 6.
Second part is the tough one, it is supposed to check how many values in the rounded range match the rounded value in cell K3. The issue is the formula checks the whole range and I want to check only for the values which match N3 (in essence like the CountIf works only for that value).
The rest is not so relevant.
Some example data:
![enter image description here][1]
As you see in the end of the table the formula with the rounding works but only because I have limited the data shown to 3 unique values in column N. Even here though if i have a blank it doesnt work becaus ei haven't considered it.
Thanks in advance.
Assuming you have Office 365 compatibility/Excel version, use a bunch of filters. To avoid an unwieldy formula I've extended ranges to maximum number of rows (customize as required)...
=LET(x_,$E$3:$E$25,a_,FILTER($E$3:$E$25,--(x_=E3)),b_,FILTER($B$3:$B$25,--(x_=E3)),IF(SUM(--(a_=E3)*(b_<>""))>6,IF((SUMPRODUCT(--(ROUND(b_,2)=ROUND(B3,2)))>9),"Always Late / Possible Automation",IF(SUM(--(a_=E3)*(b_<3.5))>0,"Delivered Earlier At Least Once",IF(SUM(--(a_=E3)*(b_>3.5))>6,"Always Late","False")))))
Note: filter does not appear to work too well within countifs for some reason (must be related to syntax RE: arrays vs. criteria TBC). Thus have replaced countifs(filter_range,X) eqn 'types' with sum(--(filter_range=X)) which works as intended.

Indirect Function with Sheet Names

I have a list of all of the sheet names in my workbook on Sheet1 and I am trying, without success, to use the INDIRECT function to reference a cell on another sheet using said name. I am aware that this is a common question, I have looked at about 10 other questions/answers on this website in addition to others. For some reason, those solutions are not working and I am kinda losing my mind.
The sheet names are all in column A
They are named after dates (format mm-dd-yy) <- I'm assuming this is the problem?
The cell that I am trying to reference is always in O1 on every sheet in the workbook.
I have tried:
=INDIRECT(A1&"!O1")
=INDIRECT("'"A1"'&!O1")
and a few other amalgamations. Again, I have looked into so many other solutions at this point I am just left with asking for help with my situation, which is apparently unique (or more likely it is some blaring user error). Please help me before immediately removing the post.
If I have this right, the names of your sheets are dates, and you have the names listed as dates in Column A. So, they will appear as dates, but are actually Excel's background number for a date (days since 1/1/1900).
If you use the Formulas tab in the ribbon to Evaluate Formula, you should see the date pop in to your formula as a 5 digit number.
If you are not doing anything else with these dates, you could try selecting column A and formatting as text. This solved the issue in my test setup. This will still work if you are using the date for other functions, but you will have to tell Excel it's a date using DateValue()
After formatting Column A as text, I used =INDIRECT("'"&A1&"'!O1")
Try,
=indirect(text(a1, "\'mm-dd-yy\'\!\O\1"))

Trying to find the last non-empty cell in a specific row/range over multiple sheets

I looked at a couple suggestions here and didn't find something that specifically worked for me. I would prefer not to use an Array Formula if possible. However, if that's the only way, I'll try to work with it.
I am working on an attendance workbook of sorts in Excel 2013. The workbook contains a Calculations sheet, a Lists sheet and a sheet for each month of the year. The Lists sheet has a list for names and a list for the months. I have included a link to a sample workbook to demonstrate how the sheets are setup and the basic functions, names, lists, etc that I am using.
My sample workbook:
https://app.box.com/s/mgvums1vmnmnec7e7d0p4vi5daoyo5nv
When looking for the last non-empty cell in a specific row/range, I receive the correct result when I use the following LOOKUP on each specific Month sheet: (Which I found after some digging on a few sites) =LOOKUP(2,1/(C5:AG5<>""),C$4:AG$4)
- For the Month of Feb, the last entry in the range C5:AG5 is in AA5, which is the 25th.
I also receive the correct result when I use the following Lookup from any non-Month sheet: =LOOKUP(2,1/(Feb!C5:AG5<>""),Feb!C$4:AG$4)
That being said, the two specific issues I am running into, are as follows:
I have been unable to work out how to come up with the last non-empty cell (which is the last marked day of attendance) when using Name and Month information selected in the Combo Box/Form Controls. Simply said, in my sample workbook, I want to know the last day in Feb that Johnny was in attendance.
I've tried starting simple, just using the "Month" I selected. I tried a few different itterations of the following:
=LOOKUP(2,1/(Month&"!C5:AG5<>"""),Month&"!C$4:AG$4")
The closest I've gotten was the above Lookup, which ends up turning into what you see below (when viewed in Calculation steps). It of course returns a #VALUE! error.
=LOOKUP(2,1/"Feb!C5:AG5<>""",Month&"!C$4:AG$4")
I also tried this Array Formula and it gave me a result of 4. Which, isn't the proper result. And, I don't know where the result actually came from.
=MAX((INDIRECT(F4&"!"&"C5:AG5")<>"")*(ROW(INDIRECT(F4&"!"&"C$4:AG$4"))))
I have been unable to work out how to come up with the last non-empty cell across all the Month sheets when using the selected Name from the Combo Box/Form Control. Basically, I want to know the last day of the year that Johnny was in attendance. In this sample workbook, that would fall on April 11th. I understand that the formula would just return "11". I believe I can format the result after the fact, using the resulting sheet name. (In this sample case, Apr)
I am fairly certain I will need to use a VLOOKUP. I just can't seem to break the barrier between the general concepts of what I want and the proper way of formulating it.
Any help would be appreciated. I'm feeling pretty lost at the moment. If you need more info from me, please let me know.
Thanks,
Kurewe
The key is to use INDIRECT with the exact same LOOKUP formula you already had and use the MATCH formula to determine the row number for the selected name.
Place the following formulas:
G3: =MATCH(F3,NameList,0)+4 (find the item number of the selected name within NameList)
H2: =F4&"!C4:AG4" (construct the address for the date row for the selected month)
H3: =F4&"!C"&G3&":AG"&G3 (construct the address to use for the selected name and month)
E9: =INDEX(MonthList,ROW()-ROW(E$8)) copy down to E20 (find the name of the month for this row using MonthList)
G9: =E9&"!C4:AG4" copy down to G20 (construct the address for the date row for the month in E9)
H9: =E9&"!C"&G$3&":AG"&G$3 copy down to H20 (construct the address to use for the selected name and the month in E9)
F9: =IFERROR(LOOKUP(2,1/(INDIRECT(H9)<>""),INDIRECT(G9)),"(n/a)") copy down to F20 (find the last day with an "X" in it using the addresses in G9 & H9)
G4: =LOOKUP(2,1/ISNUMBER(F9:F20),ROW(F9:F20)-ROW(F8)) (find the index of the first cell with "(n/a)" in it)
F5: =LOOKUP(2,1/(INDIRECT(H3)<>""),INDIRECT(H2)) (find the last day with an "X" in it for the addresses in H2 & H3)
F6: =INDEX(MonthList,G4)&"-"&INDEX(F9:F20,G4) (construct the date of the last day of attendance within the year)

Resources