Indirect reference to thisRow in Excel table - excel

The situation: I have an automatic procedure for gathering data from different input-sheets and presenting in a pivot-friendly format. It appears others are in need of the same data, though they want it formatted slightly differently (and they are not friends with excel). I therefor have a version of my table formatted as they want it (with empty columns where my extract does not contain any data).
The table (both) is one line for each department for each year for each cost/income (from now, cost) category. The raw data contains the cost for each year, though some of the users want it to be cost delta from initial year. I want:
One column for raw cost (X). One column for delta cost (Y). One output column (Z) that contains one of those two values, depending on dropdown selection. The first two columns are situated to the right of the "select with mouse and copy these"-columns, so that I dont need to teach the other users how to select non-adjecent columns :P (just letting u know the level of understanding i have to work with here)
Now the naive approach to this would be to have an if-statement in column Z like this:
=IF(selected_Calc="Use raw cost";[#[X]];[#[Y]])
Alternatively nest more ifs (one for "Use difference to 2019", and potentially add more nesting if more ways to show the value should appear in future)
This works. However, it isnt as elegant as I would like it, and if I indeed end up with more ways to calculate this for other people, it will be a lot of nested ifs.
I was therefore considering something like this:
=INDIRECT("[#["INDEX(mapTab_out;match(selected_Calc;mapTab_in;0))&]]")
But this gives a #ref, and tbh i didn't really expect it to work.
The idea is though: .
Have a range mapTab_in. This has the different selections for the dropdown box.
Have the adjecent range mapTab_out. This has the name of the column (X,Y...) that contains the desired calculation)
Have in column Z a formula for selecting which column's (X,Y...) value is to be displayed in Z
The google-stuff I have found so far all seem interested in using the indirect function from outside the table, and usually want to sum an entire column. I have used this in the past. The "ThisRow" things like using # dont seem to work with indirect though. Any ideas, or have I simply made some beginner-error in my formula?

