25
votes

Using Offset or Indirect in 'Applies To' does not seem to work. Is there any other way to stop conditional formatting from breaking after inserting row/s

I have a conditional format for a range for e.g. $O$19:$O$105. The condition is 'if cell value is > 10', it is formatted with red color.

The problem is - when I insert a row in excel, this formatting range splits and I get 2 formatting rules. For e.g. the 2 rules with range as $O$19,$O$21:$O$105 & $O$20 respectively, if I insert a new row at 20th row.

Typically for condition like the one above, it may not matter, if the rules are split into multiple ranges. But for conditions like 'highlight top 10', it causes undesired results.

I tried the following without much luck:

  1. Tried using indirect - but excel seems to resolve the formula and saves the formatting rule and hence does not work with inserts as expected
  2. Tried using offset - here again excel resolves the range same as above.

Anyone knows how to write a conditional format that does not break with row inserts?

[EDIT] I realized that insert row is not causing the splitting of the conditional formatting rules. I also copy a row and paste in the inserted row which is doing this. If I opt for special paste and choose formulas only, its working fine.

16
If the built in conditional formatting isn't matching your particular case, you can always custom-code dynamic formatting rules in VBA by latching onto the worksheet change method and looking for intersects with the area you want to perform your formatting on.danielpiestrak
@Gimp Do you have a sample/snippet that I can start with? I am have used VBA, but am not very good at it yet.ssp
Before you venture into the land of VBA with this, change the cell referencing in your conditional formatting formula to relative, instead of absolute. So, change $O$19:$O$105 to O19:O105. Then insert your row and see if it works like you expect. And a warm welcome to SO, btw!Scott Holtzman
@scott-holtzman thanks! I tried your suggestion, does not work. Excel automatically converts it back to $O19:$O$105 and inserting a row again splits the range.ssp
I don't have time to research this now, but I wouldn't go with VBA just yet. There has to be a non-VBA solution for this. It's too "easy" of a scenario to run into. Check this link... maybe you need to change your format range... just a thought excelforum.com/excel-programming-vba-macros/…Scott Holtzman

16 Answers

12
votes

I know this is an old thread but here's another solution that's super simple and works great.

Simply insert a new row or column as desired. Then select and copy a row/column that has the correct conditional formatting. Past Special into the new row/column that you just created and select the option for "All merging conditional formats". Your conditional formatting rules should now be automatically updated.

Happy Excel-ing =)

8
votes

This is a general problem with conditional formats. If you insert rows or shift things around, Excel assumes that you want the conditional format to shift with the cells, and that you want to insert cells with their original formatting (or none at all).

So it tries its best to split up the formatted range according to the changes. Unfortunately "its best" is not very good. In lucky cases, your formatting rules get duplicated without you noticing; in unlucky cases they break for some or all of the applied range.

This is especially a problem if you work with ListObjects (a.k.a. "Excel tables"). Insert some rows, reorder it a bit, drag some values around and the next time you look into your conditional formatting list, you have dozens to hundreds of duplicate rules. (example: http://blog.contextures.com/archives/2012/06/21/excel-2010-conditional-formatting-nightmare/)

In my experience the quickest way to fix the mess is to delete all rules and recreate them (or not).

Some sidenotes:

  • The applies-to range is always absolute. There is no way around that.
  • To make matters worse, conditional formats are treated like volatile formulas, meaning they are recalculated on lots of occasions (opening another file, scrolling around, etc). If you do not notice the split-ups, they can slow down the whole application significantly after a while.
  • If you go for VBA, you probably want to use the Worksheet_Calculate event, at least if your formulas refer to other worksheets (be aware of names!)
3
votes

I was having this problem while trying to create reports - once they're finished they don't need to change, but while I'm making them, I keep adding new lines and each new line mucks up the conditional formatting.

This is by no means a good solution, but it was the best I could find without resorting to VBA - which was to:

a) Make the conditional formatting rules apply to a whole column or more at a time

for example instead of setting conditional formatting on C2 and C17, put an extra column, and write "this one" in rows 2 and 17, and then set the formatting for the whole of column C to be "if the other column says 'this one' then apply this format"

b) Change the Applies To to be just $C$1:$C$2.

c) Make changes and insert rows and stuff

d) Then go back and change the Applies To to be $C:$C

That way, while you change things and add things, the conditional formatting isn't there, but then you put it all back later.

If, at a later date, you need to add a few more rows, first change it from $C:$C to $C$1:$C$2, then make the changes, and then put it back to $C:$C. That way you don't have to completely rewrite all the formatting rules from scratch as you would if you do what I've done previously which was just delete them all, curse, and start again ;)

Obviously if you're planning on inserting rows up at the top in row 1 or 2, that won't work, but you could always set it to some other rows that you know you won't change.

3
votes

Although this is quite old topic, my Excel sheets were also suffering from duplicating conditional formatting when inserting a new row.

I was able to work around it. Let me share it with others, it might help too.

