How to find a specific colour in the range and then if cell is = "" put value 0 and keep the the same colour in the cell - excel

I recently started playing with VBA and I try al I could to figure it out but without the success.
Basically what I would like to do is to find a colour in the range and then if the cell is blank, I would like to put value 0 and keep the colour.
Below is the code I created but it is not working on "If PCell.Value = "" Then"
Sub ColorCell()
PCell = RGB(255, 204, 204)
range("A:F").Select
For Each cell In Selection
If cell.Interior.Color = PCell Then
If PCell.Value = "" Then
Set cell.Value = 0
End If
End If
Next
End Sub
Below is an example of how the spreadsheet.
I would really appreciate your help. I spent all day browsing and trying but no luck :(

Your code has some issues:
Set should be used only on objects (like Worksheets or Range)
you test PCell.Value instead of cell.Value
Here is the working code:
Sub ColorCell()
PCell = RGB(255, 204, 204)
Range("A:F").Select
For Each cell In Selection
If cell.Interior.Color = PCell Then
If cell.Value = "" Then
cell.Value = 0
End If
End If
Next
End Sub

You could try:
Option Explicit
Sub test()
Dim cell As Range, rng As Range
Dim LastRow As Long
With ThisWorkbook.Worksheets("Sheet1")
LastRow = .Cells(.Rows.Count, "F").End(xlUp).Row '<- Get the last row of column F to avoid looping all the column
Set rng = .Range("A1:F" & LastRow) '<- Set the range from A1 to F last row
For Each cell In rng
If cell.Interior.Color = RGB(255, 204, 204) And cell.Value = "" Then
cell.Value = 0
End If
Next cell
End With
End Sub

Replace:
If PCell.Value = "" Then
with:
If Cell.Value = "" Then
Replace:
Set cell.Value = 0
with:
cell.Value = 0
Also avoid Select:
Sub ColorCell()
Dim PCell As Variant, Intersection As Range, Cell As Range
PCell = RGB(255, 204, 204)
Set Intersection = Intersect(Range("A:F"), ActiveSheet.UsedRange)
If Not Intersection Is Nothing Then
For Each Cell In Intersection
If Cell.Interior.Color = PCell Then
If Cell.Value = "" Then
Cell.Value = 0
End If
End If
Next
End If
End Sub
(there may be other errors in the code)

PCell is not cell
Sub ColorCell()
PCell = RGB(255, 204, 204)
For Each cell In intersect(ActiveSheet.usedrange, range("A:F"))
If cell.Interior.Color = PCell and cell.Value = "" Then
cell.Value = 0
End If
Next
End Sub

Related

Excel VBA - Change cell color based on value

In the table in the indicated range, I would like to mark the cell with the value in white, and the other cells with no value in gray. I have code but it doesn't produce any result. There is no error either. What to change to make it work
For Each cell In wbMe.Sheets("page3").Range("B76:K89")
If cell.Value = "Yes" Then cell.Interior.ColorIndex = 10
If cell.Value = "No" Then cell.Interior.ColorIndex = 3
Next cell
Please, run the next code. It will automatically place conditional formatting in the range you need:
Sub makeCondFormatting()
Dim sh As Worksheet, rng As Range, cond1 As FormatCondition, cond2 As FormatCondition
Set sh = ActiveSheet
Set rng = sh.Range("B76:K89")
With rng
.FormatConditions.Delete
Set cond1 = .FormatConditions.Add(xlExpression, Formula1:="=" & rng.cells(1, 1).Address(0, 0) & " <> """"")
Set cond2 = .FormatConditions.Add(xlExpression, Formula1:="=" & rng.cells(1, 1).Address(0, 0) & " = """"")
End With
With cond1
.Interior.color = RGB(255, 255, 255)
End With
With cond2
.Interior.color = RGB(197, 198, 198)
End With
End Sub
It will make the range cells change their interior color automatically when the cell is empty, or not.
try this code
Sub SetColor()
Dim r As Range
Set r = ThisWorkbook.ActiveSheet.Range("B2:B7")
Dim white As Long
white = RGB(255, 255, 255)
Dim grey As Long
grey = RGB(200, 200, 200)
Dim c As Range
For Each c In r
If c.Value2 = 1 Then c.Interior.Color = white
If c.Value2 = 0 Then c.Interior.Color = grey
Next
End Sub
As Ike mentions for Empty values you can use this
Sub SetColor()
Dim r As Range
Set r = ThisWorkbook.ActiveSheet.Range("B2:B7")
Dim white As Long
white = RGB(255, 255, 255)
Dim grey As Long
grey = RGB(200, 200, 200)
Dim c As Range
For Each c In r
If IsEmpty(c.Value2) Then
c.Interior.Color = white
'OR
'c.Interior.Pattern = xlNone
Else
c.Interior.Color = grey
End If
Next
End Sub

Find cell next to cell where value is placed

I insert the value of TextBox1 (on a UserForm) into the first empty cell at the bottom of Column A on Sheet("Info").
I am trying to modify this code so that the value in TextBox2 goes into cell in Column B next to the cell where TextBox1 was added.
I cannot use the same formula, because all the cells in Column A will have values, while corresponding cells in Column B may be blank.
Public Function FindNextEmpty(ByVal rCell As Range) As Range
On Error GoTo ErrorHandle
With rCell
If Len(.Formula) = 0 Then
Set FindNextEmpty = rCell
ElseIf Len(.Offset(1, 0).Formula) = 0 Then
Set FindNextEmpty = .Offset(1, 0)
Else
Set FindNextEmpty = .End(xlDown).Offset(1, 0)
End If
End With
Exit Function
ErrorHandle:
MsgBox Err.Description & ", Function FindNextEmpty."
End Function
Private Sub CommandButton2_Click()
Dim rCell As Range
Set rCell = FindNextEmpty(ThisWorkbook.Sheets("Info").Range("A1"))
rCell.Value = TextBox1.Value
Set rCell = Nothing
End Sub
Adding
rCell.Offset(0, 1) = TextBox2.Value
after
rCell.Value = TextBox1.Value
got me where I needed to be.

Use Excel-VBA to colour a range y if value is certain number is placed AND colour range x if value is certain number is placed

I need to program a conditional format in Excel VBA (2016) without using the existing conditional formatting tool. As I am a newbie and tried for a while the following, I'm asking you to help me.
I want to write this e.g. in a private sub: for range E18:G18 and K1:K10:
If value is >=1 then colour = green
If value is <1 or "" then colour red
for range B1:B10
If value is >=3 then colour = green
If value is <3 & >0 then colour yellow
if value is 0 or "" the colour red
My code is the following - when i save it, nothing happens in my second defined range (K1:K10), also after reopening the excel-workbook.
Also nothing happens with my second conditional formatting range (B1:B10):
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngObserve As Range, rngCell As Range
Set rngObserve = Intersect(Target, Range("E18:G18, K1:K10"))
If rngObserve Is Nothing Then
Exit Sub
End If
For Each rngCell In rngObserve.Cells
If Not Intersect(rngCell, rngObserve) Is Nothing Then
If rngCell.Value = vbNullString Then
rngCell.Interior.Color = xlNone
ElseIf rngCell.Value < 1 Then
rngCell.Interior.ColorIndex = 3 'red
ElseIf rngCell.Value >= 1 Then
rngCell.Interior.ColorIndex = 4 'green
Else
rngCell.Interior.ColorIndex = 3 'red
End If
End If
Next
Dim rngObserve As Range, rngCell As Range
Set rngObserve = Intersect(Target, Range("B1:B10"))
If rngObserve Is Nothing Then
Exit Sub
End If
For Each rngCell In rngObserve.Cells
If Not Intersect(rngCell, rngObserve) Is Nothing Then
If rngCell.Value = vbNullString Then
rngCell.Interior.Color = xlNone
ElseIf rngCell.Value < 3 And rgncell.Value > 0 Then
rngCell.Interior.ColorIndex = 6 'yellow
ElseIf rngCell.Value >= 3 Then
rngCell.Interior.ColorIndex = 4 'green
Else
rngCell.Interior.ColorIndex = 3 'red
End If
End If
Next
End Sub
As mentioned in the comments, you can only have one Worksheet_Change subroutine. This code should get you what you need:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngObserve As Range, rngCell As Range
'PGCodeRider comment: I'd set these to named ranges instead of hard-coded addresses
Set rngObserve = Intersect(Target, Range("E18:G18, K1:K10"))
If Not rngObserve Is Nothing Then
For Each rngCell In rngObserve.Cells
If rngCell.Value = vbNullString Then
rngCell.Interior.Color = xlNone
ElseIf rngCell.Value < 1 Then
rngCell.Interior.ColorIndex = 3 'red
ElseIf rngCell.Value >= 1 Then
rngCell.Interior.ColorIndex = 4 'green
Else
rngCell.Interior.ColorIndex = 3 'red
End If
Next rngCell
End If
Set rngObserve = Intersect(Target, Range("B1:B10"))
If Not rngObserve Is Nothing Then
For Each rngCell In rngObserve.Cells
If rngCell.Value = vbNullString Then
rngCell.Interior.Color = xlNone
ElseIf rngCell.Value < 3 And rngCell.Value > 0 Then
rngCell.Interior.ColorIndex = 6 'yellow
ElseIf rngCell.Value >= 3 Then
rngCell.Interior.ColorIndex = 4 'green
Else
rngCell.Interior.ColorIndex = 3 'red
End If
Next rngCell
End If
End Sub

VBA How to trigger Macro when columns are updated by the user and not VBA?

I am having a problem of an infinite loop which is caused by the code below.
It is caused by changes in column E affecting changes in G and vice-versa constantly triggering Worksheet_Change(ByVal Target As Range)
In the below code I could stop this with a line that tests if the last change was made by the user or by VBA. Is there a way to test this condition?
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("E:E")) Is Nothing Then Macro
If Not Intersect(Target, Range("G:G")) Is Nothing Then Macro2
End Sub
Private Sub Macro()
Dim rng As Range
Dim i As Long
Set rng = Range("E1:E10")
For Each cell In rng
If cell.Value <> "" Then
If IsNumeric(cell.Value) Then
cell.Offset(0, 2).Value = cell.Value + cell.Offset(0, 1)
End If
Else
cell.Offset(0, 2).Value = 1
End If
Next
End Sub
Private Sub Macro2()
Dim rng As Range
Dim i As Long
Set rng = Range("G1:G10")
For Each cell In rng
If cell.Value <> "" Then
If IsNumeric(cell.Value) Then
cell.Offset(0, -2).Value = cell.Value - cell.Offset(0, -1)
End If
Else
cell.Offset(0, -2).Value = 1
End If
Next
End Sub
temporarily disable events triggering:
Private Sub Macro()
Dim rng As Range
Dim i As Long
Set rng = Range("E1:E10")
On Error GoTo HandleExit ' assure proper handling of any error
Application.EnableEvents = False 'disable events triggering
For Each cell In rng
If cell.Value <> "" Then
If IsNumeric(cell.Value) Then
cell.Offset(0, 2).Value = cell.Value + cell.Offset(0, 1)
End If
Else
cell.Offset(0, 2).Value = 1
End If
Next
HandleExit:
Application.EnableEvents = True 'enable back events triggering
End Sub
the same with Macro2
EDIT to add a possible refactoring of the code
BTW, your Sub Macro() could be rewritten with no loops and without relying on IsNumeric() function (which is not 100% reliable (e.g. IsNumeric("12.5.3") would return True)
Private Sub Macro()
On Error GoTo HandleExit ' assure proper handling of any error
Application.EnableEvents = False 'disable events triggering
With Range("E1:E10") 'reference your range
If WorksheetFunction.Count(.Cells) > 0 Then ' if any "truly" numeric values in referenced range
With .SpecialCells(xlCellTypeConstants, xlNumbers).Offset(, 2) ' reference referenced range cells with constant numeric content only
.FormulaR1C1 = "=sum(RC[-1]:RC[-2])" ' write needed formula
.Value = .Value ' get rid of the formula
End With
End If
If WorksheetFunction.CountBlank(.Cells) Then .SpecialCells(xlCellTypeBlanks).Offset(, 2).Value = 1 ' if any blank cell in referenced range then fill it with 1"
End With
HandleExit:
Application.EnableEvents = True 'enable back events triggering
End Sub

Search through selected cells and hide them if they contain a letter

I want to loop through cells and look for letters. If they contain the letter hide the cell with NumberFormat. This works but how do I make this loop toggeable so i can hide/unhide.
Private Sub CommandButton1_Click()
Dim rng As Range, cell As Range
Set rng = Range("D5:F35,D43:F73,J5:L35,J43:L73,P5:R35,P43:R73,V5:X35,V43:X73,AB5:AD35,AB43:AD73,AH5:AJ35,AH43:AJ73")
For Each cell In rng
If InStr(1, cell.Value, "A") > 0 Then cell.NumberFormat = ";;;"
If InStr(1, cell.Value, "B") > 0 Then cell.NumberFormat = ";;;"
If InStr(1, cell.Value, "C") > 0 Then cell.NumberFormat = ";;;"
If InStr(1, cell.Value, "D") > 0 Then cell.NumberFormat = ";;;"
If InStr(1, cell.Value, "F") > 0 Then cell.NumberFormat = ";;;"
Next cell
End Sub
I'm not sure what you mean by "toggeable"
If you want to unhide everything, no matter what it contains, then just set the .numberformat property of the entire range to General.
If you mean that when you remove one of the target letters from the cell, that it should become unhidden, then try this macro below:
EDIT Edited to add what I think you mean by toggle.
========================================
Option Explicit
Option Compare Binary
Private Sub CommandButton1_Click()
Dim rng As Range, cell As Range
Set rng = Range("D5:F35,D43:F73,J5:L35,J43:L73,P5:R35,P43:R73,V5:X35,V43:X73,AB5:AD35,AB43:AD73,AH5:AJ35,AH43:AJ73")
Application.FindFormat.NumberFormat = ";;;"
Set cell = rng.Find(what:="*", searchformat:=True)
If Not cell Is Nothing Then
rng.NumberFormat = "General"
Exit Sub
End If
For Each cell In rng
If cell.Value Like "*[ABCDEF]*" Then
cell.NumberFormat = ";;;"
Else
cell.NumberFormat = "General"
End If
Next cell
End Sub
====================================
Try...
Private Sub CommandButton1_Click()
Dim rng As Range
Dim cell As Range
Set rng = Range("D5:F35,D43:F73,J5:L35,J43:L73,P5:R35,P43:R73,V5:X35,V43:X73,AB5:AD35,AB43:AD73,AH5:AJ35,AH43:AJ73")
For Each cell In rng
If cell.Value Like "*A*" Or cell.Value Like "*B*" Or cell.Value Like "*C*" Or cell.Value Like "*D*" Or cell.Value Like "*F*" Then
cell.NumberFormat = ";;;"
End If
Next cell
End Sub
Sub Macro1()
If cell.NumberFormat = ";;;" Then
cell.NumberFormat = "General"
End If
End Sub
The last part of the number format is for text - just remove that part from your custom number format to hide/show text.
Sub HideText()
Dim rng As Range
Set rng = ThisWorkbook.Worksheets("Sheet1") _
.Range("D5:F35,D43:F73,J5:L35,J43:L73,P5:R35,P43:R73,V5:X35,V43:X73,AB5:AD35,AB43:AD73,AH5:AJ35,AH43:AJ73")
If rng.NumberFormat <> "#,##0;-#,##0;#,##0;" Then
rng.NumberFormat = "#,##0;-#,##0;#,##0;"
Else
rng.NumberFormat = "#,##0;-#,##0;#,##0;#"
End If
End Sub

Resources