Using VBA to select a group of cells based on same values - vba

I would like write a VBA code to select a group of cells that has the same value and colour it.
MySpreadSheet
For Row A, Staff ID, are the same, for the same person, I intend to scan through them and if they are the same, fill the cells with the light blue colour you see in the picture above, for Column A to MaxColumn of Current Region.
I have a drafted a code to do that but it does nothing when I run it. Any help will be appreciated:
Sub ActualColouring()
Dim SerialNumber As Integer
SerialNumber = 2 'this variable will be assign to the rows, ignore the header, start from 2
Do While Cells(1, SerialNumber).Value <> "" 'keep looping as long as cell is not blank
If Cells(1, SerialNumber).Value = Cells(1, SerialNumber + 1).Value Then 'if the value of the cell is the same as the cell below, then
Cells(1, SerialNumber).Select 'then select it
With Selection.Interior 'this line is the start of the fill colouring
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.799981688894314
.PatternTintAndShade = 0
End With 'end of fill colouring function
End If
SerialNumber = SerialNumber + 1 'move to the next cell
Loop 'loop until the end of current region
End Sub

Qualify the objects and avoid select
Sub ActualColouring()
Dim ws as Worksheet
Set ws = ThisWorkbook.Worksheets("mySheet") ' change name as needed
With ws
Dim SerialNumber As Long, lRow as Long
lRow = .Range("A" & .Rows.Count).End(xlup).Row
For SerialNumber = 2 to lRow
If .Cells(1, SerialNumber).Value = .Cells(1, SerialNumber + 1).Value Then
With .Cells(1, SerialNumber).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.799981688894314
.PatternTintAndShade = 0
End With
End If
Next
End With
End Sub

Related

VBA loop through columns and check for specific color of cells

I am trying to loop through a range by column. When a specific color is detected in any cell within the column, it should go to the next column. Or, if the color is not present at all, mark a cell in a specific row. Should look like this:
With my current code, it is not always hitting the right cell, that needs to be marked. Can anyone help please?
Dim rng, cell, col As Range
Dim colcount, Lcount As Integer
Set rng = Sheet2.Range("B2:J4")
For Each col In rng.Columns
For Each cell In col.Cells
If cell.Interior.ThemeColor = xlThemeColorAccent5 Then
Lcount = Lcount + 1
colcount = cell.Column
End If
Next cell
If Lcount >= 1 Then
Lcount = 0
GoTo Continues
Else
With Sheet2.Cells(5, colcount).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
End With
End If
Continues:
Next col
Solved it. Sometimes one does not see the forrest through the trees
Dim rng, cell, col As Range
Dim colcount, Lcount As Integer
Set rng = Sheet2.Range("B2:J4")
For Each col In rng.Columns
For Each cell In col.Cells
If cell.Interior.ThemeColor = xlThemeColorAccent5 Then
Lcount = Lcount + 1
Else
colcount = cell.Column
End If
Next cell
If Lcount > 0 Then
Lcount = 0
GoTo Continues
Else
With Sheet2.Cells(5, colcount).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
End With
End If
Continues:
Next col

vba conditional formatting to columns

