I have 3 statuses in a dropdown list in Col C. namely "N/A", "Pending" and "Completed" and a date column in Col B. If the user selects N/A from the dropdown in Col C. it locks the date field to the left and provides some formatting to the field. However, if the user selects another status besides "N/A" it clears the formatting and N/A text from date field. I have the code below which does everything I need it to, except that if a date is entered into the field and then I select "completed" or "pending" it clears the field - which it shouldn't. Please help.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Target.Count = 1 Then
If Not Intersect(Target, Range("C3:C13,C18:C28")) Is Nothing Then
Application.EnableEvents = False
If Target.Value = "N/A" Then
With Target(1, 0)
.Value = "(N/A)"
.Enabled = False
With .Interior
.Pattern = xlLightDown
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End With
Else
With Target(1, 0)
.Value = ""
.Enabled = True
With .Interior
.Pattern = xlPatternNone
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End With
End If
Application.EnableEvents = True
End If
End If
End Sub
Given your description of what you want, the following code should get you there. I think it may have been how you aimed at the adjacent cell.
I'm not sure how you lock the date field as I can't see where you Protect the sheet in your code - I'll leave that part to you. Let me know how it goes.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo GetOut
Application.EnableEvents = False
If Not Intersect(Range("C3:C13,C18:C28"), Target) Is Nothing Then
If Target.Text = "N/A" Then
With Target.Offset(0, -1)
.Value = "(N/A)"
.Locked = True
With .Interior
.Pattern = xlLightDown
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End With
Else
With Target.Offset(0, -1)
.Value = ""
.Locked = False
With .Interior
.Pattern = xlPatternNone
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End With
End If
End If
Continue:
Application.EnableEvents = True
Exit Sub
GetOut:
MsgBox Err.Description
Resume Continue
End Sub
Related
I have a macro:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim v
If Target.Cells.Count <> 1 Then Exit Sub
If Target.Column <> 1 Then Exit Sub
v = Target.Value
If VarType(v) <> vbDate Then
Application.EnableEvents = False
If v Like "???##" Or v Like "???-##" Then Target.Value = Left(v, Len(v) - 2) & "20" & Right(v, 2)
If VarType(Target.Value) <> vbDate Then Target.Value = Empty
Target.NumberFormat = "m/d/yyyy"
Application.EnableEvents = True
End If
End Sub
When copying (ex: may20, may-20) from another column to column A in Excel itself with this macro, it allows to paste only once - the next cell is no longer pasted, apparently, the clipboard is cleared after the first paste. I have to copy again from another column. How it can be corrected?
See below - if you need to paste the same value again.
The core problem is that the change event always clears the clipboard - there's no (easy) way I'm aware of to prevent that.
Private Sub Worksheet_Change(ByVal Target As Range)
Const MNTH_NM As String = "[A-Z][A-Z][A-Z]" 'a bit better than "???"
Dim v
If Target.Cells.Count <> 1 Then Exit Sub
If Target.Column <> 1 Then Exit Sub
v = Target.Value
If Len(v) > 0 Then
Application.EnableEvents = False
If UCase(v) Like MNTH_NM & "##" Or UCase(v) Like MNTH_NM & "-##" Then
v = Left(v, 3) & "-20" & Right(v, 2)
Target.NumberFormat = "m/d/yyyy"
Target.Value = v
Target.Copy
Else
Target.ClearContents 'if doesn't match the pattern, clear it
End If
Application.EnableEvents = True
End If 'non-zero length
End Sub
I have written this code as a start. I think I'm on the correct path but the code obviously requires more for it to work. Essentially I want to start in cell W8:
If the font is black in W8, it should move to W9 and through the range (W8, W9, W10, W11, W12, Y8, Y9, Y10, Y11, Y12 and then back to W8 as a loop) checking if the font is black.
If the loop stops on a cell where the font is red, it should be changed to black and the next cell in the list should be changed to red. It should then exit the sub.
SubFontW8()
If Range("W8").Font.Color = vbRed Then
Range("W8").Font.Color = xlAutomatic
And
Range("W9").Font.Color = vbRed
Exit Sub
Else
Call SubFontW9()
End If
End Sub
SubFontW9()
If Range("W9").Font.Color = vbRed Then
Range("W9").Font.Color = xlAutomatic
And
Range("W10").Font.Color = vbRed
Exit Sub
Else
Call SubFontW10()
End If
End Sub
SubFontW10()
If Range("W10").Font.Color = vbRed Then
Range("W10").Font.Color = xlAutomatic
And
Range("W11").Font.Color = vbRed
Exit Sub
Else
Call SubFontW11()
End If
End Sub
SubFontW11()
If Range("W11").Font.Color = vbRed Then
Range("W11").Font.Color = xlAutomatic
And
Range("W12").Font.Color = vbRed
Exit Sub
Else
Call SubFontW12()
End If
End Sub
SubFontW12()
If Range("W12").Font.Color = vbRed Then
Range("W12").Font.Color = xlAutomatic
And
Range("Y8").Font.Color = vbRed
Exit Sub
Else
Call SubFontY8()
End If
End Sub
SubFontY8()
If Range("Y8").Font.Color = vbRed Then
Range("Y8").Font.Color = xlAutomatic
And
Range("Y9").Font.Color = vbRed
Exit Sub
Else
Call SubFontY9()
End If
End Sub
SubFontY9()
If Range("Y9").Font.Color = vbRed Then
Range("Y9").Font.Color = xlAutomatic
And
Range("Y10").Font.Color = vbRed
Exit Sub
Else
Call SubFontY10()
End If
End Sub
SubFontY10()
If Range("Y10").Font.Color = vbRed Then
Range("Y10").Font.Color = xlAutomatic
And
Range("Y11").Font.Color = vbRed
Exit Sub
Else
Call SubFontY11()
End If
End Sub
SubFontY11()
If Range("Y11").Font.Color = vbRed Then
Range("Y11").Font.Color = xlAutomatic
And
Range("Y12").Font.Color = vbRed
Exit Sub
Else
Call SubFontY12()
End If
End Sub
SubFontY12()
If Range("Y12").Font.Color = vbRed Then
Range("Y12").Font.Color = xlAutomatic
And
Range("W8").Font.Color = vbRed
Exit Sub
Else
Call SubFontW8()
End If
End Sub
Any help you have would be much appreciated. Thank you.
There are several ways to complete this task. First, you will need a For Next Loop. Within this context, you can either use a For Next, or a For Each. I suggest reading up more about loops to better your understanding.
For simplicity in your example, I am going to use a For Each loop.
See below code (to be inserted in any normal module in the VBE):
Option Explicit
Sub Change_Font_Colour()
'range where you want to change the font colours
Dim rOperationRange As Range
'variable used to loop through the operation range
Dim cell As Range
'set range object
'you should ALWAYS have a worksheet qualifier
'change the sheet name to the required sheet name and adjust your range accordingly
Set rOperationRange = ThisWorkbook.Sheets("mySheetName").Range("W8:Y12")
'for loop
For Each cell In rOperationRange
If cell.Font.Color = vbRed Then
'set to black
cell.Font.Color = vbBlack
'set cell BELOW as red using .Offset
cell.Offset(1, 0).Font.Color = vbRed
'now exit
Exit Sub
End If
Next cell
End Sub
How can my code be made shorter?
If a user fills the cell with color yellow then if its value is 0 then it will turn to red and it will popup a message box, then if its value is > 0 it will back again to yellow, then if the user enters value of > 0 in the "no fill up cell" it will turn grey and back to no fill up if I input 0 this code is for column L only I need to make this for column M, N and O also.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ws As Worksheet
Set ws = ActiveSheet
On Error GoTo ExitSub
'WEEK 0
'For Task Not done
With ws.Cells(15, 12)
If Not (Application.Intersect(Range("L15"), Target) Is Nothing) Then
If .Interior.ColorIndex = 6 And .Value < 1 Then
MsgBox "Project Delay!"
Range("L15").Interior.ColorIndex = 3
Else
If Range("L15").Interior.ColorIndex = 3 And .Value > 0 Then
Range("L15").Interior.ColorIndex = 6
End If
End If
'For overlapped Task
If .Interior.ColorIndex = -4142 And .Value > 0 Then
MsgBox "Overlap!"
Range("L15").Interior.ColorIndex = 16
Else
If Range("L15").Interior.ColorIndex = 16 And .Value < 1 Then
Range("L15").Interior.ColorIndex = -4142
End If
End If
End If
End With
On Error GoTo ExitSub
'For Task Not done
With ws.Cells(17, 12)
If Not (Application.Intersect(Range("L17"), Target) Is Nothing) Then
If .Interior.ColorIndex = 6 And .Value < 1 Then
MsgBox "Project Delay!"
Range("L17").Interior.ColorIndex = 3
Else
If Range("L17").Interior.ColorIndex = 3 And .Value > 0 Then
Range("L17").Interior.ColorIndex = 6
End If
End If
'For overlapped Task
If .Interior.ColorIndex = -4142 And .Value > 0 Then
MsgBox "Overlap!"
Range("L17").Interior.ColorIndex = 16
Else
If Range("L17").Interior.ColorIndex = 16 And .Value < 1 Then
Range("L17").Interior.ColorIndex = -4142
End If
End If
End If
End With
End Sub
Please try this code. As far as I understood your intentions it should do what you want.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Tmp As Long
With Target
If .Cells.CountLarge > 1 Then Exit Sub
If (.Column >= Columns("L").Column) And (.Column <= .Columns("O").Column) Then
Tmp = Val(.Value)
Select Case .Row
Case 15
.Interior.ColorIndex = IIf(Tmp, 6, 3)
If Tmp = 0 Then
MsgBox "Project Delay!", _
vbCritical, "Attention required!"
End If
Case 17
.Interior.ColorIndex = IIf(Tmp, 16, -4142)
If Tmp Then
MsgBox "Enter a value of zero.", _
vbExclamation, "Overlap!"
End If
End Select
End If
End With
End Sub
I have kept the syntax simple so that you ought to be able to tweak it where it needs tweaking. Good luck!
I need to a create similar macro for duplicates (see below). The user will be able to choose a column symbol and then all the duplicates from the chosen column will be highlighted with color. I do not how to do that.
Below is the same idea but with empty cells.
Could you help? THX!
Sub EmptyCells()
Dim kol As String
Dim ost As Long
ost = Cells(Rows.Count, "A").End(xlUp).Row
kol = InputBox("Enter column symbol: B, C...etc.", "Column symbol", "B")
If kol = vbNullString Then Exit Sub
If IsNumeric(kol) Then
MsgBox "You entered number, please enter column symbol", _
vbInformation, "ERROR"
Exit Sub
End If
If ost < 5 Then Exit Sub
Range("A5:E" & ost).Interior.Color = xlNone
Range(Cells(5, kol), Cells(ost, kol)).SpecialCells(xlCellTypeBlanks).Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End Sub
Please make the following changes as per comments in your program. After changes it works for me. Assuming I have cleared existing formats on the worksheet and it is going to be first format condition.
Sub DuplicateCells() ' changed sub name
Dim kol As String
Dim ost As Long
ost = Cells(Rows.Count, "A").End(xlUp).Row
kol = InputBox("Enter column symbol: B, C...etc.", "Column symbol", "B")
If kol = vbNullString Then Exit Sub
If IsNumeric(kol) Then
MsgBox "You entered number, please enter column symbol", _
vbInformation, "ERROR"
Exit Sub
End If
If ost < 5 Then Exit Sub
Range("A5:E" & ost).Interior.Color = xlNone
Range(Cells(5, kol), Cells(ost, kol)).Select ' Remove SpecialCells(xlCellTypeBlanks)
Selection.FormatConditions.AddUniqueValues 'Add this line
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority 'Add this line
Selection.FormatConditions(1).DupeUnique = xlDuplicate 'Add this line
With Selection.FormatConditions(1).Interior ' add FormatConditions(1)
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
End Sub
Results on my sample data are shown.
I have to create a cell like and I am looking a way to do it with excel formulas or VBA code.
With two differents formts red to green or just black, but not in all the case depends If.
For example:
Case 1: If cell F1 and G1 has values the format is Red to green
Case 2: If cell F1 has a value but G is empty the final format in image 1 have to be Just black
This VBA code should work. It goes into the worksheet_change event of your sheet.
I just set it for column I to change colors, but you can extend to J and K if you need to.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
If Target.Column = 6 Or Target.Column = 7 Then
Select Case Target.Column
Case Is = 6
If Target <> vbNullString And Target.Offset(, 1) <> vbNullString Then
With Target.Offset(, 2)
.Characters(Start:=1, Length:=5).Font.ColorIndex = 3
.Characters(Start:=6, Length:=3).Font.ColorIndex = 4
End With
Else: Target.Offset(, 2).Font.ColorIndex = 0
End If
Case Is = 7
If Target <> vbNullString And Target.Offset(, -1) <> vbNullString Then
With Target.Offset(, 1)
.Characters(Start:=1, Length:=5).Font.ColorIndex = 3
.Characters(Start:=6, Length:=3).Font.ColorIndex = 4
End With
Else: Target.Offset(, 1).Font.ColorIndex = 0
End If
End Select
End If
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub