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

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

Related

Bold Top 50% of summed values & Values => 50,000

Sub Highlight_Top50_AND_50K()
Dim CheckRange As Range
With ActiveSheet
Set CheckRange = .Range("E2:E" & .Cells(.Rows.Count, "E").End(xlUp).Row)
End With
With CheckRange
.FormatConditions.Add Type:=xlCellValue, Operator:=xlGreaterEqual, Formula1:="=0.5*SUM(E:E)", Formula2:="=50,000"
.FormatConditions(.FormatConditions.Count).SetFirstPriority
With .FormatConditions(1)
.Font.Bold = True
.StopIfTrue = False
End With
End With
End Sub
Within Range (E2:E),
CONDITION 1: Bold values that are greater than and equal to 50% of the summed values.
CONDITION 2: Bold values that are greater than and equal to 50,000.
The codes ran without error but nothing is generated. Could someone please enlighten me?
Test below code and see if it works for you. The code you've posted just adds one condition and not both the conditions you have stated!
With CheckRange
.FormatConditions.Delete
.FormatConditions.Add Type:=xlCellValue, Operator:=xlGreaterEqual, Formula1:="50000"
With .FormatConditions(1)
.Font.Bold = True
.StopIfTrue = False
End With
.FormatConditions.Add Type:=xlCellValue, Operator:=xlGreaterEqual, Formula1:="=0.5*SUM(E:E)"
.FormatConditions(.FormatConditions.Count).SetFirstPriority
With .FormatConditions(1)
.Font.Bold = True
.StopIfTrue = False
End With
End With
For some reason i couldn't figure why one of your conditions is not working, but if it helps you this alternative should do the job
Sub Highlight_Top50_AND_50K()
Dim CheckRange As Range
Dim x As Range
Dim formula1 As Long
formula1 = Evaluate("=0.5*SUM(E:E)") 'define your first condition
Set CheckRange = Range("E2:E" & Range("E" & Rows.Count).End(xlUp).Row)
For Each x In CheckRange
x.Font.Bold = False
If x >= formula1 Then 'check if greater or equal than 50% of the summed values
x.Font.Bold = True
End If
If x >= 50000 Then ' check if greater or equal to 50,000
x.Font.Bold = True
End If
Next
End Sub

Bold Top 50% of the summed values in Column E and their rows

After seeking help in stackoverflow, I came back with the skeleton of the vba codes (still not working though), however it is not generating the outcome that I desire.
Sub Highlight_Top50()
Dim CheckRange As range
Set CheckRange = range("E2:E", Cells(Rows.Count, "E").End(xlUp)).Row
Selection.FormatConditions.AddTop10
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1)
.TopBottom = xlTop10Top
.Rank = 50
.Percent = True
End With
With Selection.FormatConditions(1).Font.Bold = True
End With
Selection.FormatConditions(1).StopIfTrue = False
End Sub
Under Conditional Formatting, there's no such rule as "Highlight Top 50% of the summed value". The nearest Excel provides is "Format cells that rank in Top: x%".
You're close. There are a couple of problems to fix.
The first is to ALWAYS make sure you're specifying a worksheet reference. Notice in the code below there is a '.' before ALL of the sheet references. This ensures you're referencing the sheet in the With clause.
With ActiveSheet
Set CheckRange = .Range("E2:E" & .Cells(.Rows.Count, "E").End(xlUp).Row)
End With
Also, when you're counting the rows until the end of the data, the .Row was in the wrong place (outside of the )).
Next, you set up your CheckRange variable but you don't use it. You should avoid using Select. So just make the references for the FormatConditions to your CheckRange.
With CheckRange
...
End With
Here is the corrected method.
Sub Highlight_Top50()
Dim CheckRange As Range
With ActiveSheet
Set CheckRange = .Range("E2:E" & .Cells(.Rows.Count, "E").End(xlUp).Row)
End With
With CheckRange
.FormatConditions.AddTop10
.FormatConditions(.FormatConditions.Count).SetFirstPriority
With .FormatConditions(1)
.TopBottom = xlTop10Top
.Rank = 50
.Percent = True
.Font.Bold = True
.StopIfTrue = False
End With
End With
End Sub

Conditional Formatting blank cells -VBA

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).

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

Color formatting of Rows based on input values for a cell

There is some data in the worksheet, which includes a column for time. Time Range is provided as an Input to format the color of the time cells within that time range. Color formatting of the rows containing those cells is also desired but is not observed in the output. It is to mention that the start time or end time provided as input is sometimes not matching value of any time cell.
Attached is the code and is not giving desired output.
Any kind of help will be appreciated.
Dim ws As Worksheet
Dim timeRange As Range
Set ws = Sheets("Worksheet") 'Name of my worksheet goes here.
Set timeRange = ws.Range("D:D")
'input the lower limit and the upper limit of the search range
Dim Start_Time As Variant
Dim End_Time As Variant
Start_Time = InputBox(prompt:="Enter the Start_Time(hh:mm:ss.000)")
End_Time = InputBox(prompt:="Enter the End_Time(hh:mm:ss.000)")
timeRange.FormatConditions.Add Type:=xlCellValue, Operator:=xlBetween, _
Formula1:=Start_Time, Formula2:=End_Time
timeRange.FormatConditions(timeRange.FormatConditions.Count).SetFirstPriority
With timeRange.FormatConditions(1).Font
.Color = -16383844
.TintAndShade = 0
End With
With timeRange.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 13551615
.TintAndShade = 0
End With
timeRange.FormatConditions(1).StopIfTrue = False
'Loop to format the rows that contains those time values
Dim Range_Search As String
For Each c In Range("D:D")
If c.Interior.Color = 13551615 Then
Range_Search = "A" & c.Row & ":" & "H" & c.Row
ws.Range(Range_Search).Interior.Color = 13551615
End If
Next c
The final loop in your code won't work. You need to change it to:
For Each c In Range("D:D")
If c.Interior.Color = 13551615 Then
Range_Search = "A" & c.Row & ":" & "H" & c.Row
Range(Range_Search).Select
Selection.Interior.Color = 13551615
End If
Next c
I'm not sure what the "Let" is supposed to do in your statement, but it's not necessary. Also, you need to get the Row from cell c, not just c.
To make this even better, I would reference the cells by the worksheet as this will prevent possible problems from selecting different worksheets:
Dim ws As worksheet
Dim timeRange As Range
Set ws = Sheets("mySheet") 'Obviously change this to your sheet name
Set timeRange = ws.Range("D:D")
Then replace "Selection." with "timeRange." in your code, so
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlBetween, _
Formula1:=Start_Time, Formula2:=End_Time
becomes:
timeRange.FormatConditions.Add Type:=xlCellValue, Operator:=xlBetween, _
Formula1:=Start_Time, Formula2:=End_Time
Then change your final loop to do something similar:
For Each c In timeRange
If c.Interior.Color = 13551615 Then
ws.Range("A" & c.Row & ":" & "H" & c.Row).Interior.Color = 13551615
End If
Next c
Selecting cells is not efficient and can cause problems if something else inadvertently gets selected while you are trying to run the code.
I figured it out. Thanks to OpiesDad for help.
Basically the format condition color is not recognize by the vba until you add DisplayFormat. before the interior.color command. so something like.
For Each c In timeRange
If c.**DisplayFormat**.Interior.Color = 13551615 Then
ws.Range("A" & c.Row & ":" & "H" & c.Row).Interior.Color = 13551615
End If
Next c

Resources