i am a newbie in VBA, so i come across with several issues.
I have a dataset that looks like this:
I have to compare column A with columns B,C,D,E and F and then color the fonts of the cells in columns B:F under these conditions:
If cells in column A are equal with the cells in columns B:F, paint their font orange.
If cells in column A are higher than the cells in columns B:F, paint their font red.
If cells in column A are lower than the cells in columns B:F, paint their font green.
If the absolute difference between column A and the rest columns (B:F) is less than 1, paint their font orange.
I have tried to write a simple macro and all conditions are met except the 4th.
Here is my attempt.
Sub ConditionalFormating()
Dim i, j, a As Double
a = 0.99
i = 2
j = 2
For j = 1 To 6
For i = 2 To 10
ActiveSheet.Cells(i, j).Select
If ActiveSheet.Cells(i, j) - ActiveSheet.Cells(i, 1) >= a Then
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = RGB(255, 156, 0)
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
If ActiveSheet.Cells(i, j) - ActiveSheet.Cells(i, 1) <= a Then
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = RGB(255, 156, 0)
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
If ActiveSheet.Cells(i, j) > ActiveSheet.Cells(i, 1) Then
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = RGB(0, 255, 0)
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
If ActiveSheet.Cells(i, j) < ActiveSheet.Cells(i, 1) Then
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = RGB(255, 0, 0)
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
Next
Next
End Sub
Could anyone help me? I cannot understand why the 4th condition is not met when all others are.
Thank you in advance!
To color the font, you have to use the Font property of Range, like: Selection.Font.Color=RGB(255,128,0).
you could try this (commented) code:
Option Explicit
Sub ConditionalFormating()
Dim cell As Range, cell2 As Range, dataRng As Range
Dim colOrange As Long, colRed As Long, colGreen As Long, col As Long
colOrange = RGB(255, 156, 0)
colRed = RGB(255, 0, 0)
colGreen = RGB(0, 255, 0)
With Worksheets("CF") '<--| reference the relevant worksheet (change "CF" to your actual worksheet name)
Set dataRng = Intersect(.Columns("B:F"), .UsedRange)
For Each cell In .Range("A2", .Cells(.Rows.Count, 1).End(xlUp)).SpecialCells(xlCellTypeConstants) '<-- loop through its column "A" not empty cells from row 1 down to last not empty one
If WorksheetFunction.CountA(Intersect(dataRng, cell.EntireRow)) > 0 Then ' if current row has data
For Each cell2 In Intersect(dataRng, cell.EntireRow).SpecialCells(xlCellTypeConstants) ' loop through current column "A" cell row not empty cells
Select Case True '<-- check the current datum against the following conditions
Case cell2.Value = cell.Value Or Abs(cell.Value - cell2.Value) < 1 'if current datum equals corresponding value in column "A" or their absolute difference is lower than 1
col = colOrange
Case cell2.Value < cell.Value 'if current datum is lower then corresponding value in column "A"
col = colRed
Case cell2.Value > cell.Value 'if current datum is higher then corresponding value in column "A"
col = colGreen
End Select
With cell2.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = col
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Next cell2
End If
Next cell
End With
End Sub

Select the column header if cell is formula

I have pieces of the code figured out, but what I can't quite get is how to parse the column and then select the first row in that column.
The objective is to color the header cell of a column, if the selected cell has a formula. The piece I'm looking for is
Sub ColorFormulaHeaders()
Dim oWkbk As Workbook
Dim oWkst As Worksheet
Dim oRng As Range
For Each oRng In Selection.Cells
If oRng.HasFormula Then
'Select Column Header
With Selection
.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
End Sub
You have the right idea. Here is one way to get to the column header:
Sub ColorFormulaHeaders()
Dim oWkbk As Workbook
Dim oWkst As Worksheet
Dim oRng As Range
For Each oRng In Selection.Cells
If oRng.HasFormula Then
With oRng.EntireColumn.Cells(1).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
Next oRng
End Sub
You can use similar technique to get a row label for a cell in some row if the label is in column A for that cell.

Highlight all rows equal to value in cell foobar

