Using a variable for a data reference in COUNTIFS - excel

I am summarizing data from a table in another workbook using sth like
COUNTIFS(filename.xlsm!Sheet[DataReference];">=1/1/2021";filename.xlsm!Sheet[DataReference];"<=31/3/2021")
I have create these formulas for 16 quarters and am using the same formula for many data references. To avoid errors (and trying to save manually editing the data reference in every cell twice), I would like to have a field in my row that holds the value for "DataReference" and use that as a variable inside the reference. This way I can copy&paste the formula in many rows and only need to plug in the right data reference and avoid further errors/inconsistencies.
But neither by googling nor by trial and error have I found a way for Excel to accept a variable inside the brackets

I found it! I need to use INDIRECT and build the path:
COUNTIF(INDIRECT(<cellwithfilename>&"!"&<Cell with worksheet name>&"["&<cell with data range>&"]"; ....

Related

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

Vlookup with nested if's and variable range

I've been trying to get a Vlookup to work more efficiently without VBA with I think is a dynamic (name) range, and without nested IF functions.
I'm new here and have tried to find the solution with other posts, but couldn't work it out.
I have one workbook with item codes and a vlookup, which references to another closed workbook (so function Indirect doesn't work) with cost values. In cell D3 there is a data validation cell where the user can select which sheet in the other workbook should be referenced (e.g. File001 or File002), changing the Vlookup and returning the correct cost.
Unfortunately I can't get it to work more efficiently.
I've tried Indirect, but that only works when the other workbook is open and I need it to be closed.
I'd like something simple such as:
=VLOOKUP(B3,INDIRECT("'[Book3.xlsx]" & D3 & "'!A3:B6"),2,FALSE)
which doesn't work
...and not what I use now, where it checks every time if it is File001, or 002, or 003,.. etc. and then vlookup:
=IFNA(IFS($K$2="","?",$K$2="File001",PROPER(VLOOKUP(UPPER($E13),NameRange001,4,FALSE)),$K$2="File0002",PROPER(VLOOKUP(UPPER($E13),NameRange002,4,FALSE)),$K$2="File003",PROPER(VLOOKUP(UPPER($E13),NameRange003,4,FALSE)),$K$2="File004",PROPER(VLOOKUP(UPPER($E13),NameRange004,4,FALSE)),$K$2="File005",PROPER(VLOOKUP(UPPER($E13),NameRange005,4,FALSE)),$K$2="File006",PROPER(VLOOKUP(UPPER($E13),NameRange006,4,FALSE))),"")
Code example:
I need to add more sheets from the other wb, so e.g. up to File0030, making the nested IFs extremely long. Does anyone please have an idea how to make this work more efficiently? I've been trying to improve this for maaany days.
Thanks in advance!!

How can you dynamically change an Excel table column reference?

I have multiple Excel tables storing numeric values. I am summarizing a rows values like this:
=+SUM(Query_Current_Year[#[Begin_Balance]:[Balance_Period6]])
Every month, I need to update each table like this:
=+SUM(Query_Current_Year[#[Begin_Balance]:[Balance_Period7]])
Is there a way to store the current column string in a cell like A1 with the value of "Balance_Period6", then reference cell A1? Each month, I would only need to update one field.
I can think of numerous reasons to need this, so I am certain there is a solution.
While I don't understand every detail of the logic, this is the fix.
'''=SUM(INDIRECT("_2360_2860["&A7&"]"))'''
You need to wrap the full table reference in an indirect function. I was hoping for something more readable but it works.

Using Index & Match in Excel; why don't named ranges work?

I have a table that I am using to summarize some data from other tables; the data is almost entirely text so a pivot table isn't the answer. I have a table on a worksheet as follows...
Here is a typical formula for columns D:L...
FORMULA: =INDEX(tblITPM,MATCH(tblHCSmry[[#Headers],[Data Source]],tblITPM[[#All],[Column1]],0),MATCH([#MetricName],'SheetA'!$A$2:$D$2,0))
Individally, the formulae seem to work fine but the total of the calculations only works in the first 3 rows of my summary table (tblHCSmry). There are two issues that I don't know how to solve:
In the "array" section of the INDEX I am referencing table
names that are listed in column B (TableName); hard-coding like I
have above (tblTableA) makes all of the items that need to reference
a separate table on a separate worksheet to fail.
The MATCH formula (MATCH([#MetricName],'1_ITPM_Summary'!$A2:$D2,0)) have a similar issue; I get the correct answer for the first 3 tables (2, 3, or 4) which I expect since the "lookup_array" is hard-coded. So, the issue again arises though when I want to reference a different table such as tblTableB by pointing to Column B of tblHCSmry.
I suppose the main question is: can I use a named range of a table, or do I need to use the "'SheetA'!A3:D3" format? If so, is there a way to dynamically change, "'SheetA'!" to "'SheetB'!" by referencing Column B of the tblHCSmry? FWIW: I tried to CONCATENATE the Sheet name with the reference and that didn't work.
You can use named ranges, but you'd need to have pointers to the location of the data in cells, which appears to be what you already have in Columns A and B. You can then reference those dynamically using using =INDIRECT(). =INDIRECT() allows you to take a value of a cell and use that as a reference as opposed to the reference being to the cell itself.
For instance
=INDEX(INDIRECT([#TableName]),MATCH(tblHCSmry[[#Headers],[Data Source]],tblITPM[[#All],[Column1]],0),MATCH([#MetricName],INDIRECT("'" & [#TabName] & "'!$A$2:$D$2"),0))
Would make your return array whatever is referenced in [#TableName], and your array parameter in your second MATCH function would be whatever is referenced in [#TabName]
MSDN has very basic documentation of INDIRECT() here, but there's quite a bit you can accomplish with it as far as creating more dynamic formulas.

Run a text formula in an adjacent cell

I'm having trouble trying to figure out a way to have two columns, one to show the entire formula that can be editable and the second to actually perform the formula.
Ideally, I would like my sheet to be set up like this:
Formula | Value
=5+2 | 7
=3-2 | 1
I would like to be able to change the Formula column and have it automatically update the Value column.
I've tried using the GetFormula() function but I don't think that's what I want to do as I would end up in a circular reference based on what I want to do. The closest I've got is using a Right() function and Text in the formula column or a space and removing the space. However, I end up with the text and not the solved formula instead.
Using =RIGHT(A2, LEN(A2)-1)
Formula | Value
=5+2 | =5+2
I have also tried using =RIGHT(A2,LEN(A2)-1) but without the "=" and can't figure out how to convert the "5+2" into text that I can use to solve. I'm hoping to do this with a formula and without a macro/VBA.
Here is how to do it.
1
Open the Name Manager. Control-F3 from the worksheet, and then click the New button.
2
For the Name field in the dialog, enter EVALA. I just picked this name; it stands for "Evaluate A". But you can pick whatever name you like.
3
For the Refers to field, enter this
=EVALUATE($A1)
4
Click OK and then Close.
5
In B1 enter this formula:
=EVALA
That's it.
You can now use this formula on any row in the worksheet and it will evaluate whatever is in the column A cell of the row where you enter the formula.
You can make a user defined function easily enough with VBA, but if you don't regularly use VBA then an alternative method is to create a Name object. Name objects can access certain functions not typically available in a cell's formula. One of these functions is "Evaluate" which will evaluate a string as a mathematical expression. Here's a demonstration how to do this.
NOTE: Pay special attention to the use of $. Chances are you don't want any $ in your name definition since that will prevent it from behaving in a relative manner. Also, Sheet1! means that this will not work on another sheet.
Update I just want to give credit for this method to the following sources. This is pretty neat stuff, so for anyone interested give it a read. The last link in particular gives a neat example of creating a chart with no data points.
MSDN Evaluating Defined Names
The power of evaluate (ozgrid)
XL4 Macro Functions in Names - JKP
Evaluate and Indirect
More unique functionality of Defined Names
This is probably the best solution for the OP, since it asks to avoid using VBA; however, this method is somewhat limited. It requires manual set-up on every sheet to be used. Much preferable I think is to create a very simple UDF like this...
Function Eval(Expr As String)
Eval = Application.Evaluate(Expr)
End Function
This can be added to any accessible add-in, making it available to any instance of Excel. A little more set-up, but less maintenance.
Just put a single ' before the formula in your A column:
'=5+2 will show in your cell as "=5+2". Then in the B column, just do the formula as normal, =5+2.

Resources