Authoritative Excel range syntax reference - excel

Sorry if this has been asked before but I can't find it. I am looking for an authoritative description of all valid strings that can be used as a reference, e.g., "A1:C5", "$A:$A", $A2" etc etc. That seems a pretty basic thing yet I've wasted hours trying to locate it. All I can find is a swamp of "helpful" examples but no reference.

This seems like a fun exercise. I'm going to list as many as I can, and hopefully other people could point out ones that I've forgotten/missed/didn't know about.
A sort-of guide to what you're asking for, and a source for anyone looking for additional documentaion: http://www.excelfunctions.net/Excel-Reference-Styles.html
I'm going to start with 5 broad categories - A1, R1C1, Table, Formulas, and VBA references. I'm going to ignore other programs that can interact with Excel for the moment (Although I might add in Python if that's officially added in)
All examples will be using A1 reference style, since they're more intuitive for an inexperienced user.
A1 Reference type:
A1 style tells us the coordinates of a given cell. The alphanumeric portion tells us which column we're in, while the numeric portion tells us which row we're in.
Cell References:
A1 - The basic cell reference. References the cell A1, and as you drag formulas through columns and rows, it'll change. For example, if your formula is in C1, and you move it to D2, it'll now reference B2.
Good use: Comparing two sheets to each other. ='Sheet1'!A1='Sheet2'!A1 will compare the data in sheet 1 to sheet 2, and give a true/false if they match or not. Formula can easily be slid sideways and up/down for additional comparisons.
$A1 - This locks the column. As you drag formulas, the row will change, but the column won't. Useful if you always want to reference the same column in a formula. For example, if your formula is in C1, and you move it to D2, it'll now reference $A2.
Useful example: Formulas in helper columns. A1 = $C1*2 will neatly slide down without any issues, and if you move it over to the B column, it'll continue to reference C.
A$1 - This locks the row. As you drag formulas, the column will change, but the row won't. Useful if you always want to reference the same row in a formula. For example, if your formula is in C1, and you move it to D2, it'll now reference B$1.
$A$1 - This locks the cell reference. No matter how you drag the formulas around, it'll continue to reference cell A1. For example, if your formula is in C1, and you move it to D2, it'll now reference $A$1.
Useful example: Constant multiplier for all numbers.
To summarize, A1 References are broken out as follows:
Alphanumeric portion - What column we're in
Numeric portion - What row we're in
$ - Locking the portion immediately following
Range References:
Due to the sheer number of combinations of range references, I'm sicking to the most common. Mixing and matching types of cell references with types of range references will get every combination.
A1:B2 - References the grid of cells with A1 being at the top-left, and B2 being at the bottom-right. Both parts of the formula will slide when moved. It's generally recommended not to have unlocked references in formulas applied over multiple cells, since the reference range will also move. For example, if you have =Sum(A1:B2) in C1, and you move it to D2, it will transform to =Sum(B2:C3).
Unlocked range references most often cause problems in vlookup formulas, where the reference range ends up changing as people slide the formula down.
$A$1:$B$2 - References the grid of cells with A1 being at the top-left, and B2 being at the bottom-right. This range reference won't change, even when moved. For example, if you have =Sum($A$1:$B$2) in C1, and you move it to D2, it will transform to =Sum($A$1:$B$2)
$A$1:A2 - This locks the first cell, but leaves the second part of the reference flexible. This is very useful when you want to see "Everything that's happened so far"- For example, if you're numbering a list, when combined with =countifs ("What instance of occurrence is this one?") For example, if you have =Sum($A$1:A2) in C1, and you move it to D2, it will transform to =Sum($A$1:B3)
Similar effects can be used with $A$1:B1 going horizontally.
A:A - This gives the entire column A. Since this is unlocked, it'll slide. Useful for grabbing everything in a given column. For example, if you have =Sum(A:A) in C1, and you move it to D2, it will transform to =Sum(B:B)
$A:A - This gives the entire column A. This will expand as you go across to grab more columns. I can't think of an immediate practical use for it. For example, if you have =Sum($A:A) in C1, and you move it to D2, it will transform to =Sum($A:B)
$A:$A - This gives the entire column A. This is locked to column A, even if you move the formulas around. For example, if you have =Sum($A:$A) in C1, and you move it to D2, it will stay as =Sum($A:$A)
Slightly lesser known are rows:
1:1 - The entire first row. Unlocked. For example, if you have =Sum(1:1) in C2, and you move it to D3, it will transform to =Sum(2:2)
$1:1 - The entire first row. Partially locked. For example, if you have =Sum($1:1) in C2, and you move it to D3, it will transform to =Sum($1:2)
$1:$1 - The entire first row. Completely locked. For example, if you have =Sum($1:$1) in C2, and you move it to D3, it will stay as =Sum($1:$1)
R1C1 References
R1C1 is more of a reference style as opposed to a coordinate style. This can be extremely useful, since your formulas in all of your cells look exactly the same, and makes entering sliding formulas in VBA significantly easier.
R1C2 is broken down as such:
R - Rows
1 - Row 1 OR
[1] - We're 1 row down from our current cell
C - Columns
1 - column 1 OR
[1] - We're 1 column over from our current cell
In other words, if you don't have brackets, you're referencing the cell or column in question. If you do have brackets, you have a relative reference.
Cell References:
R3C7 is an absolute reference - 3rd row, 7th column. This would be the same as saying $G$3 in A1 style, as detailed above.
R[3]C7 is partially absolute, partially relative reference. This is asking for "Give me the cell 3 rows down from the current cell, in column 7" (Which is column G) If I have this in cell A1, I'd be referencing cell G4. If I move it to cell B2, I'd be referencing cell G5.
R[2]C[-2] is a full relative reference. You can also reference earlier columns or rows, as indicated by the - sign. If I had this formula in cell C1, it would be referencing cell A3. If I move the formula to D2, I would now be referencing cell B4.
Range references:
Table References
Tables make referencing other cells and ranges easy and intuitive. They're broken out as follows:
TableName[ColumnName]
Formula References
VBA References
VBA Conversion from Letter to Column
Something that's come up a few times is changing column numbers to column letters. I found this very helpful piece of code (somewhere on Stack Overflow, I don't currently have the link handy) to convert column numbers to column letters for ease of use in VBA.
Function Col_Letter(lngCol As Long) As String
'Converts a number (usually generated from an application.match function) to a letter. For example 1 turns into A, 5 turns into E, etc.
Dim vArr
vArr = Split(Cells(1, lngCol).Address(True, False), "$")
Col_Letter = vArr(0)
End Function
Under Construction*

