Conditional Formatting blank cells -VBA - excel

I need to highlight a cell in column B if it is less than value in column F. For example if cell B2 is 10 and F2 is 20, B2 should be red. However in column B there are blank cells i do not want these highlighted. For example B6 is blank but F6 is 10. In my code B6 become red as well.
Also how would i highlight a cell in the same row that is already highlighted. For example, if B2 is highlighted, highlight F2.
My code is below:
Sub threecf()
Dim rg As Range
Dim cond1 As FormatCondition, cond2 As FormatCondition
Set rg = Range("B2", Range("B2").End(xlDown))
'clear any existing conditional formatting
rg.FormatConditions.Delete
'define the rule for each conditional format
Set cond1 = rg.FormatConditions.Add(xlCellValue, xlLess, "=f2")
Set cond2 = rg.FormatConditions.Add(xlCellValue, xlEqual, "=isempty(f2)")
'define the format applied for each conditional format
With cond1
.Interior.Color = vbRed
.Font.Color = vbWhite
End With
With cond2
.Interior.Color = vbWhite
.Font.Color = vbWhite
End With
End Sub

As mentioned in my comment, use formulas. No need to use VBA
Easiest Way (Recommended Way)
I recommend this way because it takes into account new rows that are being added.
Select Col B
Select Home Tab | Conditional formatting | New Rule | Use a formula to determine which cells to format
Enter the formula =AND(B1<F1,B1<>"")
Select Format | Fill Tab
Set Fill color to red :)
Customized Way
Manually select cells B2 to last row in col B
Select Home Tab | Conditional formatting | New Rule | Use a formula to determine which cells to format
Enter the formula =AND(B2<F2,B2<>"")
Select Format | Fill Tab
Set Fill color to red :)
VBA Way
If you still want VBA then try this
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long
'~~> Change as applicable
Set ws = Sheet1
With ws
lRow = .Range("B" & .Rows.Count).End(xlUp).Row
With .Range("B2:B" & lRow)
.FormatConditions.Add Type:=xlExpression, Formula1:="=AND(B2<F2,B2<>"""")"
.FormatConditions(.FormatConditions.Count).SetFirstPriority
With .FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
End With
.FormatConditions(1).StopIfTrue = False
End With
End With
End Sub

Go to conditional formatting --> New Rule --> Use a formula to determine which cells to format --> Paste This: =IF(AND(B2<F2,B2<>"") = TRUE,1,0)
For the F column: =IF(AND(F2>B2,F2<>"") = TRUE,1,0)

If you want a VBA solution, try it without conditional formatting:
Sub StackOverflow()
Dim x As Long
With ThisWorkbook.Sheets("Stack")
For x = 1 To .Cells.Find("*", SearchOrder:=xlByRows, LookIn:=xlValues, SearchDirection:=xlPrevious).Row
If .Cells(x, 2).Value <> "" And .Cells(x, 2).Value < .Cells(x, 6).Value Then
.Cells(x, 2).Interior.Color = vbRed
.Cells(x, 6).Interior.Color = vbRed
.Cells(x, 2).Font.Color = vbWhite
.Cells(x, 6).Font.Color = vbWhite
Else
.Cells(x, 2).Interior.Pattern = xlNone
.Cells(x, 6).Interior.Pattern = xlNone
.Cells(x, 2).Font.Color = vbBlack
.Cells(x, 6).Font.Color = vbBlack
End If
Next x
End With
End Sub
Adapt the code to your needs (change the macro name, spreadsheet address and colors if you want).

Related

Conditional Formatting by first couple of letters in string [VBA]

I'm trying to make the font of some VBA cells bold by applying .FormatConditions.Add(xlTextString, etc.) to a range.
I'd like to bold cells within this range if the value of the cells within the range start with the letter "V"
Below is a portion of the code I'm using. I'm interested in getting from here to a functional result, but I'm not sure where to go from here -- can anyone advise?
With .Range("L2:EZ5000").FormatConditions
.Add(xlTextString,)
End With
From the macro recorder:
Selection.FormatConditions.Delete
Selection.FormatConditions.Add Type:=xlExpression, _
Formula1:="=LEFT(A1,1)=""V"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Font
.Bold = True
.Italic = False
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
and tidied up:
Dim rng As Range, fc As FormatCondition
Set rng = Selection
rng.FormatConditions.Delete
With rng.FormatConditions.Add(Type:=xlExpression, _
Formula1:="=LEFT(" & rng.Cells(1).Address(False, False) & ",1)=""V""")
.SetFirstPriority
.Font.Bold = True
.StopIfTrue = False
End With
Conditional Formatting is limited to three different formats. With VBA you can overcome this limitation.
Using a loop and either InStr or Left to check the first character in each cell, and bold the font in the cells that have an "A" in the first character position.
For Each Cel in ThisWorkbook.Sheets("Sheet1").Range("L2:EZ5000")
If InStr(1, cel.Value, "A") Then cel.Font.Bold = True
'Or use... If (Left(cel, 1) = "A") Then cel.Font.Bold = True
Next cel

