I have written a simple Excel VBA macro to have different formatting in a single cell. I have a formula that returns one of 4 possible values:
l1
l2
l3
l4
I wish to format this as Wingdings for the first character with a colour based on the number - 1 = red, 2 = orange, 3 = yellow and 4 = green.
What I have done is to put in an event trigger on cell change:
Private Sub Worksheet_Change(ByVal Target As Range)
Call Wingdings(Target)
End Sub
The subroutine is as follows:
Sub Wingdings(rCll As Range)
If rCll.Value = "l1" Or rCll.Value = "l2" Or _
rCll.Value = "l3" Or rCll.Value = "l4" Then
Select Case Right(rCll.Value, 1)
Case 1 'Red
With rCll.Characters(Start:=1, Length:=1).Font
.Name = "Wingdings"
.Color = RGB(255, 0, 0)
End With
Case 2 'Orange
With rCll.Characters(Start:=1, Length:=1).Font
.Name = "Wingdings"
.Color = RGB(255, 153, 0)
End With
Case 3 'Yellow
With rCll.Characters(Start:=1, Length:=1).Font
.Name = "Wingdings"
.Color = RGB(255, 255, 0)
End With
Case 4 'Green
With rCll.Characters(Start:=1, Length:=1).Font
.Name = "Wingdings"
.Color = RGB(0, 255, 0)
End With
End Select
End If
End Sub
My issue here is that if I manually enter eg l4, the code runs perfectly. But as soon as I determine this value using a formula, it stops working as I desire. I end up with this:
Can anyone suggest a solution to allow me to format the result of the formula as I desire?
What you have works.
Maybe call something like this on the Change event instead, conditionally, if you are dragging formulas
Sub fixstuff()
For Each cell In Selection
cell.Select
Call Wingdings(Range(cell.Address))
Next cell
End Sub
Related
I am trying to update this short macro I'm using to highlight values in my spreadsheet. Is there a method that exists to check the state of a cell? I want to change back the colors of cells to white if texts gets updated. I don't want to just change every other color in my spread sheet to white that's not a valid case because I have other colors that I want to keep. I just would like to check:
if the color was changed and is not a valid case anymore color the cell back to white...
Private Sub CommandButton1_Click()
Dim itm As Range
Application.ScreenUpdating = False
For Each itm In ActiveSheet.UsedRange.Offset(1)
If Not IsError(itm) Then
With itm
Select Case .Value2
Case "GREEN", "green", "Green"
.Interior.Color = XlRgbColor.rgbLightGreen
Case "RED", "red", "Red"
.Interior.Color = XlRgbColor.rgbRed
Case "Serverely Delayed"
.Interior.Color = XlRgbColor.rgbRed
Case "Yellow", "yellow", "Yellow"
.Interior.Color = XlRgbColor.rgbYellow
Case "Delayed", "delayed"
.Interior.Color = XlRgbColor.rgbYellow
Case "Complete", "complete"
.Interior.Color = RGB(153, 204, 0)
End Select
End With
End If
Next
Application.ScreenUpdating = True
End Sub
I have an Excel VBA procedure which is supposed to compare the values of two cells. In my case they are scalars, ranging from 1 to 3. Basically, they are answers to questions. If they match, then I want to color a certain cell green, otherwise I want to make it red. Is there something wrong with my syntax?
Sub CheckBold()
'
' CheckBold Macro
'
'
Row = ActiveCell.Row
If ThisWorkbook.Sheets(1).Range("D" & CStr(ActiveCell.Row)).Font.Bold Then
ActiveCell.Value = 1
End If
If ThisWorkbook.Sheets(1).Range("E" & CStr(ActiveCell.Row)).Font.Bold Then
ActiveCell.Value = 2
End If
If ThisWorkbook.Sheets(1).Range("F" & CStr(ActiveCell.Row)).Font.Bold Then
ActiveCell.Value = 3
End If
ActiveCell.Value = ThisWorkbook.Sheets(3).Range("A" & CStr(ActiveCell.Row)).Value & ActiveCell.Value
If CInt(ActiveCell.Value) = CInt(ThisWorkbook.Sheets(3).Range("A" & CStr(ActiveCell.Row)).Value) Then
ActiveCell.Interior.Color = RGB(0, 180, 0)
Else
ActiveCell.Interior.Color = RGB(180, 0, 0)
End If
End Sub
What happens is that always the code goes on the Then branch of the if, even though the values are different. Why do I get this behavior?
I am currently trying to use the font color as a condition to check against in an if statement. It seems incredibly easy, but VBA doesn't seem to be able to do it.
I can't show my actual code as it has proprietary information in it, but I have even tried a simple version of my code with no avail. That code is shown below.
Sub Testing()
Cells(1,1).Font.Color = -16776961
If Cells(1,1).Font.Color = -16776961 Then
Cells(1,3) = "Worked!"
Else
Cells(1,3) = "Didn't Work!"
End If
End Sub
The first line of code actually changes the font color or cell A1 to red. However the conditional statement doesn't work for some reason.
Use the RGB function instead. (Not sure where the negative value comes from anyway?)
Sub Testing()
Cells(1, 1).Font.Color = RGB(255, 0, 0)
If Cells(1, 1).Font.Color = RGB(255, 0, 0) Then
Cells(1, 3) = "Worked!"
Else
Cells(1, 3) = "Didn't Work!"
End If
End Sub
You should use RGB like this:
Cells(1,1).Font.Color = RGB(255, 0, 0)
If Cells(1,1).Font.Color = RGB(255, 0, 0) Then
Cells(1,3) = "Worked!"
Else
Cells(1,3) = "Didn't Work!"
End If
I have attempted various iterations of the below and some have worked first time around, then not after, some not at all.
In short cell b2 on all sheets can be one of 6 text entries, (complete, in progress, scrapped, future works, parked, held) to show the currwnt state of that specific piece of work. To further help at a glance I want to update tab colours based on b1 as well.i.e if in progress B2 goes green, so does that tab.
Current code:
Private Sub tabcolour_Change(ByVal Target As Range)
Select Case Range("$b$2").Value
Case "In progress"
.Color = 43
Case "Held"
.Color = 6
Case "Scrapped"
.Color = 3
Case "Parked"
.Color = 28
Case "Complete"
.Color = 55
Case "Future Works"
.Color = 53
Case Else
.ColorIndex = xlColorIndexNone
End Select
End With
End Sub
I updated it slightly as still not working. The article I used below.
Excel VBA: automatically adjust tab colour
It won't be seen as a macro whilst I have "ByVal Target As Range" between () on the first line. But if I remove it it doesn't work.
It did work correctly once but then didn't change the colour of the cell after and threw up an error (this was a couple of hours ago now, so can't remember the message sorry).
It is probably something very basic, but alas so is my knowledge.
Could someone point me in the right direction please?.
**************EDIT/UPDATE**********************
Current code courtesy of Darren:
Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Range("B1"), Target) Is Nothing Then
With ActiveSheet.Tab
Select Case Target
Case "In Progress"
.Color = RGB(153, 204, 0)
Case "Held"
.Color = RGB(255, 255, 0)
Case "Parked"
.Color = RGB(0, 255, 255)
Case "Complete"
.Color = RGB(128, 0, 128)
Case "Future works"
.Color = RGB(153, 0, 167)
Case "scrapped"
.Color = RGB(194, 24, 7)
Case Else
.ColorIndex = xlColorIndexNone
End Select
End With
End If
End Sub
The tab colours do change, but not for "In Progress", "Future works", or "scrapped", the rest work fine?. I have changed the RGB values incase it is those colours, but it's still the same?. No colour values make these change, and the text going into the box is right as I have now added this as a data validation too (using a list on another tab). I complete the drop down now, and for 3 of the 6 it works fine???.
Two ways to do it - both use the Change event to monitor when a value is updated on a worksheet.
The Intersect command checks that the range B2 is being changed.
You can either add this code to each sheet:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Range("B2"), Target) Is Nothing Then
With Target.Parent.Tab
Select Case Target
Case "In Progress"
.Color = 43
Case "Held"
.Color = 6
Case "Parked"
.Color = 28
Case Else
.ColorIndex = xlColorIndexNone
End Select
End With
End If
End Sub
or you can add this code to the ThisWorkbook module:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Not Intersect(Sh.Range("B2"), Target) Is Nothing Then
With Sh.Tab
Select Case Target
Case "In Progress"
.Color = 43
Case "Held"
.Color = 6
Case "Parked"
.Color = 28
Case Else
.ColorIndex = xlColorIndexNone
End Select
End With
End If
End Sub
Try
Private Sub worksheet_Change(ByVal Target As Range)
Dim myTab As Object
Set myTab = ActiveSheet.Tab
With myTab
Select Case Range("$b$2").Value
Case "In progress"
.ColorIndex = 43
Case "Held"
.ColorIndex = 6
Case "Scrapped"
.ColorIndex = 3
Case "Parked"
.ColorIndex = 28
Case "Complete"
.ColorIndex = 55
Case "Future Works"
.ColorIndex = 53
Case Else
.ColorIndex = xlColorIndexNone
End Select
End With
End Sub
UPDATE
Thank you for the assistance. I have updated my code to look like:
Sub AddColor()
With Sheet1.Range("$T$3:$T$3600").FormatConditions
.Delete
With .Add(xlExpression, Formula1:="=AND(($Q3+7)<=TODAY(),$Q3>0,$T3="""")")
.Interior.Color = RGB(0, 176, 240)
.StopIfTrue = False
End With
With .Add(xlExpression, Formula2:="=AND(($Q3+14)<=TODAY(),$Q3>0,$T3="""")")
.Interior.Color = RGB(255, 0, 0)
.StopIfTrue = True
End With
End With
With Sheet1.Range("$U$3:$U$3600").FormatConditions
.Delete
With .Add(xlExpression, Formula1:="=AND(($S3-1)<=TODAY(),$S3>0,$U3="""")")
.Interior.Color = RGB(0, 176, 240)
.StopIfTrue = False
End With
With .Add(xlExpression, Formula2:="=AND(($T3+1)<=TODAY(),$U3="""",$T3>0)")
.Interior.Color = RGB(255, 0, 0)
.StopIfTrue = True
End With
End With
'Code continues
I am now getting an error that says "Argument Not Optional" and it seems to be referring to my "Formula2" line on the first set of statements. I am not sure what argument is missing, as it is working correctly for the first statement. I tried to skip over the second formula and it has the same error for the next set for arguments.
It is probably something simple, but any assistance is appreciated!
UPDATE
I am trying to add conditional formatting through VBA, but am running into some issues with my code. I would like to be able to do it through the conditional formatting function, but the data that is going to be imported requires that i split columns, which causes the reference cells to change, but conditional formatting does not seem to keep it how I want it (long story). Anyway, I have about 10 more of these to format the information in the corresponding columns and am just trying to figure out why I keep getting an error. Here is what I have:
Sub AddColor()
With Sheet1.Range("$T$3:$T$3600")
.FormatConditions.Add xlExpression, Formula1:="=AND(($Q3+7)
<=TODAY(),$Q3>0,$T3="")"
.FormatConditions(1).Interior.Color = RGB(0, 176, 240)
.FormatConditions(1).StopIfTrue = False
.FormatConditions.Add xlExpression, Formula2:="=AND(($Q3+14)
<=TODAY(),$Q3>0,$T3=0)"
.FormatConditions(2).Interior.Color = RGB(255, 0, 0)
.FormatConditions(2).StopIfTrue = True
End With
With Sheet1.Range("$U$3:$U$3600")
.FormatConditions.Add xlExpression, Formula1 = "=AND(($S3-1
<=TODAY(),$S3>0,$U3="")"
.FormatConditions(3).Interior.Color = RGB(0, 176, 240)
.FormatConditions(3).StopIfTrue = False
.FormatConditions.Add xlExpression, Formula2 = "=AND(($T3+1)
<=TODAY(),$U3="",$T3>0)"
.FormatConditions(4).Interior.Color = RGB(255, 0, 0)
.FormatConditions(4).StopIfTrue = True
End With
(the<=TODAY() portion is a continuation i my code, it just jumped to the next line due to formatting.) What am I doing wrong? Any assistance would be greatly appreciated!
Your statement
.FormatConditions.Add xlExpression, Formula1:="=AND(($Q3+7)<=TODAY(),$Q3>0,$T3="")"
is trying to tell Excel to use a formula of =AND(($Q3+7)<=TODAY(),$Q3>0,$T3="). That is syntactically incorrect, as there is no closing quote for the part that starts $T3=".
You need to escape all double-quotation marks (") within string literals in VBA code by using two double-quotation marks (i.e. "") for every one you actually want in the string.
I believe you want your code to be:
Sub AddColor()
With Sheet1.Range("$T$3:$T$3600")
.FormatConditions.Add xlExpression, Formula1:="=AND(($Q3+7)<=TODAY(),$Q3>0,$T3="""")"
.FormatConditions(1).Interior.Color = RGB(0, 176, 240)
.FormatConditions(1).StopIfTrue = False
.FormatConditions.Add xlExpression, Formula2:="=AND(($Q3+14)<=TODAY(),$Q3>0,$T3=0)"
.FormatConditions(2).Interior.Color = RGB(255, 0, 0)
.FormatConditions(2).StopIfTrue = True
End With
With Sheet1.Range("$U$3:$U$3600")
.FormatConditions.Add xlExpression, Formula1:="=AND(($S3-1)<=TODAY(),$S3>0,$U3="""")"
.FormatConditions(3).Interior.Color = RGB(0, 176, 240)
.FormatConditions(3).StopIfTrue = False
.FormatConditions.Add xlExpression, Formula2:="=AND(($T3+1)<=TODAY(),$U3="""",$T3>0)"
.FormatConditions(4).Interior.Color = RGB(255, 0, 0)
.FormatConditions(4).StopIfTrue = True
End With
In addition to the corrections made by YowE3K, I suggest you make a few other improvements. The way you are referring to the newly added CFs is hazardous. I suggest:
1- delete any old CF before adding new ones in the macro. Otherwise they will keep accumulating each time you run the macro and accordingly theit indexes will not be what you "think" they are.
2- Refer explicitly to any newly added CF instead of by index. For example, in the column U, you refer to them as .FormatConditions(3) and (4), which is incorrect.
With Sheet1.Range("$U$3:$U$3600").FormatConditions
.Delete ' <--- delete old CF if any
With .Add(xlExpression, Formula1:="=AND(($S3-1)<=TODAY(),$S3>0,$U3="""")")
.Interior.Color = RGB(0, 176, 240)
.StopIfTrue = True
'...
End With
With .Add(xlExpression, Formula1:="=AND(($T3+1)<=TODAY(),$U3="""",$T3>0)")
.Interior.Color = RGB(255, 0, 0)
.StopIfTrue = True
'...
End With
End with
Apply the same method for each CF you want to add, and don't forget to "double-up" your formula's double-quotes that you embed inside a VBA string.