I don't know if there is a list of formats, because there really are only 2: A1 format and R1C1 format.
You're not actually specifying a range format when you use A1:C3 because the : is actually the range operator.
The variants of $A$1, $A1, A$1 are just that - variants, identifying that when copying the reference the coordinate before the $ should not change, but that otherwise the coordinate may change relative to the copy.
R1C1 is more complex, because it allows relativity. R3C2 is an absolute reference to Row 3, Column 2 (B3 in A1 notation), while the use of braces [] in an R1C1 reference indicates that it is relative to the current cell R[-2]C[1] from cell R3C2 would give R1C3 (C1).
Nearly forgot. There can also be a reference to cells in another worksheet. 'Sheet2'!IV256
I use
(((\w*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d+)
as a regexp for identifying cell references in the A1 format

The problem is that there are a variety of operators (Range, Intersect, implicit intersect etc ), functions (INDEX, OFFSET, CHOOSE, INDIRECT + user-defined functions), Defined Names and structured Table references etc that can all be de-referenced to provide a valid range reference. So to do a complete job means parsing arbitrary Excel formulae.
And it also varies by Excel version.
If all you want to do is work with standard explicit range references the usual trick is to convert the string to R1C1 notation and work with that. The syntax for R1C1 references is reasonably well described in Excel documentation.
There is also a BNF description of Excel formulae available somewhere but I have mislaid the reference.

"it's used for identifying cell references that might need modification when inserting a new row or column in a worksheet"
If the rows/columns are inserted with Excel live (as opposed to hacking into the workbook using another application), any references will update to the new address automatically.

Related

Excel365 'Sequence' combined with 'If'

I've created a sequence of dates for a dynamic calender.
This works fine.
But now I want to implement a condition, using 'IF' statement, where the step of the sequence is changed based on the value in the cells in column D (starting in cell D8).
If the cell in column D contains "Y" then the step in the sequence for that specific cell must be 8 in stead of 7.
The idea is that the sequence generates a list of all Mondays of a specific year (defined in B6), but when the Monday is a holiday, the return value must be a Thuesday.
The problem is that the reference for the column (D8) doesn't change and stays on the first cell reference. It should change to D9 for the next sequence value, D10 for the 3rd sequence value, etc.
Dutch formula -
=REEKS(54;1;DATUM($B$6;1;1)-WEEKDAG(DATUM($B$6;1;1);2)+1;ALS(D8="Y";7;8))
English version formula -
=SEQUENCE(54,1,Date($B$6,1,1)-WEEKDAY(DATE($B$6,1,1),2)+1,IF(D8="Y",7,8))
Edit 04/01/2023
This is the first cell in the sequence
This is currently the second cell in the sequence, where reference to D8 needs to be D9
Now I understand your question (in my first answer, I thought you were copying your formula on another place).
There seems to be a difference between earlier Excel versions, where a formula could only have one single cell as a result. Now there are formulae (like =SEQUENCE(), whose answer spreads over different cells. All those cells contain one element of the formula result, which means that the formula itself does not change over the multi-cell result.
I'm not sure if I understand what you mean: I have copied your formula (the English one) in cell "E2" and this is what I get:
=SEQUENCE(54,1,DATE($B$6,1,1)-WEEKDAY(DATE($B$6,1,1),2)+1,IF(D8="Y",7,8))
In another cell ("G3"), this turns into (select cell "E2", press Ctrl+C, press cell "G3", press Ctrl+V):
=SEQUENCE(54,1,DATE($B$6,1,1)-WEEKDAY(DATE($B$6,1,1),2)+1,IF(F9="Y",7,8))
So, when I apply a formula to another cell (two columns further, one row further), the reference to "D8" turns into "F9" (two columns further, one row further).
The other reference ("$B$6) does not change. Obviously, because the dollarsigns prevent that value to be changed (this is exactly what absolute and relative cell references are about, as described here).
Unfortunately, I don't know what you mean when you say that your cell references don't change: the ones, who should, do, and the ones, who shouldn't, don't, which is correct behaviour.
Oh: when you enter your formula in an external tool (like Notepad or so), you paste your formula in a cell and you paste it again in another cell, Excel won't realise that the cell references need to be update, is this the problem you're having?

Cell reference to named area, with offset

This is a question about OpenOffice spreadsheet, not Excel.
I have a named range which is a row of cells. (Say, the name in B4, the range C4:K4). I want to put a row of formulas underneath, where each formula references the cell within the named range at the same column. (The formula in C5 references C4, in D5 references D4, etc.).
Of course I could just use standard relative referencing, but I'd prefer to use the range naming.
How to do that?
I've played with COLUMN(), INDEX(), OFFSET(). I just get invalid reference errors.
Supplementary: there's something in Excel where you highlight a cell with relative references, and get it to recast the formulas using range-names. That might be called Names -> Apply IIRC. Is there something comparable in OpenOffice?
Provided your formulae are in columns C:K this is very simple, for example B5:B7 show the formulae in C5:C7 that have been copied across to ColumnK:
Why this is so is difficult to describe, but for Excel Doc.AElstein has attempted an explanation.

EXCEL: When dragging cells to the right I need to use information stored in columns not rows (Not sure how to ask this properly)

It's probably a simple problem, but I did not even know the keywords to google it ;/. Let's say I have this data :
Now I also have this litle formula:
If I know drag the C cell to the right, Excel will attempt the following caluclation:
=2+B1
What I want him to do is to attempt this calculation
=2+A2
Of course the easiest solution would be to store my initial data in one row instead of 1 column, but it is really inconvenient for me. Thanks for any help
You can use the indirect() method to reference a cell by it's "String identifier", i.e. "A3". When filling out to the right, use CONCATENATE() and COLUMN() to create your String identifiers {A1,A2,A3,A4,A5...} as required:
=2+INDIRECT(CONCATENATE("A";COLUMN()-2))
This will result in the following:
Side-Node: If you want this for some x/y-Grid-Generation, you can also be lazy,
and just insert =COLUMN() for every cell from "A1 - Z1" and ROW() for every cell from "A2 - A24".
(Or even avoid these at all and directly perform your actual calculation by using column() and row() as replacement for your x/y.
You may try using a combination of the INDIRECT and COLUMN functions:
=2+INDIRECT("A"&(COLUMN()-2))
You would paste the above formula into cell C1, and then drag across to the right however many columns/rows you wanted to cover.
This would result in the following:
This works because COLUMN()-2 returns 1 for the C column, 2 for the D column, and so on. Therefore, the formula will be calling INDIRECT on A1, A2, etc. for column C, D, and so on.
In general, if you want relative references to move down as cells are dragged to the right, you can use this:
Instead of:
= 2+A1
Do:
= 2+INDEX($A:$A,COLUMN()+<offset>)
Where <offset> is whatever offset you need. The offset will change depending on which column the starting formula is located in.
INDEX should be preferred over INDIRECT because INDIRECT is volatile (must recalculate after any change to the workbook) but INDEX is not (only recalculated when one of the inputs the formula, in this case $A:$A, changes).

Increment value inside curly brackets

I am using a formula in Excel 2010 to display the individual with the most wins, as below:
IF($P$3="Most wins",SUM(LARGE(Wins,{1})),"FALSE")
where wins represents an array of an indefinite number of individuals.
However I would like to be able to autofill this, or similar, such that the next row displays the following:
IF($P$3="Most wins",SUM(LARGE(Wins,{2})),"FALSE")
Unfortunately I can't get the value inside the curly brackets to increment, which is causing no end off issues when the formula is going to be dragged down beyond 1,000 rows.
Is this possible, or am I using the wrong method?
=IF($P$3="Most wins",SUM(LARGE(Wins,ROW(A1))),"FALSE")
Place that in the top of your column and copy it down. As you do, the cell reference for A1 will change from A1 to A2 to A3, etc. The ROW function returns the number of the row of the cell reference.
Alternatively as pointed out in Darren's comment, you could also use ROW()-2 if you data is starting in the second row. This has the advantage if you ver deleted the 1 row or column, you will not screw up your cell references.

Excel formula to reference 'CELL TO THE LEFT'

I'm trying to do conditional formatting so that the cell color will change if the value is different from the value in the cell left of it (each column is a month, in each row are the expenses on certain object. I want to monitor easily changes in prices over months.)
I can do it per cell and format-drag it, but I would like a general formula to apply to the whole worksheet.
=OFFSET(INDIRECT(ADDRESS(ROW(), COLUMN())),0,-1)
The shortest most compatible version is:
=INDIRECT("RC[-1]",0)
"RC[-1]" means one column to the left. "R[1]C[-1]" is bottom-left.
The second parameter 0 means that the first parameter is interpreted using R1C1 notation.
The other options:
=OFFSET(INDIRECT(ADDRESS(ROW(), COLUMN())),0,-1)
Too long in my opinion. But useful if the relative value is dynamic/derived from another cell. e.g.:
=OFFSET(INDIRECT(ADDRESS(ROW(), COLUMN())),0, A1)
The most simple option:
= RC[-1]
has the disadvantage that you need to turn on R1C1 notation using options, which is a no-go when other people have to use the excel.
When creating your conditional formatting, set the range to which it applies to what you want (the whole sheet), then enter a relative formula (remove the $ signs) as if you were only formatting the upper-left corner.
Excel will properly apply the formatting to the rest of the cells accordingly.
In this example, starting in B1, the left cell would be A1. Just use that--no advanced formula required.
If you're looking for something more advanced, you can play around with column(), row(), and indirect(...).
If you change your cell reference to use R1C1 notation (Tools|Options, General tab), then you can use a simple notation and paste it into any cell.
Now your formula is simply:
=RC[-1]
Instead of writing the very long:
=OFFSET(INDIRECT(ADDRESS(ROW(), COLUMN())),0,-1)
You can simply write:
=OFFSET(*Name of your Cell*,0,-1)
Thus for example you can write into Cell B2:
=OFFSET(B2,0,-1)
to reference to cell B1
Still thanks Jason Young!! I would have never come up with this solution without your answer!
fill the A1 cell, with the following formula :
=IF(COLUMN(A1)=1;"";OFFSET(A20;0;-1))&"1"
Then autoextend to right, you get
1| A | B | C | ect ect
2| 1| 11| 111| ect ect
If offset is outside the range of the available cell, you get the #REF! error.
Hope you enjoy.
Even simpler:
=indirect(address(row(), column() - 1))
OFFSET returns a reference relative to the current reference, so if indirect returns the correct reference, you don't need it.
Why not just use:
=ADDRESS(ROW(),COLUMN()-1)
You could use a VBA script that changes the conditional formatting of a selection (you might have to adjust the condition & formatting accordingly):
For Each i In Selection
i.FormatConditions.Delete
i.FormatConditions.Add Type:=xlCellValue, Operator:=xlLess, Formula1:="=" & i.Offset(0, -1).Address
With i.FormatConditions(1).Font
.Bold = True
End With
Next i
I stumbled upon this thread because I wanted to always reference the "cell to the left" but CRUCIALLY in a non-volatile way (no OFFSET, INDIRECT and similar disasters). Looking the web up and down, no answers. (This thread does not actually provide an answer either.) After some tinkering about I stumbled upon the most astonishing method, which I like to share with this community:
Suppose a starting value of 100 in E6. Suppose I enter a delta to this value in F5, say 5. We would then calculate the continuation value (105) in F6 = E6+F5. If you want to add another step, easy: just copy column F to column G and enter a new delta in G5.
This is what we do, periodically. Each column has a date and these dates MUST BE in chronological order (to help with MATCH etc). Every so often it happens that we forget to enter a step. Now suppose you want to insert a column between F and G (to catch up with your omission) and copy F into the new G (to repopulate the continuation formula). This is NOTHING SHORT of a total disaster. Try it - H6 will now say =F6+H5 and NOT (as we absolutely need it to) =G6+H5. (The new G6 will be correct.)
To make this work, we can obfuscate this banal calculation in the most astonishing manner F6=index($E6:F6;1;columns($E1:F1)-1)+F5. Copy right and you get G6=index($E6:G6;1;columns($E1:G1)-1)+G5.
This should never work, right? Circular reference, clearly! Try it out and be amazed. Excel seems to realize that although the INDEX range spans the cell we are recalculating, that cell itself is not addressed by the INDEX and thus DOES NOT create a circular reference.
So now I am home and dry. Insert a column between F and G and we get exactly what we need: The continuation value in the old H will refer back to the continuation value we inserted in the new G.
Make a named formula "LeftCell"
For those looking for a non-volatile answer, you can accomplish this by using the INDEX function in a named formula.
Select Cell A2
Open Name Manager (Ctrl+F3)
Click New
Name it 'LeftCell' (or whatever you prefer)
For Scope:, select Workbook
In Refers to:, enter the formula:
=INDEX(!A1:!A2, 1)
Click OK and close Name Manager
This tells Excel to always look at the value immediately to the left of the current cell, and will change dynamically as different cells are selected. If the name is used alone it provides the cell's value, but in a range it uses the reference. Credit to this answer about cell references for the idea.
I think this is the easiest answer.
Use a "Name" to reference the offset.
Say you want to sum a column (Column A) all the way to, but not including, the cell holding the summation (say Cell A100); do this:
(I assume you are using A1 referencing when creating the Name; R1C1 can subsequently be switched to)
Click anywhere in the sheet not on the top row - say Cell D9
Define a Named Range called, say "OneCellAbove", but overwrite the 'RefersTo' box with "=D8" (no quotes)
Now, in Cell A100 you can use the formula =SUM(A1:OneCellAbove)
When creating a User Defined Function, I found out that the other answers involving the functions OFFSET and INDIRECT cannot be applied.
Instead, you have to use Application.Caller to refer to the cell the User Defined Function (UDF) has been used in. In a second step, you convert the column's index to the corresponding column's name.
Finally, you are able to reference the left cell using the active worksheet's Range function.
Function my_user_defined_function(argument1, argument2)
' Way to convert a column number to its name copied from StackOverflow
' http://stackoverflow.com/a/10107264
' Answer by Siddarth Rout (http://stackoverflow.com/users/1140579/siddharth-rout)
' License (if applicable due to the small amount of code): CC BY-SA 3.0
colName = Split(Cells(, (Application.Caller(1).Column - 1)).Address, "$")(1)
rowNumber = Application.Caller(1).Row
left_cell_value = ActiveSheet.Range(colName & rowNumber).Value
' Now do something with left_cell_value
Please select the entire sheet and HOME > Styles - Conditional Formatting, New Rule..., Use a formula to determine which cells to format and Format values where this formula is true::
=A1<>XFD1
Format..., select choice of formatting, OK, OK.

Resources