is there any code which identifies a particular cell ( b2) true and then subsitute the formula in another cell (i2)?

the yellow highighted is where the data is entered lets say cell b2 is data entry.. and i2 to AD2 are the cells in which formulas are suppose to be set.
i need a vba code which identifies b2 = any amount/symbol if its true, I2 to ad2 should insert this if formula [[IF($I$1=D2,G2,"")]
This should be applied in all the rows
Please place this in your worksheet's module.
It checks, whether cell B2 is changed and contains something, and then places the formula in whole range, starting at I2:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim RelevantArea As Range
Dim lastRow As Long
Set RelevantArea = Intersect(Target, Me.Range("B2"))
If Not RelevantArea Is Nothing Then
If Len(Target.Value2) > 0 Then
' find the last used row, e. g. in column 9:
lastRow = Me.Cells(Me.Rows.Count, 9).End(xlUp).Row
Application.EnableEvents = False
Me.Range("I2:AD" & lastRow).Formula = "=IF(I$1=$D2,$G2,"""")"
Application.EnableEvents = True
End If
End If
End Sub
The formula is inserted into the range like you would get it, if you copy the formula of the first cell (here: I2) to the rest of the range. I changed the formula a little, assuming you wanted it like that.
By following you get it for the changed row only, i. e. if you paste into e. g. B5:B9, it works for rows 5 to 9.
You can use the A1- or R1C1-notation to adapt the formula to your needs.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim MonitoredArea As Range
Dim CurrentRow As Long
Dim CurrentCell As Range
Set MonitoredArea = Intersect(Target, Me.Range("B:B"))
If Not MonitoredArea Is Nothing Then
For Each CurrentCell In MonitoredArea.Cells
If Len(CurrentCell.Value2) > 0 Then
CurrentRow = CurrentCell.Row
Application.EnableEvents = False
With Me.Range(Me.Cells(CurrentRow, "I"), Me.Cells(CurrentRow, "AD"))
.Formula = "=IF(I$1=$D" & CurrentRow & ",$G" & CurrentRow & ","""")"
'.FormulaR1C1 = "=IF(R1C=RC4,RC7,"""")"
Dim i As Integer
For i = xlEdgeLeft To xlInsideHorizontal ' all borders
With .Borders(i)
.LineStyle = xlContinuous
.Weight = xlThin
.Color = RGB(0, 0, 0)
.TintAndShade = 0
End With
Next i
End With
Application.EnableEvents = True
End If
Next CurrentCell
End If
End Sub

Highlight cell if greater than today

I'm trying to highlight cells that have a date greater than today's date.
Column H is formatted as Date.
I have the following:
Sub Test()
Dim lrow As Long
lrow = Cells(Rows.Count, 1).End(xlUp).Row
Columns("H:H").EntireColumn.AutoFit
If Range("H2:H" & lrow).Value > Date Then Cell.Interior.Color = vbYellow
End Sub
I get a "Type Mismatch" error.
Range("H2:H" & lrow).Value will be a 2D array (the Value of a Range is always a 2D array if more than a single cell is involved); you're getting a type mismatch error because you can't compare a 2D array to a Date; if you can't use a conditional formatting, you need to compare the individual array subscripts.
Last thing you want to do is to iterate each individual cells (otherwise your next question will be "how do I make this loop run faster?"). Get that array into a Variant, and iterate that array - since it's only 1 column, make it a 1D array with Application.Transpose:
Dim values As Variant
values = Application.Transpose(Range("H2:H" & lastRow).Value)
Dim i As Long, current As Long
For i = LBound(values) To UBound(values)
current = i + 1 'array would be 1-based, so to start at row 2 we need to offset by 1
If values(i) > Date Then
ActiveSheet.Cells(current, 8).Interior.Color = vbYellow
End If
Next
That way you only hit the worksheet when you have to.
In response to #MatthieuGuindon's suggestion to #CharlesPL's answer, here's some code that does the conditional formatting. I've set it so it highlights dates that are after the day you run it as a bright yellow.
Option Explicit
Sub setCondFormat()
Dim lrow As Long
lrow = ActiveSheet.Range("H" & ActiveSheet.Rows.Count).End(xlUp).Row
With Range("H2:H" & lrow)
.FormatConditions.Delete
.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=H2>TODAY()"
With .FormatConditions(.FormatConditions.Count)
.SetFirstPriority
With .Interior
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
End With
End With
End With
End Sub
Use conditional formatting! As the name suggests, this is build for that!
Microsoft blog post on date conditional formating
I would recommend iterating over the range of cells and testing each cell individually. Please see below.
Dim rng As Range, cell As Range
Set rng = Range("H:H")
For Each cell In rng
If cell.Value > Date Then cell.Interior.Color = vbYellow
Next cell

How do you change the formated font color of a cell using VBA?

I would like to select rows in my excel sheet based on a criteria and then edit the format of other cells in the same row.
I know that I can select rows using autofilters (column n equals ""):
Sub beautify()
Dim rng As Range
Set rng = ActiveSheet.Range("F60:AJ3272")
rng.AutoFilter Field:=4, Field:=4, Criteria1:=""
End Sub
Now how do I change the font of column F of the lines that I have selected to white.
You can use VBA to change the background color of a cell using .Interior.ColorIndex = RGB(r, g, b) : red and the font color of the text inside a cell with .Font.Color = RGB(r, g, b) : red
The range to change these property on should be defined, like mentionned in your question by the column and the row you selected so say you chose column F and row 12 it should look like this:
Range("F12").Font.Color = -4142
So say you want to scroll through every row of a column, and change the color of every blank cell what you could do is :
Dim i As Long
For i = 1 To Rows.Count
'Column F is 6
If Cells(i, 6).Value = "" Then
Cells(i, 1).Interior.ColorIndex = RGB(150, 0, 0)
Next i
I made slight modifications to your code and it worked:
Sub beautify()
Dim i As Long
For i = 1 To 50
If Cells(i, 9).Value = "" Then
ActiveSheet.Range(Cells(i, 10), Cells(i, 31)).Font.Color = vbBlack
ActiveSheet.Range(Cells(i, 8), Cells(i, 8)).Font.Color = vbWhite
End If
Next i
End Sub

VBA StrComp - Compare values with exceptions

enter image description hereI have today's data in column D which I want to compare with yesterday's data in column F, row wise.
Below is the code I'm using to compare and highlight duplicates.
A) Highlighting blank cells which I don't want.
B) I want to handle some exceptions like I don't wish to highlight $0.00 or specific text "No Data"
Sub CompareAndHighlight()
Dim Myrng1 As Range, Myrng2 As Range, i As Long, j As Long
Application.ScreenUpdating = False
For i = 3 To Sheets("Sheet1").Range("D" & Rows.Count).End(xlUp).Row
Set Myrng1 = Sheets("Sheet1").Range("D" & i)
For j = 3 To Sheets("Sheet1").Range("F" & Rows.Count).End(xlUp).Row
Set Myrng2 = Sheets("Sheet1").Range("F" & j)
If StrComp(Trim(Myrng1.Text), Trim(Myrng2.Text), vbTextCompare) = 0 Then
'If Myrng1.Value = Myrng2.Value Then
Myrng1.Interior.Color = RGB(255, 255, 0)
End If
Set Myrng2 = Nothing
Next j
Set Myrng1 = Nothing
Next i
Application.ScreenUpdating = True
End Sub
Data giving random errors on running macros multiple times after clearing highlighted colors.
Use the conditional formatting function.
Columns("A:A").Select
Selection.FormatConditions.AddUniqueValues
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
Selection.FormatConditions(1).DupeUnique = xlDuplicate
With Selection.FormatConditions(1).Font
.Color = -16383844
.TintAndShade = 0
End With
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 13551615
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
Then after this create one loop that goes through your range and turns the colour of the cell to no colour where your conditions are met, alternatively you could just filter the data to exclude your cases, such as "No Data", and copy and paste the results into a new column. In fact you do not really need vba for this.
sticking with VBA you could try the following code:
Option Explicit
Sub CompareAndHighlight()
Dim refRng As Range, cell As Range
Application.ScreenUpdating = False
With Worksheets("Sheet1")
Set refRng = .Range("F3", .Cells(.Rows.Count, "F").End(xlUp)).SpecialCells(XlCellType.xlCellTypeConstants)
For Each cell In .Range("D3", .Cells(.Rows.Count, "D").End(xlUp)).SpecialCells(XlCellType.xlCellTypeConstants)
If cell.value <> 0 And cell.value <> "No Data" Then
If refRng.Find(what:=cell.value, LookIn:=xlFormulas, lookat:=xlWhole, MatchCase:=False) Is Nothing Then cell.Interior.color = RGB(255, 255, 0)
End If
Next cell
End With
Application.ScreenUpdating = True
End Sub

Resources