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
Related
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.
I have array of numbers in a single column like this:
I want only that numbers for which corresponding negative numbers exist. If number exist 2 times, but negative number exist only one time, then I wanted to retain one positive and one negative number. Similarly, if number exists 3 times, and negative number appears only two times, then I want 2 set of numbers including positive and negative. In this case, I wanted to get output:
5 2 -2 -5
Orders of numbers are not relevant for me. Please do not use VBA. You can create multiple column and apply filter at the end.
Thank you for the response, but I wanted to get the data in column next to the values. Like:
5
2
-2
-5
Please help.
Here's another Office 365 solution:
Name the data range DATA
Put this formula anywhere: =CONCAT(REPT(-ROW(A1:A100)&" "&ROW(A1:A100)&" ",COUNTIF(DATA,"="&ROW(A1:A100)*IF(COUNTIF(DATA,"="&-ROW(A1:A100))<COUNTIF(DATA,"="&ROW(A1:A100)),-1,1))))
That will output the pairs into one cell.
Here's a slightly modified Step 2, which excludes duplicates: =CONCAT(IF((COUNTIF(DATA,"="&-ROW(A1:A100))>0)*(COUNTIF(DATA,"="&ROW(A1:A100))>0),-ROW(A1:A100)&" "&ROW(A1:A100)&" ",""))
Looks like this:
The data doesn't need to be sorted. Both methods work up to 100, but you can easily expand that by changing A100 to A1000 or whatever you need.
Use the vlookup formula to identify the rows, and you can use the Filter & Unique formula to get the list, or a pivot table.
First, immediately next to your data use the formula:
=vlookup(A1*-1,$A$1:$A$1,1,0)
For non-365:
This will produce an error for each instance that doesn't have a match. You can filter at this point to get your list from the existing table. You can also create a pivot table under the Data tab of your ribbon and inserting a pivot table. Filter the #N/A from there to get an exclusive list without hidden rows.
For 365:
You can use the following combination of formulas to get the exclusive list as well.
=UNIQUE(FILTER(B1:B8,ISNUMBER(B1:B8)),0,0) or =UNIQUE(FILTER($B$1:$B$8,ISNUMBER($B$1:$B$8)),0,0) should yield the same results
As ScottCraner mentioned, you can circumvent the helper column in 365 by modifying the formula a bit more:
=UNIQUE(FILTER(A1:A8,ISNUMBER(MATCH(-A1:A8,A1:A8,0)),"")
The Match here is doing something similar to the Vlookup, but housing that logic within the formula, so it's a cleaner solution in my opinion.
Using your data the result was { -5,-2,2,5 }
These are spill formulas so you only need to put it in one spot and it will expand the formula over the adjacent cells below where it's entered for however many cells needed to list all the unique numbers that occur. It takes into account the negatives and so on. This may be a 365 formula, so if you're on another version of excel it may not work.
Edit: Adjusted the instructions to fully address the question.
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'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....
I'm stuck on an Excel problem and am hoping someone can assist. I read through 10-15 topics that are similar, but I wasn't able to get anything to work. Here is where I'm at...
I have a large data set containing columns for Year, Name, Total 1, Total 2 (and 20+ other columns). The same names appear in multiple rows based on the yearly totals. On a separate sheet, I have another data set containing Name and would like to pull the data from sheet one into columns as shown below.
I have done this in the past using only one year as the initial data set with the following formula:
=INDEX(DATARANGE,MATCH([#Name],DATARANGE[Name],0),MATCH("Total 1",DATARANGE[#Headers],0))
The problem I am having is the result of adding multiple years of data to my 1st data set. Is there a way to match the row based on name and year and then return the results of the appropriate column?
=SUM(($A$2:$A$9=B$16)*($B$2:$B$9=$A17)*($C$2:$C$9))
Enter above in cell B14 as an array formula or below as standard
=SUMPRODUCT(($A$2:$A$9=B$16)*($B$2:$B$9=$A17)*($C$2:$C$9))
You can do the same for total 2 just replace Cs with Ds
And then drag right and down.
Change the first MATCH function to something like this:
=MATCH(1,INDEX(([#Name]=DATARANGE[Name])*([#Year]=DATARANGE[Year]),0),0)
so as part of your whole formula that would be this
=INDEX(DATARANGE,MATCH(1,INDEX(([#Name]=DATARANGE[Name])*([#Year]=DATARANGE[Year]),0),0)
,MATCH("Total 1",DATARANGE[#Headers],0))
Another way you can use for returning numbers only (as here) is like this: (with cell refs for simplicity).
=SUMPRODUCT((A2:A9=2013)*(B2:B9="name x")*(C1:D1="Total 1"),C2:D9)
If the presented data to be indexed is a table then
This
=MATCH(1,INDEX(([#Name]=DATARANGE[Name])*([#Year]=DATARANGE[Year]),0),0)
should be corrected to a proper structured reference of
#[Name]
Also since this is an array formula it may not work with structured references at all. You'd be better served with regular cell references. Also if it is not a table only cell references will work.