I am trying to code this procedure to highlight all rows of which have a value of "N" in their respective row within Column N
I am not too familiar with coding VBA formatting and I cannot get this procedure to function
Sub highlight_new_pos()
Dim rng As Range, lCount As Long, LastRow As Long
Dim cell As Object
With ActiveSheet 'set this worksheet properly!
LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
For Each cell In .Range("N2:N" & LastRow)
If cell = "N" Then
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Next cell
End With
End Sub
Option Explicit
Sub highlight_new_pos()
Dim cel As Object
With ActiveSheet
For Each cel In .Range("N2:N" & .Cells(.Rows.Count, 14).End(xlUp).Row)
If UCase(cel.Value2) = "N" Then cel.Interior.Color = 65535
Next
End With
End Sub
This will be faster if you have a lot of rows:
Sub highlight_new_pos1()
Application.ScreenUpdating = False
With ActiveSheet
With .Range("N1:N" & .Cells(.Rows.Count, 14).End(xlUp).Row)
.AutoFilter Field:=1, Criteria1:="N"
.Offset(1, 0).Resize(.Rows.Count - 14, .Columns.Count).Interior.Color = 65535
.AutoFilter
End With
End With
Application.ScreenUpdating = True
End Sub
In your code, you are looping through the cells, but you're still changing the color of the initial selection (not of the cell in the loop). Adjust as follows:
Sub highlight_new_pos()
Dim rng As Range, lCount As Long, LastRow As Long
Dim cell As Object
With ActiveSheet 'set this worksheet properly!
LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
For Each cell In .Range("N2:N" & LastRow)
If cell = "N" Then
With cell.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End if
Next cell
End With
End Sub
If you want the entire row, change cell.Interior to cell.entirerow.Interior

VBA Excel - Row cells locking/unlocking using Conditional formatting?