In my case, all my conditional formatting rules were applied to the whole table. I realized that only certain rules are duplicated when inserting a new row. These rules are formula based comparing values in different rows.

In my case, I wanted to render a horizontal border when values of two adjacent rows differ, e.g.:

=$A2 <> $A1

If I use OFFSET to refer to previous row, all is correct, no duplicated conditional formatting rules.

=$A2<>OFFSET($A2; -1; 0)

I actually put these conditional formatting formulas into a hidden column but the result should be the same.

1
votes

I realized that insert row is not causing the splitting of the conditional formatting rules. I also copy a row and paste in the inserted row which is doing this. If I opt for special paste and choose formulas only, its working fine.

However, I wonder if there would ever be a need to use 'INDIRECT' or 'OFFSET' in 'Applies to' field of Conditional Formatting. If so, it's going to be a problem.

1
votes

I realize this is an old post, but I was running into the same problem and have since figured out how to not get the split conditional format rules.

In my Excel 2010 spreadsheet, I enter dates into column B. Some times I fat finger the date entry, which is why I wanted to conditionally format them. Initially, I was selecting a range (B2:B1960), so my formula in the Conditional Formatting Rule would be "=B2:B1960>TODAY()".

Well, that worked fine until I went to insert new rows between existing rows. The rules would split just as the OP described. I happened to look at several different websites and found a Microsoft Office site that pointed me to the answer. It mentioned to highlight the range that you want to format, but change the formula to "=B2>TODAY()".

Since changing the formula, I can now insert new rows between existing rows and not get the split Rules as before. Here is the link to that web page. http://office.microsoft.com/en-us/excel-help/use-a-formula-to-apply-conditional-formatting-HA102809768.aspx

1
votes

What works for me is, when you insert a row, don't copy the formatting from another row. Only copy-special paste the formulas. The conditional formatting then does not get split up.

1
votes

What you have to do is 1) insert a new row 2) copy the row you want to clone 3) paste special "Merge Conditional Formatting"

Not intuitive and a mountain of user training if you want others to share the workbooks you create

1
votes

My solution to this exact problem was clearing the formatting from the source copy. Steps:

  1. Copy source onto clipboard
  2. Open new excel document
  3. Paste Special, select formula (copies values and formulae and omits formatting)
  4. Copy this to clipboard
  5. Now you can either paste back to the source before using it or you insert blank rows into the sheet with the conditional formatting (note just inserting rows will not change the range on the conditional formatting rules) and paste the clipboard content into the new rows.

This worked for me using MS Excel 2016

1
votes

I agree with what has been posted previously; copy and paste values (or paste formulas) will totally work to not split up the conditional formatting.

I'm a little lazy for that. And I don't want those who use my spreadsheets to have to do that. I'm also not confident that they will remember to do copy and paste values. :(

I don't know if this solution will work for your needs, but I resorted to deleting all conditional formatting and reapplying the correct conditional formatting every time the workbook is opened.

Because this macro runs every time the workbook is opened, the user does not need to change the way they copy and paste. They don't need to know that the macro is even there. They don't need to manually run the macro; it is automatic. I feel this creates a better user experience.

Please keep in mind that this code needs to be copied and pasted into the "This Workbook" module; not a regular module.

Private Sub Workbook_Open()
'This will delete all conditional formatting and reapply the conditional formatting properly.
'After copying and pasting the conditional formatting get split into two or more conditional formattings. After a few
'weeks there are so many conditional formattings that Excel crashes and has to recover.

Dim ws As Worksheet, starting_ws As Worksheet


Set starting_ws = ActiveSheet   'remember which worksheet is active in the beginning
Application.ScreenUpdating = False
For Each ws In ThisWorkbook.Worksheets
    If ws.Name <> "InvErr" Then
        ws.Activate
        Cells.FormatConditions.Delete
        ''Every Other Row Tan
        Range("A4:M203").FormatConditions.Add Type:=xlExpression, Formula1:="=ISODD(ROW(A4))"
        Range("A4:M203").FormatConditions(Range("A4:M203").FormatConditions.Count).SetFirstPriority
        Range("A4:M203").FormatConditions(1).Interior.PatternColorIndex = xlAutomatic
        Range("A4:M203").FormatConditions(1).Interior.ThemeColor = xlThemeColorDark2
        Range("A4:M203").FormatConditions(1).Interior.TintAndShade = 0
        Range("A4:M203").FormatConditions(1).StopIfTrue = False

        ''Highlight Duplicates Red
        Columns("B").FormatConditions.AddUniqueValues
        Columns("B").FormatConditions(Columns("B").FormatConditions.Count).SetFirstPriority
        Columns("B").FormatConditions(1).DupeUnique = xlDuplicate
        Columns("B").FormatConditions(1).Font.Color = -16383844
        Columns("B").FormatConditions(1).Font.TintAndShade = 0
        Columns("B").FormatConditions(1).Interior.PatternColorIndex = xlAutomatic
        Columns("B").FormatConditions(1).Interior.Color = 13551615
        Columns("B").FormatConditions(1).Interior.TintAndShade = 0
        Columns("B").FormatConditions(1).StopIfTrue = False
    End If
