Conditional Formatting a Range row by row - excel

I'm trying to apply some conditionals rules using VBA in a Range.
But I'm very new with conditional formating VBA so I'm a bit lost.
My Users can add rows above of the target range, that mean the range address could be always different.
let's admit that for the exemple, my range is Worksheets("test").Range("MyBoard")
("MyBoard" is my range name, currently located at A19:O32)
How can I apply a rule to turn yellow each rows of my range if the first column contains the value "Customer" ?
Sub FormatRange()
Dim MyRange As Range
Set MyRange = Worksheets("test").Range("MyBoard")
MyRange.FormatConditions.Delete
MyRange.FormatConditions.Add Type:=xlCellValue, Formula1:="=COUNTIF(MyRange;"*Customer*") > 0"
MyRange.FormatConditions(1).Interior.Color = RGB(255, 255, 0)
End Sub
Thanks for the help

Please, use the next adapted code:
Sub FormatRange()
Dim MyRange As Range, listSep As String
Set MyRange = Range("MyBoard")
listSep = Application.International(xlListSeparator)
MyRange.FormatConditions.Delete
MyRange.FormatConditions.Add Type:=xlExpression, formula1:="=ISNUMBER(SEARCH(" & _
"""Customer""" & listSep & MyRange.cells(1, 1).Address(0, 1) & "))"
MyRange.FormatConditions(1).Interior.Color = RGB(255, 255, 0)
End Sub

Conditional formatting has some very particular format to get an entire row to work.
E.g., If i want to apply a color to each row, between certain columns of a specified range:
With .Range(.Cells(1, startColumn), .Cells(lastRow, endColumn))
.FormatConditions.Add Type:=xlExpression, Formula1:="=$A1>1"
.FormatConditions(1).Font.Italic = True
End With
Edit1: Indicating use of Find() for the row containing "Customer" being used for the above code.
Sub test()
With Sheets(1)
Dim customerCell As Range: Set customerCell = .Columns(1).Find("Customer")
If customerCell Is Nothing Then Exit Sub
Dim lastRow As Long: lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
.Cells.FormatConditions.Delete
With .Range(.Cells(customerCell.Row, 1), .Cells(lastRow, 10))
.FormatConditions.Add Type:=xlExpression, Formula1:="=CountIf($A" & customerCell.Row & ",""*Customer*"")"
.FormatConditions(1).Interior.Color = RGB(255, 255, 0)
End With
End With
End Sub

I think, this is what your are looking for:
Sub FormatRange()
Dim MyRange As Range
Set MyRange = Worksheets("test").Range("MyBoard")
Dim startAddress As String
startAddress = MyRange.Cells(1, 1).Address(False, True) ' will return e.g. $A19 in your case
Dim formula As String
'formula = startAddress & " = ""customer""" 'exact customer
formula = "ISNUMBER(FIND(""customer""," & startAddress & "))" ' *customer*
Dim fc As FormatCondition
With MyRange
.FormatConditions.Delete
Set fc = .FormatConditions.Add(xlExpression, Formula1:="=" & formula)
fc.Interior.Color = RGB(255, 255, 0)
End With
End Sub
You have to reference the first cell within your range - and "fix" the column --> .Address(False, True) will return $A19 in your case.
Then you need to build a valid string for the formula to pass to the format condition
You need double quotes for "customer" when building the string.

Related

Using VBA for a conditional formatting with différent rules

How can I set a rules to turn the row backround Yellow and also apply a pattern to some specific columns of this same row, only using VBA ?
Sub FormatRange()
Dim MyRange As Range, listSep As String
Set MyRange = Range("MyBoard")
listSep = Application.International(xlListSeparator)
MyRange.FormatConditions.Delete
MyRange.FormatConditions.Add Type:=xlExpression, formula1:="=ISNUMBER(SEARCH(" & _
"""Customer""" & listSep & MyRange.cells(1, 1).Address(0, 1) & "))"
MyRange.FormatConditions(1).Interior.Color = RGB(255, 255, 0)
MyRange.FormatConditions(1).Interior.Pattern = xlGray75
End Sub
Can I just specify the column letter at the same time as the Range ? (column B/C/E/H)
Please, test the next adapted code. It assumes that you need, **for the same Formula2 condition (formula), to place a specific pattern only on the mention columns (of the named range):
Private Sub FormatRange()
Dim MyRange As Range, listSep As String
Set MyRange = Range("MyBoard")
listSep = Application.International(xlListSeparator)
MyRange.FormatConditions.Delete
MyRange.FormatConditions.Add Type:=xlExpression, formula1:="=ISNUMBER(SEARCH(" & _
"""Customer""" & listSep & MyRange.cells(1, 1).Address(0, 1) & "))"
MyRange.FormatConditions(1).Interior.Color = RGB(255, 255, 0)
'the code new part:
Dim myRng As Range
Set myRng = Intersect(MyRange, MyRange.Parent.Range("B:C, E:E, H:H"))
myRng.FormatConditions.Delete
myRng.FormatConditions.Add Type:=xlExpression, formula1:="=ISNUMBER(SEARCH(" & _
"""Customer""" & listSep & MyRange.cells(1, 1).Address(0, 1) & "))"
myRng.FormatConditions(1).Interior.Pattern = xlGray75
End Sub