Hi, my sheet has 103 columns and 18550 rows of data which is coming from database. Based on B column cells value i have to apply formatting for the respective row like [if B2 value is 1 then for that row interior color should be Orange in color else if it is -1 then it should be in Blue else if it is 0 then the columns F & G should be Green in color and these green coloured cells should not be locked. And every 1 valued row and the immediate -1 valued rows should be grouped. Currently i have the following code which is almost taking 8 minutes of time to apply formattings.
With ThisWorkBook.Sheets("RoAe").Range("A1:A" & rowLen)
'=================For 1 valued Rows==========
Set C = .Find("1", LookIn:=xlValues)
x=0
If Not C Is Nothing Then
firstAddress = C.Address
Do
valR = Split(C.Address, "$")
actVal = valR(2)
ReDim Preserve HArray(x)
HArray(x) = actVal + 1
x = x + 1
With ThisWorkBook.Sheets("RoAe").Range("D" & actVal & ":FN" & actVal)
.Rows.AutoFit
.WrapText = True
.Font.Bold = True
.Interior.Color = RGB(252,213,180)
.Borders.Color = RGB(0, 0, 0)
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
End With
Set C = .FindNext(C)
Loop While Not C Is Nothing And C.Address <> firstAddress
End If
'=================For -1 valued Rows==========
Set C = .Find("-1", LookIn:=xlValues)
y=0
If Not C Is Nothing Then
firstAddress = C.Address
Do
valR = Split(C.Address, "$")
actVal = valR(2)
ReDim Preserve HArray(y)
FArray(y) = actVal + 1
y = y + 1
With ThisWorkBook.Sheets("RoAe").Range("D" & actVal & ":FN" & actVal)
.Rows.AutoFit
.WrapText = True
.Font.Bold = True
.Interior.Color = RGB(141,180,226)
.Borders.Color = RGB(0, 0, 0)
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
End With
Set C = .FindNext(C)
Loop While Not C Is Nothing And C.Address <> firstAddress
End If
'===================For 0(Zero) Valued Rows============
For p = 0 To UBound(HArray)
groupRange = "A" & HArray(p) & ":A" & FArray(p)
For i = 0 To UBound(arrUnlockMonthStart)
unlockRange = F & (HArray(p) + 1) & ":" & G & FArray(p)
ThisWorkBook.Sheets("RoAe").Range(unlockRange).Locked = False
ThisWorkBook.Sheets("RoAe").Range(unlockRange).Interior.Color = RGB(216,228,188)
Next
next
end with
ThisWorkBook.Sheets("RoAe").protect "12345"
Can we do the same with Conditional Formatting. Applying format & locking/unlocking for the rows based on cell value. Any help would be appreciated greatly.
As i mentioned that you cannot lock/unlock a cell in conditional formatting. You will have to first apply the conditional formatting and then lock/unlock the cells. Also you do not need to loop to apply conditional formatting. You can do that in one go.
Try this
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, i As Long
Dim Rng As Range, unlockRng As Range
'~~> Set this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Find the last row in Col B
lRow = .Range("B" & .Rows.Count).End(xlUp).Row
'~~> Set your range where CF will be applied for -1/1
Set Rng = .Range("D2:H" & lRow)
With Rng
.FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=1"
.FormatConditions(1).SetFirstPriority
With .FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0.399945066682943 '<~~ Orange
End With
.FormatConditions(1).StopIfTrue = True
.FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=-1"
.FormatConditions(2).SetFirstPriority
With .FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorLight2
.TintAndShade = 0.599993896298105 '<~~ Blue
End With
.FormatConditions(1).StopIfTrue = True
End With
'~~> Set your range where CF will be applied for 0
Set Rng = .Range("F2:G" & lRow)
With Rng
.FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=0"
.FormatConditions(3).SetFirstPriority
With .FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent3
.TintAndShade = 0.399975585192419 '<~~ Green
End With
.FormatConditions(1).StopIfTrue = True
End With
'~~> Loop through cells in Col B to checl for 0 and store
'~~> relevant Col F and G in a range
For i = 2 To lRow
If .Range("B" & i).Value = 0 Then
If unlockRng Is Nothing Then
Set unlockRng = .Range("F" & i & ":G" & i)
Else
Set unlockRng = Union(unlockRng, .Range("F" & i & ":G" & i))
End If
End If
Next i
End With
'~~> unlock the range in one go
If Not unlockRng Is Nothing Then unlockRng.Locked = False
End Sub
ScreenShot
EDIT
For 103 Columns and 18550 Rows use this method. This is much faster than the above
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, i As Long
Dim Rng As Range, unlockRng As Range
'~~> Set this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
Application.ScreenUpdating = False
With ws
'~~> Find the last row in Col B
lRow = .Range("B" & .Rows.Count).End(xlUp).Row
'~~> Set your range where CF will be applied for -1/1
'~~> Taking 103 Columns into account
Set Rng = .Range("D2:DB" & lRow)
With Rng
.Locked = True
.FormatConditions.Delete
.FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=1"
.FormatConditions(1).SetFirstPriority
With .FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0.399945066682943 '<~~ Orange
End With
.FormatConditions(1).StopIfTrue = True
.FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=-1"
.FormatConditions(2).SetFirstPriority
With .FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorLight2
.TintAndShade = 0.599993896298105 '<~~ Blue
End With
.FormatConditions(1).StopIfTrue = True
End With
'~~> Set your range where CF will be applied for 0
Set Rng = .Range("F2:G" & lRow)
With Rng
.FormatConditions.Add Type:=xlExpression, Formula1:="=$B2=0"
.FormatConditions(3).SetFirstPriority
With .FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent3
.TintAndShade = 0.399975585192419 '<~~ Green
End With
.FormatConditions(1).StopIfTrue = True
End With
'~~> Loop through cells in Col B to check for 0 and
'~~> unlock the relevant range
For i = 2 To lRow
If .Range("B" & i).Value = 0 Then
.Range("F" & i & ":G" & i).Locked = False
End If
Next i
End With
Application.ScreenUpdating = True
End Sub
As far as I know, the locking and grouping cannot be done with Conditional Formatting, the coloring however can be done.
You can color a cell based o a formula entered in conditional formatting dialog and this formula can contain relative, semi-relative and absolute references to other cells (using the $ notation as in any other formulas).
For example the "make row orange if column B = 1" can be done by setting condition formatting in cell D2 to formula =if($B1=1;TRUE;FALSE). If you put the $ in front of B as in this example, than you can apply the conditional formatting to the whole range columns D:H and it should color the lines as your script does.
Doing all the colors is just repeating the process and setting more conditional formating rules with different formulas.