Next

starting_ws.Activate   'activate the worksheet that was originally active
Application.ScreenUpdating = True

End Sub
1
votes

This worked well enough for me...

Sub ConditionalFormattingRefresh()
'
' ConditionalFormattingRefresh Macro
'

'Generales
Dim sh As Worksheet
Dim tbl As ListObject
Dim selectedCell As Range
Set sh = ActiveSheet
Set tbl = Range("Plan").ListObject
Set selectedCell = ActiveCell

'Rango a copiar
Dim copyRow As Range
Set copyRow = tbl.ListRows(1).Range

'Rango a restaurar
Dim startCell As Range
Dim finalCell As Range
Dim refreshRange As Range
Set startCell = tbl.DataBodyRange.Cells(2, 1)
Set finalCell = tbl.DataBodyRange.Cells(tbl.ListRows.Count, tbl.ListColumns.Count)
Set refreshRange = Range(startCell.Address, finalCell)

'Ocultar procesamiento
Application.ScreenUpdating = False
Application.EnableEvents = False

'Borrar formato corrupto
refreshRange.FormatConditions.Delete

'Copiar
copyRow.Copy
'Pegar formato
tbl.DataBodyRange.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False

'Retornar a la normalidad
selectedCell.Select
    Application.ScreenUpdating = True
Application.EnableEvents = True

End Sub
0
votes

Here's a similar thread that may get you ont he right track:

How to use the Worksheet_Change event for Conditional Formatting?

It outlines a workaround to R1C1 style formatting which may not be affected by the inserts (untested) along with the VBA approach I mentioned in the comments.

0
votes

I have found a simple process that seems to work consistently for inserting new rows or columns AND preserves the continuity of the conditional formatting rules (in Office 2010 at least), as follows:

  1. Do a simple "Insert" of your desired number of new rows or columns above, below or left or right of a row or column containing the conditional formatting to be preserved.

NOTE a) Your conditional formatting is automatically applied to the inserted rows or columns without you having to do anything further. The formatting should have been inherited from the neighboring row or column. b) Any borders formatting should also have been copied to the newly inserted cells.

  1. Select a row, column or range (by clicking it) that is adjacent to the newly inserted ones, and which contains the conditional formatting (and formulas and data if applicable) to be copied.

  2. Hover your mouse over the lower left or lower right corner of the selected range until you see a plus "+" sign appear (don't confuse it with the row re-size gadget as they look similar).

  3. Left click and hold on "+", and drag across the desired rows, columns or range to be formatted, then release.

NOTE: I create Conditional Formatting rules referencing only one cell: Example) in the field titled "Format values where this formula is true:", create a rule such as ... =AND($B8="",$C8="",$D8="",$K8<>""), where this rule Applies to say the range ... =$B$8:$D$121,$J$8:$M$121.

0
votes

In 2013, Once you find your formatting rules have been split/duplicated, define a new namedrange for each format. Then set the applies to =[Named Range]. Excel will replace the named range with the actual range. Then delete the duplicate formats.

0
votes

I'm building a solution that others with mixed Excel skill levels will come into play, so I needed something easier and more consistent than to have them remember to copy and paste a certain way.

In Excel 2016, you can insert a table from a selected range which then gives you the benefit of using structured references (example: tblTOP[Type], to reference data in the Type column of the table named tblTOP).

I then found this answer at Microsoft's site that shows an effective way to reference a table in the formula part of CF: conditional formatting structured references


So, with that established...

This is what I'm working with:

tblTop Columns

I set up my conditional formatting so that when I change the Type value anywhere between A to E, it will change that row to a corresponding color. (Example shown: B turns the row to green)

This was accomplished by using the formula =INDIRECT("tblTOP[Type]")="B"

When I went to add a row though, I got the same formatting applied to that second row :(.

Broke CF between two rows

CF formula that worked

Long story short, the following formula is what I came up with to apply my CF rule to that particular row and not affect any rows being added or taken away:

=INDIRECT("tblTOP[@Type]")="B"

The addition of the '@' in front of the structured reference keeps things happening just for that given row. Nice.

So now I can tab through or use the context menu to add a new row and it awaits the type selection to determine the color for that row only.

New Row added clean

New Row working as expected

I haven't tested it with pasting cells as the purpose of this table is for the end user to enter data and add/delete rows as needed, so I can't say if this will work with pasting a row.

Hope this helps someone with conditional formatting in a table.

-1
votes

I got it to work on Excel Mac 2011 by the following steps

  • inserting the new row
  • copying the one above it (with the conditional formatting already applied)
  • highlighting the new row and PASTE SPECIAL -> MERGE CONDITIONAL FORMATTING.

The CF rules stayed unsplit and updated to include an additional row.