Assuming it's in the same table, you can take advantage of implicit intersection and simply use:
=INDEX(Tablename,,MATCH(selected_Calc,Tablename[#Headers],0))
where selected_Calc is the name of the column you want back. (You could make that the result of a further INDEX/MATCH if you want to use a lookup table for some reason.)

Related

Use INDEX/MATCH to select formula written as string, and enable it?

I have a pricelist, with currently 5 different categories of products. Each product will have to have two different prices. Depedning of the product and the type of price, the calculation will be different. Therefor I've used INDEX/MATCH to find the formula needed, from a table I created.
Below a screendump, and I wanted to attach the Excel fil, but canøt seem to work out how.
Question: HOW do I then "run" the formula I fetched? -I've tried different suggestions on using EVALUATION, but it doesn't seem to cut it? Also I've tried "Indirect' on the whole formula, without success.
I would like to avoid any VBA for this case.
Can anybody provide some insight?
You could but if I understand properly, the only thing changing in the formulas is the "muliplier" number, then it's better to lookup that number instead of the whole formula. The other method (which would use Evaluate etc) is not be considered "good practice" for a number of reasons.
EDIT:
I didn't see the 2nd varying value (since I was on the SO mobile app) but it's still not an issue since it would a target column. You could be thinking of the opposite: sometimes lookups based on multiple criteria can get complicated, but this a matter of more data, as opposed to adding criteria for the lookup.
VLookup would have been the simplest method, like G2 could have been:
=VLOOKUP(E2, $J$4:$L$8, 2, False)
...to return the second column of range J4:L8 where the first column equals E2. (Then for the next required column, same formula except with 3 instead of 2.)
Since I wasn't sure more columns could be added one day, I allowed for that by, instead of specifying "Column 2 or 3" etc, it finds the column dynamically by name. (So the multiplier/factor used in G2 will change if you change the title in G1 to the name of a different column existing in the target data chart.
For the sake of neatness as well as potential of additional columns like G & H, I moved the lookup table to a separate sheet. It can stay out of the way since you won't need to see or change it very often. (If the same chart was going to be referenced by many workbooks, you could even move it to a separate workbook and point all formulas at that, since it's always best to have one copy of identical data instead of many in different workbooks.
Also to assist with potential future changes (and just to be tidier), instead of referring to the target table range addresses (like "J4:L8" etc) I named two ranges:
the table of multiplier/factor data can be referred to by it's address, or by myMultipliers
the titles of the same table is also called myMultiplierTitles (used to match to the titles of column G & H on the original sheet.
Formula
After those changes, the lookup formula in G2 is:
=INDIRECT(VLOOKUP($E2,myMultipliers,MATCH(G$1,myMultiplierTitles,0),FALSE)&ROW())*VLOOKUP($E2,myMultipliers,MATCH(G$1,myMultiplierTitles,0)+1,FALSE)
INDIRECT returns the value of a cell that you refer to by name (text/string) as opposed to directly (as a range). For example:
=INDIRECT("A1")
returns the same as
=A1
...but with INDIRECT we can get the name from elsewhere (a cell, function or formula). So if x="A1" then =INDIRECT(x) returns the same as the 2 above examples.
Your original plan of storing the entire formula in a table as text would have worked with the help of INDIRECT and/or EVALUATE but I think this way is considered better practice partly because it facilitates easier future expansion.
The formula is longer than it would have been, but that's mostly because it's dynamically reading the field names. And size doesn't matter. :-)

Using AverageIf function on large amount of cells does not behave as expected. What am I doing wrong?

I have an excel spreadsheet that I'm fooling around with attempting to analyze data. I could go the pivot table route possibly, but I like being stubborn and building my own formulas/tables to analyze the data sometimes.
Anyways my problem is this:
I'm trying to find the average of a column of cells (just one column) that contain 'x' value somewhere in the same row. Using the function AverageIf, I can easily do this 'manually', but I'd like to be able to change the 'x' value by editing another cell.
Currently said code looks like this:
=AVERAGEIF($D$2:$D$527,L$2,$I$2:$I$527).
It works fine. But it limits what 'x' value I can sort the Average through to only ones within the D column. I attempted to highlight all the data I would potentially be analyzing like so:
=AVERAGEIF($A$2:$H$527, L$2, $I$2:$I$527)
That just gives me all sorts of issues. I'm obviously not utilizing the If function correctly here, is there anyway to fix this error or am I stuck analyzing column by column for different 'x' values.
Side note, 'x' values are all string text, not an actual digit. Not sure if that makes a difference. And I am attempting to make a small table with this data (not an actual excel table), hence the $ in the formulas, as I'm using the fill option. There are just a ton of different comparisons I could potentially make and I don't like limiting myself.
Also, when I used fill to move this formula over one column, I have a completely different error from the above formula. In the first case, the output is a . .
In the second case the output is a #div/0 error. Only difference in the two formula's is the criteria portion.
The actual code for the second filled formula:
=AVERAGEIF($A$2:$H$527, M$2, $I$2:$I$527)
Though the output is changing based upon the 'x' value. Some work fine after testing a few, most give me issues.
EDIT: Playing around with this for a bit, weird stuff keeps happening. I find it depends where on the 'table' I set up matters to how the average is calculated. In other words, an 'x' value that doesn't work in the first column of my analyzing table will work perfectly fine elsewhere in the table, but only if certain other values are selected in the other spaces of the table. If that doesn't make sense in how I described it, let me know.
EDIT 2: Just going to throw up the data set, DropBox Excel File
The problem is that when using a multi-column range as the first parameter, the "value" range (Col I) in your example gets shifted to the right, according to the location on each row where the "criteria" value is matched.
Simple example:
Using "A" as the criteria get the average from ColF as expected, but using "B" or "C" gets the average from cols G and H respectively.
I think in some cases you're actually averaging numbers in your "analysis" block (which in your posted file is to the right of your data block).

Sumproduct or Countif on a 2D matrix

I'm working on data from a population of people with allergies. Each person has a unique ExceptionID, and each allergen has a unique AllergenID (451 in total).
I have a data table with 2 columns (ExceptionID and AllergenID), where each person's allergies are listed row by row. This means that the ExceptionID column has repeated values for people with multiple allergies, and the AllergenID column has repeated values for the different people who have that allergy.
I am trying to count how many times each pair of allergies is present in this population (e.g. Allergen#107 & Allergen#108, Allergen#107 & Allergen#109,etc). To keep it simple I've created a matrix of 451 rows X 451 columns, representing every pair (twice actually because A/B and B/A are equivalent).
I somehow need to use the row name (allergenID) to lookup the ExceptionID in my data table, and count the cases where that matches the ExceptionIDs from the column name (also AllergenID). I have no problem using Vlookup or Index/Match, but I'm struggling with the correct combination of a lookup and Sumproduct or Countif formula.
Any help is greatly appreciated!
Mike
PS I'm using Excel 2016 if that changes anything.
-=UPDATE=-
So the methods suggested by Dirk and MacroMarc both worked, though I couldn't apply the latter to my full data set (17,000+ rows) because it was taking a long time.
I've since decided to turn this into a VBA macro because we now want to see the counts of triplets instead of pairs.
With the 2 columns you start with, it is as good as impossible... You would need to check every ExceptionID to have 2 different specific AllergenID. Better use a helper-table with ExceptionID as rows and AllergenID as columns (or the opposite... whatever you like). The helper table needs a formula like:
=COUNTIFS($A:$A,$D2,$B:$B,E$1)
Which then can be auto-filled. (The ranges are from my example, you need to change them to your needs).
With this helper-matrix you can easily go for your bigger matrix like this:
=COUNTIFS(E:E,1,INDEX($E:$G,,MATCH($I2,$E$1:$G$1,0)),1)
Again, you can auto-fill with this formula, but you need to change it, so it fits your needs.
Because the columns have the same ID2 (would be your AllergenID), there is no need to lookup them because E:E changes automatically with the auto-fill.
Most important part of the formulas are the $ which should not be messed up, or you can not auto-fill it.
Picture of my self-made example (formulas are from the upper left cell in each table):
If you still have any questions, just ask :)
It can be done straight from your original set-up with array formulas:
Please note that array formulas MUST be entered with Ctrl-Shift-Enter, before copying across and down:
In the example pic, I have NAMED the data ranges $A$2:$A$21 as 'People' and $B$2:$B$21 as 'Allergens' to make it a nicer set-up. You can see in the formula bar how that looks as a formula. However you could use the standard references like this in your first matrix cell:
EDIT: silly me, N function is not needed to turn the booleans into 1's and 0's, since multiplying booleans will do the trick. Below formula works...
SUM(IF(MATCH($A$2:$A$21,$A$2:$A$21,0)=ROW($A$2:$A$21)-1, NOT(ISERROR(MATCH($A$2:$A$21&$E2,$A$2:$A$21&$B$2:$B$21,0)))*NOT(ISERROR(MATCH($A$2:$A$21&F$1, $A$2:$A$21&$B$2:$B$21,0))), 0))
Then copy from F2 across and down. It can be perhaps improved in technique with sumproduct or whatever, but it's just a rough example of the technique....

Excel SUMIFS which adds values if column a, or column b contains a specified value

I've had a look around and can't find a solution, and I don't even know if this is possible.
I have two worksheets. I would like Sheet1!G5 to display the sum of values in Sheet2!D:D where Sheet2!A:A OR Sheet2!B:B is equal to Sheet1!D5.
I know its a bit complex, and like I say I don't even know if it is possible, or if SUMIFS is the correct formula to be using.
see images below for dummy data in the spreadsheets..
basically I want someone to be able to search how many Desktop or how many HP Elitedesk 800 G1 there are (there are more different models of desktops, laptops and monitors etc, but I just don't have them in the dummy data...that's why I want to be able to search both fields.
If my logic is correct you should be able to get away with two separate SUMIF's, one for column A and one for column B, added together:-
=SUMIF(Sheet2!A:A,D5,Sheet2!D:D)+SUMIF(Sheet2!B:B,D5,Sheet2!D:D)
It doesn't look as if it's possible to have the same thing in column A and B for any row, but if so you could make a correction to avoid double-counting as follows:-
=SUMIF(Sheet2!A:A,D5,Sheet2!D:D)+SUMIF(Sheet2!B:B,D5,Sheet2!D:D)-SUMIFS(Sheet2!D:D,Sheet2!A:A,D5,Sheet2!B:B,D5)
The first formula can easily be modified to work with more than two criteria columns (e.g. if you wanted to match on serial number as well), but the second one can't.
To get the total quantity based on more than two columns, where a string can occur more than once in the same row, you would need an array formula like
=SUM(SIGN((Sheet2!A2:A10=D5)+(Sheet2!B2:B10=D5)+(Sheet2!C2:C10=D5))*Sheet2!D2:D10)
which must be entered with CtrlShiftEnter

Using a Named Range for column number look up in VLookup

I have a worksheet that is 200 columns wide. I am using VLookup to return values based off of a date in the first column.
Due to the width of the spreadsheet, troubleshooting (or even determining the column number to use) is a real pain. I tried naming the column, and replacing the column 45 with the name, but I get a Value error.
There are two tabs: recap and Roll-up. In the recap tab, I have:
=VLOOKUP(MONTH($C$4),Rollup,45)
C4 is the date that users want to look up in the named range Rollup first column.
The Rollup range is defined as:
='Roll-up'!$A$2:$FF$15
The formula needs to be something non-power Excel users can understand and use for future growth of their workbooks (not that I don't like doing all their work for them).
Well, I guess you could use something like this:
=VLOOKUP(MONTH($C$4),Rollup,MATCH("(EAF) Equivalent availability factor", INDEX(Rollup,1,0),0),0)
MATCH("(EAF) Equivalent availability factor", INDEX(Rollup,1,0),0) gets the column number in Rollup in which there is (EAF) Equivalent availability factor.
It's not so simple, and if you want, you should also be able to use a simpler:
=VLOOKUP(MONTH($C$4),Rollup,MATCH("(EAF) Equivalent availability factor", 'Roll-up'!$A$2:$FF$2,0),0)
To reduce the number of functions, at most. From experience, non-Excel users usually have difficulty with even understanding how VLOOKUP works, so I guess if they don't understand it at all, it might be better having something that could be more robust to changes such as row insertions.
INDEX(Rollup,1,0) by the way gives the first row in the range Rollup.

Resources