VBA StrComp - Compare values with exceptions - excel

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

Related

Error 9 subscript out of range when applying conditional formatting

I want to apply some conditional formatting to my sheet, it errors out my code below
the line that errors out is
MyRange.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
do you think that i have the 2nd row hidden, may impact the method?
Sub DraxCXLImport()
Dim header As Integer
Dim r As Integer
On Error GoTo ErrorHandler
Application.EnableEvents = False
Worksheets("APM").Activate
Range("A1").CurrentRegion.Select
r = Selection.Rows.Count
If r < 3 Then
r = 3
End If
Worksheets("Cxl Policies").Activate
'drag down formulas
Worksheets("Cxl Policies").Range("A2:AA" & r).FillDown
'add conditional formatting
'Define Range
Dim MyRange As Range
Set MyRange = Worksheets("Cxl Policies").Range("S2:T" & r)
'Delete Existing Conditional Formatting from Range
MyRange.FormatConditions.Delete
'Apply Conditional Formatting to Tier cancellation hours
MyRange.FormatConditions.Add Type:=xlExpression, Formula1:="=$S3<>$T3"
MyRange.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
'remove duplicates
Worksheets("Cxl Policies").Range("A1:AA" & r).RemoveDuplicates Columns:=Array(1, 2), header:=xlYes
Worksheets("Cxl Policies").Rows(2).Hidden = True
Worksheets("Cxl Policies").Range("A1").Select
Application.EnableEvents = True
Exit Sub
ErrorHandler:
MsgBox Err.Number & " " & Err.Description
Err.Clear
Application.EnableEvents = True
Resume Next
End Sub
You're using both MyRange and Selection in the line that's erroring - that's probably the cause of the problem.
However, FormatConditions.Add() returns the added FormatCondition, so you can simplify your code by using the return value directly in a With block:
Dim MyRange
'...
'...
Set MyRange = Worksheets("Cxl Policies").Range("S2:T" & r)
MyRange.FormatConditions.Delete
With MyRange.FormatConditions.Add(Type:=xlExpression, Formula1:="=$S3<>$T3")
.SetFirstPriority
.StopIfTrue = False
With .Interior
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
End With
End With

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

VBA Excel Highlighting cells based on cell input

I'm trying to create a VBA script to highlight a particular range of cells when a user inputs any value in the cell. For example my cell range will be a1:a5, if a user enters any value in any cells within the range, cells a1 till a5 will be highlighted in the desired color. I'm a new user with VBA and after searching for a while found the below code that might be useful. Looking for advice. Thanks.
Private Sub Highlight_Condition(ByVal Target As Range)
Dim lastRow As Long
Dim cell As Range
Dim i As Long
With ActiveSheet
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Application.EnableEvents = False
For i = lastRow To 1 Step -1
If .Range("C" & i).Value = "" Then
Debug.Print "Checking Row: " & i
.Range("A" & i).Interior.ColorIndex = 39
.Range("F" & i & ":AW" & i).Interior.ColorIndex = 39
Next i
Application.EnableEvents = True
End With
End Sub
Edit: Trying to edit the code given by teylyn to be able to remove highlight from cells if cell value is removed however I can't seem to find the solution. (The original code will highlight the cells when there is input in cells however if you remove the cell value the highlight remains there.)
If Not Intersect(Target, Range("A12:F12")) Is Nothing Then
With Range("A12:F12").Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ElseIf IsEmpty(Range("A12:F12").Value) = True Then
With Range("A12:F12").Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65536
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
This code does what you describe, i.e. set a fill color for range A1 to A5 when any cell in that range is edited.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A1:A5")) Is Nothing Then
With Range("A1:A5").Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
End Sub
This code needs to be put in the sheet module.
Edit: If you want the highlight to disappear if none of the five cells have a value, then you can try out this variant:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim valCount As Long
If Not Intersect(Target, Range("A1:A5")) Is Nothing Then
' a cell in Range A1 to A5 has been edited
' we don't know if that edit was adding or deleting a cell, so ...
' ... we count how many cells in that range contain values
valCount = WorksheetFunction.CountA(Range("A1:A5"))
If valCount > 0 Then
' the range has values, so highlight
With Range("A1:A5").Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Else
' the range has no values, so remove the highlight
With Range("A1:A5").Interior
.Pattern = xlNone
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
End If
End Sub

Conditional Formating by groups in excel

Was wondering if there was a way to set conditional formatting separately for different groups across the same column. Something like this:
The idea is that the color scale should be done independently for the groups. In Group 1: 2 is the smallest value and therefore would be red and 50 is the highest and therefore would be green (even though there are values like 114 or 1467, it shouldn't affect this range as it belongs to a different group).
Thanks in advance!
If colour scaling within groups something like:
Public Sub FormatRanges()
Dim rng1 As Range, rng2 As Range, rng3 As Range, rng As Long
Application.ScreenUpdating = False
With ActiveSheet
Set rng1 = .Range("B1:B5")
Set rng2 = .Range("B6:B10")
Set rng3 = .Range("B11:B15")
Dim myRanges()
myRanges = Array(rng1, rng2, rng3)
For rng = LBound(myRanges) To UBound(myRanges)
ApplyFormatting myRanges(rng)
Next rng
End With
Application.ScreenUpdating = True
End Sub
Public Sub ApplyFormatting(ByRef rng As Variant)
rng.FormatConditions.Delete
rng.FormatConditions.AddColorScale ColorScaleType:=3
rng.FormatConditions(rng.FormatConditions.Count).SetFirstPriority
rng.FormatConditions(1).ColorScaleCriteria(1).Type = _
xlConditionValueLowestValue
With rng.FormatConditions(1).ColorScaleCriteria(1).FormatColor
.Color = 7039480
.TintAndShade = 0
End With
rng.FormatConditions(1).ColorScaleCriteria(2).Type = _
xlConditionValuePercentile
rng.FormatConditions(1).ColorScaleCriteria(2).Value = 50
With rng.FormatConditions(1).ColorScaleCriteria(2).FormatColor
.Color = 8711167
.TintAndShade = 0
End With
rng.FormatConditions(1).ColorScaleCriteria(3).Type = _
xlConditionValueHighestValue
With rng.FormatConditions(1).ColorScaleCriteria(3).FormatColor
.Color = 8109667
.TintAndShade = 0
End With
End Sub
Example data:
Code goes in a standard module by pressing Alt + F11 to open VBE and then right click in project and add standard module.

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