Highlight cell that doesn't have only letters

I'm currently trying to develop my first conditional formatting on VBA, but after hours of trial it still doesn't work.
I'm aiming for a formula that would change the background / highlight the text of a cell that contains something else than any alphabet letters (not sensitive to caps or not). Accents, numbers and special characters would be the trigger
Here is my current code
Thank you in advance for your help
Sub Highlight()
Dim MyRange As Range
Set MyRange = Selection
MyRange.FormatConditions.Delete
MyRange.FormatConditions.Add xlExpression, , Formula1:="=IsAlpha()=false"
MyRange.FormatConditions(1).Interior.Color = RGB(255, 0, 0)
End Sub
And IsAlpha would be a function like
Function IsAlpha(s) As Boolean
IsAlpha = Len(s) And Not s Like "*[!a-zA-Z ]*"
End Function
You need to pass an argument to IsAlpha. Try the following:
Sub Highlight()
Dim MyRange As Range
Set MyRange = Selection
MyRange.FormatConditions.Delete
Dim s As String
s = "=NOT(IsAlpha(" & MyRange.Cells(1).Address(False, False) & "))"
MyRange.FormatConditions.Add xlExpression, Formula1:=s
MyRange.FormatConditions(1).Interior.Color = vbRed 'Or use RGB...
End Sub
In action:
Highlight Not Pure Alpha
There is a delay of about 2s before the cells get colored (on my machine). I wonder if a worksheet change would handle this smoother (if the range contains values (not formulas)).
Option Explicit
Sub HighlightNotPureAlphaTEST()
If TypeOf Selection Is Range Then
HighlightNotPureAlpha Selection
End If
End Sub
Sub HighlightNotPureAlpha(ByVal rg As Range)
With rg
.FormatConditions.Delete
' To not highlight blanks...
.FormatConditions.Add xlExpression, , _
"=NOT(IsAlphaOrBlank(" & .Cells(1).Address(0, 0) & "))"
' To highlight blanks:
'.FormatConditions.Add xlExpression, , _
"=NOT(IsAlpha(" & .Cells(1).Address(0, 0) & "))"
.FormatConditions(1).Interior.Color = RGB(255, 0, 0)
End With
End Sub
Function IsAlphaOrBlank(ByVal S As String) As Boolean
Application.Volatile
IsAlphaOrBlank = Not S Like "*[!A-Za-z]*"
End Function
Function IsAlpha(ByVal S As String) As Boolean
Application.Volatile
If Len(S) > 0 Then IsAlpha = Not S Like "*[!A-Za-z]*"
End Function

excel vba: fill another column with color if this column is not null

how to write code in vba if I want the another column to fill with yellow color when one column is not null?
For example:
if A1,A3,A8,A100 is not null:
fill background of B1,B3,B8,B100 into yellow color
If a loop is used would be great because my actual case have 7000 cells to fill instead of 4
Option Explicit
Sub ColorColA()
Dim ws As Worksheet
Dim lastrow As Long, cell As Range
Set ws = ThisWorkbook.Sheets("Sheet1")
lastrow = ws.Range("B" & Rows.Count).End(xlUp).Row
For Each cell In ws.Range("A1:A" & lastrow)
If IsEmpty(cell) Then
cell.Offset(0, 1).Interior.Color = RGB(255, 255, 0) 'yellow
Else
cell.Offset(0, 1).Interior.Pattern = xlNone ' remove color
End If
Next
MsgBox lastrow & " rows scanned", vbInformation
End Sub

Conditional Formatting in VBA

