Data source start and end range variables - excel

Hopefully the title is sort of correct...
To try to explain; I'm pulling a ton of data from a PLC into a spreadsheet. I've got a graph to display two series against time. Because of the sheer amount of data I'm limiting the series values with a range ='Retrieve Data'!$D$400:$D$2000 for example.
Both legend entries and the horizontal axis should be across the same range, currently to show a different window of time on the graph I need to edit these all individually to the same series range within their respective columns.
Is there a way I can use two cells, one as start and one as end point in the formula, something like:
='Retrieve Data'!$D$("W6"):$D$("X6") where W6 is start of range and X6 is end of range?
Else would I need to look into use VBA?

You could use the INDIRECT function:
=INDIRECT("'Retrieve Data'!$D$" & W6 & ":$D$" & X6)
Note that INDIRECT is a volatile function and you should avoid heavy use because it can slow down a lot.
If you plan to use this in a chart data range it will not work because chart data ranges have to have a fixed address.
There is a way around this, and that's using named ranges
In name manager, define a name MyChartRange using the formula above. Then use =MyChartRange as address in your cart data.

Related

How do you average repeating blocks of cells in Excel?

I am trying to figure out how to average 4 x 4 groups of cells in my spreadsheet across a very large data set. I've tried using OFFSET with a cell range (e.g. B2:E5) but I haven't had success (I don't even know if you can use a range for the reference with OFFSET). This is my first time tackling a problem like this, so any advice would be welcome! A portion of the data set is attached to give an idea of the ranges I would like to average.
If the data was in B2:Q17 you could use this complicated looking formula to return the average for each 4*4 block.
=AVERAGE(INDEX($B$2:$Q$17,(ROWS($2:2)-1)*4+1,(COLUMNS($R:R)-1)*4+1):INDEX($B$2:$Q$17,(ROWS($2:2)-1)*4+4,(COLUMNS($R:R)-1)*4+4))
You would copy this across and down and it could go anywhere on a sheet.
You can use INDEX to refer to a range derived from values fro TopLeft and BottomRight corners, in the form
INDEX(DataRange, TopRow, LeftCol):INDEX(DataRange, BottomRow, RightCol)
Then wrap that in AVERAGE(...)
To demonstrate
=AVERAGE(INDEX($B$7:$AH$903,B1,B2):INDEX($B$7:$AH$903,B3+B1-1,B4+B2-1))
Note: INDEX has the advantage over OFFSET in that it's non-volatle

Excel dynamic graph range

Without using VBA macros, is it possible to dynamically set the range of a graph?
I have a table like this:
I want to now create a graph with merely the "valid" amounts of 2,3,4 and 5 as bar chart, say. These valid ranges can change however to 3,4 and 5 say. The valid numbers are always consecutive. so I just need the beginning and end.
I've looked into index, match, and offset, and I just don't get how to accomplish this exactly.
Thanks in advance.
My answer in a nutshell as I have to leave in a few minutes. (I can add details later, if you are interested).
As far as I know, Excel charts do neither allow range names or formula as input, which makes it difficult to set a dynamic range without a VBA macro.
However, if you are only interested in a chart that grows and shrinks with the data, you can use a XY chart do achieve the desired result.
Formulas:
D2: =IF(COUNTBLANK(A2)=1,#NA,COUNTIFS(D$1:D1,">=0")+1)
E2: =D2
F2: =IF(COUNTBLANK(C2)=1,#NA,0)
G2: =IF(COUNTBLANK(C2)=1,#NA,C2)
Chart properties
Just create the maximum number of rows (here 7)
Set the stroke/line width to 30.
Ajust the x-axis to start with 0.5.
Note: Screenshots were made with a German Excel version.
Downsite: The x-axis labels cannot be adjusted easily.

Scatter Plot in Excel using VBA

I have one column that contains my x data and two columns that contain my y data. I would like to plot y against x, but the length of each column is dependent on a counter variable, i. I do not have experience with vba, but do with coding. Can someone outline the correct syntax to perform this task?
Please and Thank you!
You could goto your 'Developer' tab, and record a macro. While in record mode, create the graph using the data and specifications you desire.
End recording of the macro, and you will then have a template of VBA code (ALT+F11) to work with as a foundation.
It sounds like the best solution is to simply make the X-Y scatter plot ranges longer than you ever expect the data to be (Excel will ignore the blank rows).
But if you want to get fancy, you can populate your scatter plot data with dynamic named ranges that automatically adjust to the length of your data without bothering with VBA:
Create a dynamic named range (AKA named formula) representing your X data column.
Example (assuming column A, and data starting at A1):
=$A$1:INDEX($A$1:$A$1000,MATCH(TRUE,ISBLANK(Sheet1!$A$1:$A$1000),0)-1)
Change $A$1 so that it corresponds to the first row of your data. Change $A$1000 to a row number that is longer than you ever expect your data to be.
Call the named formula above "XColumn" or something similar. To make a named range, do Formulas->Define Name.
Set the X range of your scatter plot equal to:
=Sheet1!XColumn
Note that Excel's plotting window will give an error (devoid of any helpful information regarding how to fix the problem!) if you try to input the named range without the sheet name, even if the named range is scoped to the entire workbook, and even if it's on the same worksheet! -- Annoying, right?
Do this for each column and scatter plot range (Y1 = Y1Column, Y2 = Y2Column, etc.).
Note that this will not work correctly if your columnar data contains text, blanks, errors, etc., but the method can be modified to handle these issues.
To test and make sure your dynamic named ranges are being created as expected, in any cell you can enter:
=SUMPRODUCT(XColumn)
Then do Formulas-->Evaluate Formula-->Evaluate to make sure the XColumn array contains the data you want it to contain.
Optional tip: create another named range called FirstColumn set to the location of the first column, e.g. $A:$A. Make another named range called FirstRow and set it to the location of the first row, e.g. $1:$1. Make yet another named range called MaxRow and set it to the maximum length you ever expect your data to be, e.g. $1000:$1000. Finally:
Replace all instances of $A$1 above with:
INDEX(FirstRow,0,COLUMN(FirstColumn)+<DATA TABLE COLUMN NUMBER - 1>)
Replace all instances of $A$1000 with:
INDEX(MaxRow,0,COLUMN(FirstColumn)+<DATA TABLE COLUMN NUMBER - 1>)
<DATA TABLE COLUMN NUMBER - 1> will be different for each named formula (e.g. 0 for XColumn, 1 for Y1Column, 2 for Y2Column, etc etc).
Now if you ever want to create new data tables and scatter plots in different locations, instead of doing all of the work over again you can just copy and paste your named ranges and you only have to change one or two things instead of 15! Additionally, if the data ever gets longer than you expected, you only have to change one thing instead of 3.
Excel's built-in Table functionality is a great way to automatically increase a range-size when new data is added. Simply select your data, then either press Ctrl + t or go to Insert > Table. Then when you reference your new Table from the Chart it will increase as your data does.

Dynamic chart range using INDIRECT: That function is not valid (despite range highlighted)

I'm trying to create a chart with a range built dynamically using the INDIRECT function. Excel does recognize the range I am creating using INDIRECT as it highlights the corresponding range on the sheet:
However when saving the chart, I get an error message saying the function is not valid:
Does anybody know what the problem is / how to create a dynamic chart range from a specific start to specific end point?
PS: You can download the above spreadsheet here. The formula I was using:
=INDIRECT("sheet!"&E2&":"&E3)
The way you are trying to do it is not possible. Chart data range has to have a fixed address.
There is a way around this, and that's using named ranges
Put the number of rows you want in your data in a cell (e.g., E1)
So, using your example, I put Number of Rows in D1 and 6 in E1
In name manager, define the names for your data and titles
I used xrange and yrange, and defined them as:
xrange: =OFFSET(Sheet1!$A$2,0,0,Sheet1!$E$1)
yrange: =OFFSET(Sheet1!$B$2,0,0,Sheet1!$E$1)
now, to your chart - you need to know the name of the workbook (once you have it set up, Excel's function of tracking changes will make sure the reference remains correct, regardless of any rename)
Leave the Chart data range blank
for the Legend Entries (Series), enter the title as usual, and then the name you defined for the data (note that the workbook name is required for using named ranges)
for the Horizontal (Category) Axis Labels, enter the name you defined for the labels
now, by changing the number in E1, you will see the chart change:
Mine is similar to Sean's excellent answer, but allows a start and end day. First create two named ranges that use Index/Match formulas to pick the begin and end days based on E2 and E3:
rngDay
=INDEX(Sheet1!$A:$A,MATCH(Sheet1!$E$2,Sheet1!$A:$A,0)):INDEX(Sheet1!$A:$A,MATCH(Sheet1!$E$3,Sheet1!$A:$A,0))
rngValue
=INDEX(Sheet1!$B:$B,MATCH(Sheet1!$E$2,Sheet1!$A:$A,0)):INDEX(Sheet1!$B:$B,MATCH(Sheet1!$E$3,Sheet1!$A:$A,0))
You can then click the series in the chart and modify the formula to:
=SERIES(Sheet1!$B$1,Sheet1!rngDay,Sheet1!rngValue,1)
Here's a nice Chandoo post on how to use dynamic ranges in charts.
Just another answer for bits and googles..
If you still want to refer to your start and end cells, you'll need to add a separate formula for your Day Range and your Values Range. Formulas are below and the screenshot shows the formulas used.
Day Range:
="Sheet1!"&$F$2&":"&ADDRESS(ROW(INDIRECT($F$3)),COLUMN(INDIRECT($F$2)))
Values Range:
="Sheet1!"&ADDRESS(ROW(INDIRECT($F$2)),COLUMN(INDIRECT($F$3)))&":"&$F$3
Then add two ranges referencing the INDIRECT values of those cells
Press Ctrl+F3, Click New, and add a new range with the name "chart_days", referring to =INDIRECT(Sheet1!$F$4); and a new range with the name "chart_values", referring to =INDIRECT(Sheet1!$F$5)
Finally, in your chart, add a series that refers to =nameOfYourWorkbook!chart_values
and Edit the category to refer to =nameOfYourWorkbook!chart_days
I use OFFSET to create a defined name formula so that I may define all the ranges for the data, allowing me to have a starting a ending date (or the beginning and ending position of any data set).
For a simple graph, I define the name CategoryLabels as follows:
= OFFSET($A$5; (InicitialMonth-1); 0; LastMonth - (InitialMonth-1))
and DataCars as follows:
= OFFSET($B$5; (InicitialMonth-1); 0; LastMonth - (InitialMonth-1))
You will have to define as many names as Series you want to include, following the same procedure. In this simple case, I only included Car sales.
Initial Month and Last Month are Range Names defined for single cells used to indicate which months of the graph will be included (from starting to ending months).
Remember, as explained by Sean Cheshire and others, that to use the names for the chart values, the name of the spreadsheet must be included.
According to the formula you have shown: =INDIRECT("sheet!"&E2&":"&E3)
you are not naming the sheet correctly.
I would have thought it would be Sheet1! or Sheet2! etc.
Your formula resolves to =sheet!E2:E3 which is not a valid address. The error message you are getting means Excel cannot resolve the input to INDIRECT. INDIRECT is a valid function so the argument you offer it must be invalid.
All of the above answers which state the sheet name have corrected your error but do not mention it... ;)
Named formula with Indirect functions DOES NOT WORK IN CHARTS. It works in other froms as your desired dynamic source will be highlighted, but when you it in chart, it would not be evaluated. Hope Microsoft put a fix on this.
When a line chart's range is a named variable, and the variable has INDIRECT() references through a cell to a range, then the variable must have at least 2 INDIRECT()s separated by a comma.

Modifying a Dynamic Name with VBA

I have a spreadsheet that links to several other spreadsheets to pull data that compiled into one sheet; I am tasked with modifying the sheet to graph this data. There is a row of 12 slots for each month in a person's report; if a person was working in a month then the month will be displayed in the appropriate slot. For the graph I have figured out to use a dynamic name range so that the number of months in the graph is equal the number of months present in the line; the only problem is that the start pointing changes based on what month a person started.
I am able to make a rather large nested if statement but that doesn't seem like a very good way to approach resolving my problem. Is there a way I can have a VBA script change the value of the dynamic name range or just modify the chart's value directly? If this isn't a viable option is there any other way to approach this problem other than a dynamic named range?
I can't change how this report sheet behaves as this is a spreadsheet related to work and that's how they want it to be for reporting reasons; I'm simply looking to add the graphing functionality.
EXAMPLES:
https://www.dropbox.com/s/zn6yt4l6kjvwq33/Example1.xlsx
https://www.dropbox.com/s/j88tgoik68s4lhx/Example2.xlsx
In the first example you see an example of the problem when you select "Second" from the dropbox next to Agent Name. It's including pointless data in the graph.
In the 2nd example I have resolved the problem by adding an if statement to the dynamic named ranges used in the chart; but as you can see to include 2 months it's now massive and to include all 12 it would be pretty much impossible. If I were to add a 3rd person who started in March they would also not work in the 2nd example.
Is there a way I can make it so the values in the Dynamic name range are changeable through VBA? Can I modify the chart's values directly using VBA? Is there a way to bypass this problem without even using VBA?
Thanks.
(I'm not 100% certain I've understood the problem, but this might at least help to get closer...)
Try defining three names, something like this:
start_month
data
chart_data
Where start_month contains the number of the column that you want to be charted, data is all twelve columns of data, something like =OFFSET($C$1,0,0,COUNT($A:$A),12) and chart_data selects the column you want from the data, e.g. =INDEX(data, , start_month)
Now set your chart's series to WorkbookName!chart_data, using whatever your workbook's called. As the start_month value changes, so should the values displayed in the chart.
You can add or modify a Name in VBA like:
Dim nm As Name
Dim rng As Range
'Here, you could use a more complicated expression'
' to derive the proper address dynamically.'
Set rng = Sheets("Sheet1").Range("A2:A25")
'Now, add a Name to the workbook:'
Set nm = ActiveWorkbook.Names.Add("My_Name", rng)
With some string functions/variables, you could derive/caclulate the range address in VBA.

Resources