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.
Related
I would like to highlight a cell which is the closest the a specific value but still lower (below) or equal according to a formula.
For instance, if I have 14 in B4, I would like the cell 13 (or 14) highlighted but not 15 in the range.
The value I need to look for would be in B4 and the range that I must apply the highlight formula to would be L1:L371.
So far, the best result I was able to achieve was with (from what I was able to find using Google or Stackoverflow already existing content):
=SMALL($L1:$L317,COUNTIF($L1:$L371,"<="&$B$4))
Although, not only it selects the value I am looking for, it also selects all the values below.
May someone provide me some help so I can achieve the expected result please?
Thank you for your time and help, it is greatly appreciated.
Based on your description, it seems like you need to find the maximum value of a range (L1:L137) that is less than or equal to an input variable (B4) and highlight that value in the search range. Depending on what version of Excel you have, here's what you need to do:
For Excel 2019 or Excel 365
You can use the MAXIFS function. You would actually put that function in a conditional formatting rule, but more on that in just a second. As a test, put the following code in cell B5:
=MAXIFS($L$1:$L$137,$L$1:$L$137,"<="&$B$4)
The first argument is your "MAX_RANGE", or the range that contains the values you want to find the max of. It is also our "CRITERIA_RANGE", the second argument. The third argument is the criteria itself, which is that the search range must be less than or equal to the value in cell B4. Essentially, we are going through the list and creating a subset of numbers that are less than or equal to our search value, and discarding the rest. I assume you are aware of relative vs. absolute referencing, since you used the "$" anchor in your referenced code. If not, here's a description of the difference.
Now, the result of that formula should be the highest number in the list less than or equal to the search value, but that doesn't highlight it for us in our list. To do this we need conditional formatting. To do this, highlight your data range (L1:L137) and go to the conditional formatting drop down on the home tab of the menu ribbon. Choose "New Rule". On the dialog that pops up, choose, "Use a formula to determine which cells to format". In the formula input box, enter:
=L1=MAXIFS($L$1:$L$137,$L$1:$L$137,"<="&$B$4)
This will compare whether the value in the cell being evaluated (L1, for instance) is equal to the result of that formula we talked about above. Since L1 is only relatively referenced, this formula will work for every cell in the data range.
Now, before you hit "OK" on the dialog, select the Format button. This will allow you to adjust your highlighting and formatting as you desire. Click "OK" on the formatting dialog, then "OK" on the Conditional Formatting Rule dialog. This should now highlight any data cell that is equal specifically to the result of our formula, and not everything that's less than our value.
For Earlier Versions of Excel
The concept is the same in earlier versions of Excel, but unfortunately, the MAXIFS function is not present in these versions. Instead, we must use an array formula. Array formulas are a whole other can of worms, but ExcelJet is an excellent resource. In fact, they talk about this very issue, here.
Unfortunately, we can't put the array formula in the conditional formatting formula like we did above, so we'll need to put this formula on a cell in the worksheet, then the conditional formula should reference that new cell. So in cell B5, if you put:
=MAX(IF(L1:L137=B4,L1:L137)
And then, instead of pressing Enter, you must press Ctl + Shift + Enter
This keyboard combination will tell Excel that you are trying to enter an array formula. If you don't press these keys, then the formula will error. Once you have entered the array formula, if you put your cursor in cell B5, you will see the formula bar at the top has added curly braces ({ , }) around the formula to look like
{=MAX(IF(L1:L137=B4,L1:L137)}
This leads to the same result as above, but is just achieved slightly differently. Now, following the same process described above for conditional formatting, you will simply set the formula to:
=L1=$B$5
And that should be it! Hope this helps!
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).
Here is my problem:
I have a cell (V4) containing the value 444. I want to use this value in the formula of another cell (M12) in the following way. I want the formula to be equivalent to =MIN(L12:L444) but instead of 444 I want to refer to cell V4 which contains the value 444. But when I type in =MIN(L12:L(V4)) it obviously doesnt work so how do I do it? Sorry if I didn't explain it very well. :S
Would this work for you:
=MIN(L12:INDIRECT("L"&$V$4))
From: Excel - INDIRECT and Using the value in a cell as a cell reference in a formula?
INDIRECT will work and is closest to the solution you described, but I prefer OFFSET, which uses proper references. (For example, if you insert a column in the sheet before L, INDIRECT will break while OFFSET will just update its reference as expected.
Two ways to go with OFFSET:
1 - Start at L$1 and go down $V$4-1 rows. (This will work with $V$4 as you've defined it now.)
=MIN(L12:OFFSET(L$1,$V$4-1,0))
2 - In $V$4, provide the height of the range you want.
=MIN(OFFSET(L12,0,0,$V$4,0))
It's hard to make suggestions without more context, but I'm sure you can tweak one of these patterns to meet your needs.
I am not sure if you are trying to include all of the values in 1 column and then on non-contiguous cell. If so, it should look like = Min(L12:L444,V4) . The L12:L444 looks at the value in every cell in the L column from 12 - 444.
So you can check individual cell (A3, D15, Q54) with commas, or a range of cells (A3:Z54) with a colon. Or a range and a specific cell like above =Min(L12:L444, V4).
How does one cell obtain the formula of another cell as text without using VBA? I can see this question has already been asked many times and the answer is always to write a custom function in VBA.
However, I found a post made in 2006 which claimed to have found the non-VBA solution but the link provided in that post is already broken.
=FormulaText(Reference) will do the trick Documentation
There is nice way of doing this without VBA. It uses XL4 macros (these are macros, but it is not VBA, as asked).
With reference to the figure 1, cells A2:A4 contain usual formulas.
Going to Formulas -> Define Name, I defined two named ranges (see fig. 2), with the information shown in cells A6:B8.
Enter in cell B2 =FormulaAsText. This will retrieve the formula in cell A2 as text.
Explanation:
The named range FormulaAsText uses =GET.CELL(info_type,reference). In this case, ìnfo_type = 6 retrieves the formula, and reference = OFFSET(INDIRECT("RC",FALSE),0,-1) uses the cell with 0 rows and -1 columns offset from the one the formula is used in.
Copy B2 and paste into B3:B4. This will show formulas in A3:A4. Cell A4 shows that the worksheet function CELL only retrieves values, not formulas (as opposed to GET.CELL).
Since FormulaAsText gets the formula from a cell at fixed offset (0,-1) from the current, I defined another range FormulaAsText2, which uses an offset (rows,cols) read from the worksheet itself. Cells D2:D4 contain =FormulaAsText2. Thus, cell D2 shows the contents of cell B3 (=OffSET(D2,1,-2)), which is FormulaAsText. cells D3:D4 show the contents of themselves. This adds some flexibility. YMMV.
PS1: The essence was taken from
http://www.mrexcel.com/forum/excel-questions/20611-info-only-get-cell-arguments.html
PS2: Tim Williams mentioned in a comment "the old XLM GET.FORMULA()". This answer is possibly related (not the same, since this one uses GET.CELL()).
PS3: A simple VBA solution is given, e.g., in
http://dmcritchie.mvps.org/excel/formula.htm
EDIT: Complementing this nice answer, the worksheet function FormulaText is available for Excel 2013 and later.
This suggestion may be helpful for those who after retrieving a block of formulas and transporting them to a new spreadsheet want to put them to work again. Excels FORMULATEXT function is great for picking up formulas but it leaves them as unusable text strings. If you want to get them back as fully functioning formulas you have to edit each one individually to remove the string character, but here is a shortcut for larger blocks.
Get to the position where you have the required formulas as text (in other words after using FORMULATEXT - you have done a copy and (value only) paste). The next step involves highlighting all the cells you want to convert and then navigating to the [Text-To-Columns] menu option ({Data} bar on Excel 2016). You can select 'Delimited' but on the next screen just make sure you de-select any marks that do appear in your formulas. Then 'Finish'. Excel should automatically analyse the cells as containing formulas and you should now have them working again.
There is a way to do this. In my example I had a table that showed a date. The date comes from Sheet!G91. In my table I also had a column that showed the sheet name. I added two more columns to my table. The first column had column(Sheet!g91), which returns the number 7, because G is the seventh letter in the alphabet. I then converted the number to a letter (G) using another table in my workbook. In the second column that I added, I made a formula row(Sheet!G91), which returns the number 91. Note: Row and Column may appear as volatile formulas, which recalculate with every calculation of the workbook.
I wanted another column to show the formula contents of the date cell mentioned at the beginning of this post. I included the following string function (you can also use CONCATENATE).
"=" & AJ9 & "!" & AM9 & AN9
The items separated by ampersands get strung together (that is, concatenated). AJ9 in my example contains the sheet name, AM9 contains the column letter, and AN9 contains the row number.
I now have a column that dynamically updates its contents to reflect the sheet name and cell reference. The results in my workbook cell are
=Sheet!G91.
You can't. This is most likely a design choice to eliminate an average Excel user from accidentally getting something they did not want.
What you are reading is correct - writing a UDF is the solution you want.
How do I obtain a reference to the current cell?
For example, if I want to display the width of column A, I could use the following:
=CELL("width", A2)
However, I want the formula to be something like this:
=CELL("width", THIS_CELL)
Several years too late:
Just for completeness I want to give yet another answer:
First, go to Excel-Options -> Formulas and enable R1C1 references. Then use
=CELL("width", RC)
RC always refers the current Row, current Column, i.e. "this cell".
Rick Teachey's solution is basically a tweak to make the same possible in A1 reference style (see also GSerg's comment to Joey's answer and note his comment to Patrick McDonald's answer).
Cheers
:-)
Create a named formula called THIS_CELL
In the current worksheet, select cell A1 (this is important!)
Open Name Manager (Ctl+F3)
Click New...
Enter "THIS_CELL" (or just "THIS", which is my preference) into Name:
Enter the following formula into Refers to:
=!A1
NOTE: Be sure cell A1 is selected. This formula is relative to the ActiveCell.
Under Scope: select Workbook.
Click OK and close the Name Manager
Use the formula in the worksheet exactly as you wanted
=CELL("width",THIS_CELL)
EDIT: Better solution than using INDIRECT()
It's worth noting that the solution I've given should be preferred over any solution using the INDIRECT() function for two reasons:
It is nonvolatile, while INDIRECT() is a volatile Excel function, and as a result will dramatically slow down workbook calculation when it is used a lot.
It is much simpler, and does not require converting an address (in the form of ROW() COLUMN()) to a range reference to an address and back to a range reference again.
EDIT: Also see this question for more information on workbook-scoped, sheet dependent named ranges.
EDIT: Also see #imix's answer below for a variation on this idea (using RC style references). In that case, you could use =!RC for the THIS_CELL named range formula, or just use RC directly.
You could use
=CELL("width", INDIRECT(ADDRESS(ROW(), COLUMN())))
=ADDRESS(ROW(),COLUMN(),4) will give us the relative address of the current cell.
=INDIRECT(ADDRESS(ROW(),COLUMN()-1,4)) will give us the contents of the cell left of the current cell
=INDIRECT(ADDRESS(ROW()-1,COLUMN(),4)) will give us the contents of the cell above the current cell (great for calculating running totals)
Using CELL() function returns information about the last cell that was changed. So, if we enter a new row or column the CELL() reference will be affected and will not be the current cell's any longer.
A2 is already a relative reference and will change when you move the cell or copy the formula.
=ADDRESS(ROW(),COLUMN())
=ADDRESS(ROW(),COLUMN(),1)
=ADDRESS(ROW(),COLUMN(),2)
=ADDRESS(ROW(),COLUMN(),3)
=ADDRESS(ROW(),COLUMN(),4)
Without INDIRECT(): =CELL("width", OFFSET($A$1,ROW()-1,COLUMN()-1) )
I found the best way to handle this (for me) is to use the following:
Dim MyString as String
MyString = Application.ThisCell.Address
Range(MyString).Select
Hope this helps.
Inside tables you can use [#] which (unfortunately) Excel automatically expands to Table1[#] but it does work. (I'm using Excel 2010)
For example when having two columns [Change] and [Balance], putting this in the [Balance] column:
=OFFSET([#], -1, 0) + [Change]
Note of course that this depends on the order of the rows (just like most any other solution), so it's a bit fragile.
There is a better way that is safer and will not slow down your application. How Excel is set up, a cell can have either a value or a formula; the formula can not refer to its own cell. You end up with an infinite loop, since the new value would cause another calculation... . Use a helper column to calculate the value based on what you put in the other cell. For Example:
Column A is a True or False, Column B contains a monetary value, Column C contains the folowing formula:
=B1
Now, to calculate that column B will be highlighted yellow in a conditional format only if Column A is True and Column B is greater than Zero...
=AND(A1=True,C1>0)
You can then choose to hide column C
Full credit to the top answer by #rick-teachey, but you can extend that approach to work with Conditional Formatting. So that this answer is complete, I will duplicate Rick's answer in summary form and then extend it:
Select cell A1 in any worksheet.
Create a Named Range called THIS and set the Refers to: to =!A1.
Attempting to use THIS in Conditional Formatting formulas will result in the error:
You may not use references to other workbooks for Conditional Formatting criteria
If you want THIS to work in Conditional Formatting formulas:
Create another Named Range called THIS_CF and set the Refers to: to =THIS.
You can now use THIS_CF to refer to the current cell in Conditional Formatting formulas.
You can also use this approach to create other relative Named Ranges, such as THIS_COLUMN, THIS_ROW, ROW_ABOVE, COLUMN_LEFT, etc.
EDIT: the following is wrong, because Cell("width") returns the width of the last modified cell.
Cell("width") returns the width of the current cell, so you don't need a reference to the current cell. If you need one, though, cell("address") returns the address of the current cell, so if you need a reference to the current cell, use indirect(cell("address")). See the documentation: http://www.techonthenet.com/excel/formulas/cell.php
Reference to a cell that include this formula (self reference):
address(row();column())
E.g. getting the value of the cell above:
indirect(address(row()-1;column()))
Or what the OP asked:
=Cell(width;address(row();column()))