I am tying to manage duplicates on an Excel sheet by having the duplicate cells turn red. I put this in a use to sheet protection to keep from editing the conditional formatting for these columns. However, when I move the cell information (by clicking and dragging) the conditional formatting moves from that cell as well. At the end of the day, I do not have duplicate coverage for every cell that I want. Is there some way I can prevent this from happening when I move the cell, or what macro can I put in to take care of this?
I want to do something like this using VBA:
Sub Duplicate()
Dim rngData As Range
Dim cell As Range
Set rngData = Range("P3:P19, P56:P58, P39:P42, P21:P25, P27:P37, P39:P42, P39:P42, P44:P54, M25:M76, B69:B77, B66:E67, B51:B64, H44:H47, D44:D47, H42, H33:H40, D33:D42, H31, D28:D31, H28:H29, D5:D8" & Cells(Rows.Count, "B").End(xlUp).Row)
For Each cell In rngData
cell.Offset(0, 0).Font.Color = vbBlack ' DEFAULT COLOR
' LOCATE DUPLICATE VALUE(S) IN THE SPECIFIED RANGE OF DATA.
If Application.Evaluate("COUNTIF(" & rngData.Address & "," & cell.Address & ")") > 1 Then
cell.Offset(0, 0).Font.Color = vbRed ' CHANGE FONT COLOR TO RED.
End If
Next cell
Set rngData = Nothing
Application.ScreenUpdating = True
End Sub
But I get a "Type Mismatch" error at:
If Application.Evaluate("COUNTIF(" & rngData.Address & "," & cell.Address & ")") > 1 Then
How can I get around this?
As per comment you would need to loop twice:
Sub Duplicate()
Dim rngData As Range
Dim cell As Range
Dim cell2 As Range
Set rngData = Range("P3:P19, P56:P58, P39:P42, P21:P25, P27:P37, P39:P42, P39:P42, P44:P54, M25:M76, B69:B77, B66:E67, B51:B64, H44:H47, D44:D47, H42, H33:H40, D33:D42, H31, D28:D31, H28:H29, D5:D8" & Cells(Rows.Count, "B").End(xlUp).Row)
rngData.Font.Color = vbBlack
For Each cell In rngData
If cell.Font.Color = vbBlack Then
For Each cell2 In rngData
If cell = cell2 And cell.Address <> cell2.Address Then
cell.Font.Color = vbRed
cell2.Font.Color = vbRed
End If
Next
End If
Next
Set rngData = Nothing
Application.ScreenUpdating = True
End Sub

Variables in Conditional Formatting Formula1

I'm trying to use variables in the FormatCondition Formula1 property. The variables will be cell references. However, I can't get the syntax right. The two bits I'm having trouble with in the code below are: "=(C$3:J$10=""CM"")" and "=($C3:$J10=""RM"")".
The aim of this is to highlight a column with CM in a certain cell, and to highlight a row with RM in a certain cell. The number of columns and rows will increase and decrease, hence the use of variables.
Or if this isn't the right way or the best way, alternatives would be appreciated.
The code is:
Private Sub Workbook_Open()
Application.ScreenUpdating = False
'Rows
Dim iRowA As Integer, iRowB As Integer, iRowC As Integer
Dim iRowDataStart As Integer, iRowLast As Integer
'Columns
Dim iColX As Integer, iColY As Integer, iColZ As Integer
Dim iColDataStart As Integer, iColLast As Integer
'Ranges
Dim rAll As Range
Dim rRowB As Range, rColY As Range
Dim rRowMark As Range, rColMark As Range
'String
Dim sString As String
'Assign values, normally these would be variable values, not assigned
iRowA = 1: iRowB = 2: iRowC = 3
iRowDataStart = 4: iRowLast = 10
iColX = 1: iColY = 2: iColZ = 3
iColDataStart = 4: iColLast = 10
'Set ranges
Set rAll = Range(Cells(iRowA, iColX), Cells(iRowLast, iColLast))
Set rRowB = Range(Cells(iRowB, iColZ), Cells(iRowLast, iColLast))
Set rColY = Range(Cells(iRowC, iColY), Cells(iRowLast, iColLast))
Set rRowMark = Range(Cells(iRowC, iColZ), Cells(iRowLast, iColLast))
Set rColMark = Range(Cells(iRowC, iColZ), Cells(iRowLast, iColLast))
'Delete all CF currently in the worksheet
With rAll
.FormatConditions.Delete
End With
'Format column with Column Mark
sString = "=(C$3:J$10=""CM"")"
With rRowB
.FormatConditions.Add _
Type:=xlExpression, _
Formula1:=sString
.FormatConditions(.FormatConditions.Count).SetFirstPriority
With .FormatConditions(1)
.Interior.Color = RGB(196, 189, 151)
.StopIfTrue = False
End With
End With
'Format row with Row Mark
sString = "=($C3:$J10=""RM"")"
With rColY
.FormatConditions.Add _
Type:=xlExpression, _
Formula1:=sString
.FormatConditions(.FormatConditions.Count).SetFirstPriority
With .FormatConditions(1)
.Font.ColorIndex = 2
.Interior.Color = RGB(127, 127, 127)
.StopIfTrue = False
End With
End With
Range("A1").Select
Application.StatusBar = False
Application.CutCopyMode = False
End Sub
You just need to dynamically set your ranges by getting last row and column of your data where you can find many examples here like this one. Something like:
Dim r As Range
Dim lr As Long, lc As Long
Dim formula As String
With Sheet1 '~~> change to your actual sheet
lr = .Range("C" & .Rows.Count).End(xlUp).Row '~~> based on C, adjust to suit
lc = .Cells(3, .Columns.Count).End(xlToLeft).Column '~~> based on row 3
Set r = .Range(.Cells(3, 3), .Cells(lr, lc))
formula = "=(" & r.Address & "=""CM"")"
'~~> formatting code here
End With
Or you can try what I've posted here about Conditional Formatting which of course can be automated as I posted HERE and HERE. Something like:
formula = "=C3=""CM"""
[C3].FormatConditions.Add xlExpression, , formula
With [C3].FormatConditions(1)
.Interior.Color = RGB(196, 189, 151)
.ModifyAppliesToRange r
End With
HTH.

Resources