Excel formula - fixing cell reference across multiple worksheets - excel

This is a question for Excel. I have to create similar tables in several worksheets. But the tables are not matched up in terms of the row numbers. For example, table in worksheet one starts on row 48; table in worksheet two starts on row 35, etc. Each table refers to a cell that is 3 rows above the table starts and needs to be fixed for the length of the table. So, in table in worksheet one, the formula needs to refer to cell M45 (three rows above 48); in table in worksheet two, the formula needs to refer to cell M32 (three rows above 35); and so on. If it were just one worksheet, I know that I could fix 32 and refer to M$45. But I do not know how to automate it for the problem described above. The formula I need to automate is:
IF(SUM($L49:$L$61)>=M$45,0,MIN($L48,M$45)).
M$45 needs to be M$32 in worksheet two when I copy the formula over from worksheet one to worksheet two. The other references will also need to be modified accordingly. But once I know how to do one, I can take care of the rest.
Would appreciate any help you can provide.

If you use the following inside the table,
=OFFSET([#Headers], -3, 0, 1, 1)
The formula will adjust to show the table name as in,
=OFFSET(Table1[#Headers], -3, 0, 1, 1)
Copying the table will adjust the internal formula to the new table's name. e.g.
=OFFSET(Table2[#Headers], -3, 0, 1, 1)

Related

Excel - Reference within a reference

I may going up the wrong tree with this.
I have the following formula, that will replace the * with the range of sheets in the workbook, and SUM the values in cell B2 on each of the sheets:
=(SUM('*'!B2)/J2)/100
This works fine, however the formula doesn't retain the '*', it replaces it with the actual range, eg:
=(SUM('Period 1:Period 4'!B2)/J2)/100
So, is it possible to either:
Retain the '*' so that the formula doesn't update, and therefore remains dynamic should I add a new tab.
Add a reference into the reference. The first sheet will always be 'Period 1', however the end sheet will change from month to month, and will be 'Period x', where x is the value in cell J2. Is it possible to reference J2 within =(SUM('Period 1:Period 5'!B2)/J2)/100? =(SUM('Period 1:Period [J2]'!B2)/J2)/100 or something similar?
The only way I know to do this is to create a 'sheet sandwich' with a 'Start' and 'End' sheet then the range is =SUM('Start:End'!B2). New sheets obviously have to be inserted between these to be included.
Note:not my solution, credit belongs to SUM across multiple sheets with variable sheet name question.

How to Extract, Change and Replace Data?

Maybe I have used the wrong phrase to search but I have not been able to find a solution to the following challenge for Excel/VBA:
In Sheet 1 I have a database of order data from cells A1 to F10. Each row contains data for one order. Column A contains the order number.
As first step I, in sheet 2, wish to make a search on the order number and retrieve all data for that order into cells A5 to F5 in sheet 2.
After reviewing the data (and running another macro to recalculate the sales price) I wish to have the revised data replace the original data in sheet 1.
Can anyone help me with this?
Thank you in advance!
The 1st part does not need macro.
vlookup (fkeres magyarul) is your function. If you put this function in A5-F5 fields in sheet 2, looking for a given order number, in Sheet1 $A$1:$F$10, entering the required column number, asking exact match (FALSE), it works nicely. I entered the functions parameters in my previous sentence.
The 2nd part needs macro which makes Copy Paste back.
OR
Look for the requested order row in sheet2 A5 cell with MATCH (HOL.VAN magyarul) function, like =MATCH(A1;Sheet1!A1:A10;0)
and put INDIRECT (INDIREKT magyarul) function, like =INDIRECT("Sheet1!B"&A5;TRUE) in B5, etc.
In this case the Copy-Paste back macro is (starting from Sheet2):
Myorder = Range("A5").Value
Range("B5:F5").Select ' A5 is the row number of order, not the order No
Selection.Copy
Application.Goto Reference:=Worksheets("Munka1").Range("A" & Myorder)
ActiveSheet.Paste
...or very similar

Excel - Use VBA to modify a cell based on the sum of other cells in the row. Loop

In my sheet I would like to hit a button and loop through a series of rows and change A3 to contain "x" if sum(C3:F3) = 0 and "" if sum(C3:F3) > 0 then move to row 4, then row 5 then row 6, etc.
Any help would be appreciated.
Thanks.
do you mean in row 3 use the sum of row 3, in row 4 use the sum of row 4 and put the x also in row 4 and so on?
The easiest is to just use either use the index function (use the easy one where the index is the row into your array, or just write a little program that copies the formulas down, then you have everything automatically correct thanks to the relative references.
If you would post your code / show the row/column setup one could easily answer with the code and/or formulas
No need for VBA. Put this formula in A3 and fill down:
=IF(SUM(C3:F3)=0,"x","")
You can use spreadsheet functions in VBA code, like so:
Dim Res As Variant
Worksheets("MySheet").Activate
Res = Application.WorksheetFunction.SUM("A1:C100")
The worksheet function will act on the currently active worksheet, so be sure to set that first.

Excel chart dynamic range-selection

I have a client that has a simple yet complicated request for an excel sheet setup, and I can't for the world thing of where to start. I'm drawing a blank.
We have a data range. Example:
Quarter Data
2010Q1 1
2010Q2 3
2010Q3 4
2010Q4 1
I have a chart built on top of that. Change data, chart changes, protect worksheet to keep other idi... er... users from changing old data. Simple.
What I want to have happen: When I add the next Q1 below Q4, the chart "automagically" selects the most recent 4Q. So when I update the data to:
Quarter Data
2010Q1 1
2010Q2 3
2010Q3 4
2010Q4 1
2011Q1 7
The chart will show data for the last 4 quarters (2010Q2 thru 2011Q1). The goal being: keep "old" data on the same sheet, but have the charts update to most recent quarters.
I'm thinking: "fixed" data locations, reverse the data (new data at top), and just insert row each new quarter:
Quarter Data
2011Q2 9
2011Q1 7
2010Q4 1
2010Q3 4
2010Q2 3
2010Q1 1
But this will involve a lot of changes to the already existing excel sheets and I was hoping that there may be an easier/better "fix".
EDIT:
#Lance Roberts ~ Running with your suggestion:
- Little more detail... The data is setup such that the column information is in A, but data for multiple tables are in B+. Table 1 is B/C. Table2 is D/E. Etc.
- Data is also on a different sheet than the tables.
Going by: This Offset Description, what I've tried doing is adjusting similar to such:
NAME FORMULA OFFSET(range, rows, columns, height, width )
DATA0 =OFFSET('DATASHEET'!$A$2, COUNTA('DATASHEET'!$A:$A - 8, 0, 8, 1)
DATA1 =OFFSET('DATASHEET'!$A$2, COUNTA('DATASHEET'!$A:$A - 8, 1, 8, 1)
DATA2 =OFFSET('DATASHEET'!$A$2, COUNTA('DATASHEET'!$A:$A - 8, 2, 8, 1)
Goal being to tie the length/location for B/C/etc data to A. So if I add a column on A, stuff tied to Data1/2 adjust accordingly (or 3/4/5/etc, which are different charts on different sheets
)
I want data cells to be picked by the first row, and then an offset number to get data x columns over. Variations on the formula don't seem to be working.
1 issue I haven't solved yet: the data is not aligning properly:
"Data" is always, last column under 2nd to last Quarter. Last quarter is always empty. Data is shifting to the right (in this example, under 3Q10 - NOT under the correct column. 11 should be under 4Q10. 9.5 should be under 2Q10).
I know I'm getting something simple wrong...
Seems to be working. First thing I had to change was CountA - 9 (not CountA - 8). Next was the "column offset" (0, 1, 2, 3,...). Also split some stuff up to make it more compartmentalized (I do have to train someone else how to do this for her reporting needs).
Thanks Lance :)
If the chart is on the same sheet as the data:
Name the first cell of the data (A2) as a named range, say TESTRANGE.
Created a named range MYDATA as the following formula:
=OFFSET(TESTRANGE, COUNTA($A:$A) - 5, 0, 4, 2)
Now, go to the SERIES tab of the chart SOURCE DATA dialog, and change your VALUES statement to:
=Sheet1!MYDATA
Now everytime you add a new row, it'll change the chart.
I know this is an old question, but I wanted to share an alternative that may be easier.
Change your Quarter-Data range to an Excel Table. Select the range, and press Ctrl+T. In the Insert Table, make sure the correct data range is selected, and that My Table Has Headers is checked, and press OK. This converts the simple range into a special data structure with magical properties.
Then make a new range which links to the last four rows of this table, and create a chart based on this new range. This is illustrated below. The table is the specially formatted range in A1:B9 (you can choose a less in-your-face style), and the plotting range is D1:E5.
The formulas in cells D2 through D5 are below. Copy D2:D5 and paste into E2:E5 to complete the formulas in our plotting range.
D2: =INDEX(Table1[Quarter],ROWS(Table1[Quarter])-3)
D3: =INDEX(Table1[Quarter],ROWS(Table1[Quarter])-2)
D4: =INDEX(Table1[Quarter],ROWS(Table1[Quarter])-1)
D5: =INDEX(Table1[Quarter],ROWS(Table1[Quarter]))
Table1 is the name assigned to the Table, and Quarter is the name of the first column of the Table (and also the column header). You don't need to type all this, just select the column in the Table. As the Table expands or contracts, Table1[Quarter] keeps track of the changes.
Now add a new data point. The Table expands, and our little staging area in D1:E5 links to the new last four rows of the table.
And as we add years worth of data, the formulas and the chart keep up.

Excel charts - setting series end dynamically

I've got a spreadsheet with plenty of graphs in it and one sheet with loads of data feeding those graphs.
I've plotted the data on each graph using
=Sheet1!$C5:$C$3000
This basically just plots the values in C5 to C3000 on a graph.
Regularly though I just want to look at a subset of the data i.e. I might just want to look at the first 1000 rows for example. Currently to do this I have to modify the formula in each of my graphs which takes time.
Would you know a way to simplify this? Ideally if I could just have a cell on single sheet that it reads in the row number from and plots all the graphs from C5 to C 'row number' would be best.
Any help would be much appreciated.
OK, I had to do a little more research, here's how to make it work,
completely within the spreadsheet (without VBA):
Using A1 as the end of your desired range,
and the chart being on the same sheet as the data:
Name the first cell of the data (C5) as a named range, say TESTRANGE.
Created a named range MYDATA as the following formula:
=OFFSET(TESTRANGE, 0, 0, Sheet1!$A$1, 1)
Now, go to the SERIES tab of the chart SOURCE DATA dialog,
and change your VALUES statement to:
=Sheet1!MYDATA
Now everytime you change the A1 cell value, it'll change the chart.
Thanks to Robert Mearns for catching the flaws in my previous answer.
This can be achieved in two steps:
Create a dynamic named range
Add some VBA code to update the charts data source to the named range
Create a dynamic named Range
Enter the number of rows in your data range into a cell on your data sheet.
Create a named range on your data sheet (Insert - Name - Define) called MyRange that has a formula similar this:
=OFFSET(Sheet1!$A$1,0,0,Sheet1!$D$1,3)
Update the formula to match your layout
Sheet1!$A$1 set this to the top left hand side of your data range
Sheet1!$D$1 set this to the cell containing the number of rows
3 set this value to the number of columns
Test that the named range is working:
Select the dropdown menus Edit - Go To, type MyRange into the reference field.
Your data area for the chart should be selected.
Add some VBA code
Open the VBA IDE (Alt-F11)
Select Sheet1 in the VBAProject window and insert this code
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address <> "$D$1" Then Exit Sub
'Change $D$1 to the cell where you have entered the number of rows
'When the sheet changes, code checks to see if the cell $D$1 has changed
ThisWorkbook.Sheets("Sheet1").ChartObjects(1).Chart.SetSourceData _
Source:=ThisWorkbook.Sheets("Sheet1").Range("MyRange")
' ThisWorkbook.Sheets("Chart1").SetSourceData _
Source:=ThisWorkbook.Sheets("Sheet1").Range("MyRange")
'The first line of code assumes that chart is embedded into Sheet1
'The second line assumes that the chart is in its own chart sheet
'Uncomment and change as required
'Add more code here to update all the other charts
End Sub
Things to watch for
Do not directly use the named range as the data source for the chart. If you enter the named range "MyRange" as the Source Data - Data Range for the chart, Excel will automatically convert the named range into an actual range. Any future changes to your named range will therefore not update your chart.
Performance might be impacted by the approaches listed above.
The OFFSET function in the named range is "volatile" which means that it recalculates whenever any cell in the workbook calculates. If performance is an issue, replace it with the INDEX formula.
=Sheet1!$A$1:INDEX(Sheet1!$1:$65536,Sheet1!$D$1,2)
The code fires everytime data is changed on Sheet1. If performance is an issue, change the code to run only when requested (i.e. via a button or menu).
You could look at dynamic ranges. If you use the OFFSET function, you can specify a starting cell and the number of rows and columns to select. This site has some useful information about assigning a name to an OFFSET range.
You can set the range for a chart dynamically in Excel. You can use something like the following VBA code to do it:
Private Sub Worksheet_Change(ByVal Target as Range)
Select Case Target
Case Cells(14, 2)
Sheet1.ChartObjects(1).Chart.SetSourceData Range("$C5:$C$" & Cells(14,2))
...
End Select
End Sub
In this case, the cell containing the number of the last row to include is B14 (remember row first when referring to the Cells object). You could also use a variable instead of the Cells reference if you wanted to do this entirely in code. (This works in both 2007 and 2003.) You can assign this procedure to a button and click it to refresh your chart once you update the cell containing the last row.
However, this may not be precisely what you want to do ... I am not aware of a way to use a formula directly within a chart to specify source data.
Edit: And as PConroy points out in a comment, you could put this code in the Change event for that worksheet, so that neither a button nor a key combination is necessary to run the code. You can also add code so that it updates each chart only when the matching cell is edited.
I've updated the example above to reflect this.
+1s for the name solution.
Note that names don't really really reference ranges, they reference formulae. That's why you can set a name to something like "=OFFSET(...)" or "=COUNT(...)". You can create named constants, just make the name reference something like "=42".
Named formulae and array formulae are the two worksheet techniques that I find myself applying to not-quite-power-user worksheets over and over again.
An easy way to do this is to just hide the rows/columns you don't want included - when you go to the graph it automatically excludes the hidden rows/columns
Enhancing the answer of #Robert Mearns, here's how to use dynamic cells ranges for graphs using only the Excel's formulas (no VBA required):
Create a dynamic named Range
Say you have 3 columns like:
A5 | Time | Data1 | Data2 |
A6 | 00:00 | 123123 | 234234 |
...
A3000 | 16:54 | 678678 | 987987 |
Now, the range of your data may change according to the data you may have, like you have 20 rows of data, 3000 rows of data or even 25000 rows of data. You want to have a graph that will be updated automatically without the need to re-set the range of your data every time you update the data itself.
Here's how to do it simply:
Define another cell that it's value will have the number of the occupied cells with data, and put the formula =COUNTIF(A:A,"<>"&"") in it. For example, this will be in cell D1.
Go to "Formulas" tab -> "Define Name" to define a name range.
In the "New Name" window:
i. Give your data range a name, like DataRange for example.
ii. In the "Refers to" set the formula to: =OFFSET(Sheet1!$A$1, 0, 0,Sheet1!$D$1,3),
where:
Sheet1!$A$1 => Reference: is the Reference from which you want to base the offset.
0 => Rows: is the number of rows, up or down, that you want the upper-left cell of the results to refer to.
0 => Columns: is the number of columns, to the left or right, that you want the upper-left cell of the results to refer to.
Sheet1!$D$1 => Height: is the height, in number of rows, that you want the result to be.
3 => Width: is the width, in number of columns, that you want the result to be.
Add a Graph, and in the "Select Data Source" window, in the Chart data range, insert the formula as you created. For the example: =Sheet1!DataRange
The Cons: If you directly use the named range as the data source for the chart, Excel will automatically convert the named range into an actual range. Any future changes to your named range will therefore not update your chart.
For that you need to edit the chart and re-set the range to =Sheet1!DataRange every time. This may not be so usable, but it's better than editing the range manually...

Resources