Check if two cells match specific values to create MsgBox - excel

I am trying to check if two cells have two different values. I want to create a MsgBox for when if cell A1 is A and B1 is B to create MsgBox with text. But that the MsgBox will only pop up once.
The code works when I have one cell:
Option Explicit
Dim oldVal
Private Sub Worksheet_Change(ByVal Target As Range)
If (Target.Address = "$A$1") Then
If Target.Value = "A" And Target.Value <> oldVal Then
oldVal = Target.Value
MsgBox "Text."
End If
End If
End Sub
But I get error message when I try to for two cells:
Compile error: Procedure declaration does not match description of
event or procedure having the same name.
Option Explicit
Dim oldVal
Dim oldVal2
Private Sub Worksheet_Change(ByVal Target1 As Range, ByVal Target2 As Range)
If (Target1.Address = "$A$1") And (Target2.Address = "$B$1") Then
If Target1.Value = "A" And Target2.Value = "B" And Target1.Value <> oldVal And Target2.Value <> oldVal2 Then
oldVal = Target1.Value
oldVal2 = Target2.Value
MsgBox "Text."
End If
End If
End Sub
What can I do?

First of all you cannot change the parameters of the Worksheet.Change event and add more than one Target like this:
Private Sub Worksheet_Change(ByVal Target1 As Range, ByVal Target2 As Range)
'this does not work!
Instead you need to check if the Target intersects (Application.Intersect method) with your desired range and then check the values of A1 and B1.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("A1,B1")) Is Nothing Then 'check if A1 or B1 changed
If Me.Range("A1").Value = "A" And Me.Range("B1").Value = "B" Then
MsgBox "A1=A and B1=B"
End If
End If
End Sub

Related

Execute a function only if a specific cell contains a specific value

The below code works just great.
Now I only want it to function if cell B2 says "2020".
If cell B2 says "2021", for example, I want the value instead to go to sheet "2021".
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim xRtn As Variant
If Selection.Count = 1 Then
If Not Intersect(Target, Range("D9:AS20")) Is Nothing Then
xRtn = Application.InputBox("Insert your value please")
Sheets("2020").Range(Target.Address).Value = xRtn
End If
End If
End Sub
How can I achieve that?
solved myself
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim xRta As Variant
If Selection.Count = 1 Then
If ActiveSheet.Range("B2") = "2020" Then
If Not Intersect(Target, Range("D9:AS20")) Is Nothing Then
xRta = Application.InputBox("Insert your value please")
Sheets("2020").Range(Target.Address).Value = xRta
End If
End If
End If
Dim xRtb As Variant
If Selection.Count = 1 Then
If ActiveSheet.Range("B2") = "2021" Then
If Not Intersect(Target, Range("D9:AS20")) Is Nothing Then
xRtb = Application.InputBox("Insert your value please")
Sheets("2021").Range(Target.Address).Value = xRtb
End If
End If
End If
End Sub

Data validation to a dynamic range

I have a column named "time" in my excel sheet. I want to write a code such that whenever user performs an entry in time column, if it is a whole number, it should accept, but if it is not a pop up should appear saying "only numbers allowed". Also, the validation should be dynamic i.e. should automatically validate next row if users enters a new entry
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Target.Column = Range("Meeting Time").Column Then
If Not (IsNumeric(Target.Value)) Then
MsgBox "only numbers allowed"
Target.Value = ""
Target.Select
End If
End If
End Sub
You could try:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
'1. Check if the column that affected is B (change to the column you want)
'2. Check if changed field is one (used to avoid errors if user change more than one cells at the same time)
If Not Intersect(Target, Columns("B:B")) Is Nothing And Target.Count = 1 Then
'Check if target is numeric
If Not IsNumeric(Target.Value) Then
Call Clear(Target)
End If
'Check if target.offset(1,0) is numeric
If Not IsNumeric(Target.Offset(1, 0).Value) Then
Call Clear(Target.Offset(1, 0))
End If
End If
End Sub
Sub Clear(ByVal rng As Range)
'Disable events in order to prevent code to re trigger when clear cell
Application.EnableEvents = False
rng.Value = ""
'Enable events
Application.EnableEvents = True
End Sub
EDITED VERSION:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
'1. Check if the column that affected is B (change to the column you want)
'2. Check if changed field is one (used to avoid errors if user change more than one cells at the same time)
If Not Intersect(Target, Columns("B:B")) Is Nothing And Target.Count = 1 Then
'Check if target is numeric
If Not IsNumeric(Target.Value) Then
Call Clear(Target)
ElseIf Target.Value > 160 Or (Target.Value = Int(Target.Value) = False) Then
Call Clear(Target)
End If
'Check if target.offset(1,0) is numeric
If Not IsNumeric(Target.Offset(1, 0).Value) Then
Call Clear(Target.Offset(1, 0))
ElseIf Target.Offset(1, 0).Value > 160 Or (Target.Offset(1, 0).Value = Int(Target.Offset(1, 0).Value) = False) Then
Call Clear(Target)
End If
End If
End Sub
Sub Clear(ByVal rng As Range)
'Disable events in order to prevent code to re trigger when clear cell
Application.EnableEvents = False
rng.Value = ""
'Enable events
Application.EnableEvents = True
End Sub
first you can create a range name for column you want your "time" and you can use the sample codes below.
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Target.Column = Range("time").Column Then
If Not (IsNumeric(Target.Value)) Then
MsgBox "only numbers allowed"
Target.Value = ""
Target.Select
End If
End If
End Sub

Execute code if the value entered in the cell is not the same as the previous value

I have data validation as list for some cells (possible values are "Enrolled", "Waitlisted", "Cancelled"). I need to execute some code if the value of these cells changes, only if the new value is not the same as the existing one. Question is, how can I get Excel to compare the previous value of the cell with the current one.
I tried this solution (How do I get the old value of a changed cell in Excel VBA?) but it didn't work. What am I missing? Here is some sample code. Currently, it changes the cell colors even if I enter the same value.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim previous_value As String
previous_value = oval
Select Case Target.Value
Case Is = "enrolled"
If previous_value = Target.Value Then
MsgBox "you entered the same value"
Application.EnableEvents = False
Application.Undo
Application.EnableEvents = True
Else
Target.Interior.Color = vbBlue
End If
Case Is = "waitlisted"
' (....etc.)
End Select
End Sub
Public Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim oval As String
If Selection.Cells.Count = 1 Then
oval = Target.Value
End If
End Sub
If you use something like this below code, you can save the most recent clicked instance in a named range and then check it against whatever the user entered. Obviously, this goes in the respective sheet code.
Private anOldValue As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count = 1 Then
If Target.Value = anOldValue Then
MsgBox "Same value!"
End If
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count = 1 Then
anOldValue = Target.Value
End If
End Sub
Here is the final code. Thanks #PGCodeRider for the help!
Private anOldValue As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count = 1 Then
Select Case Target.Value
Case Is = "enrolled"
If Target.Value = anOldValue Then
MsgBox "Student already enrolled!"
Else 'code that needs to happen when "enrolled" is selected
Target.Interior.ColorIndex = 10
End If
Case Is = "waitlisted"
If Target.Value = anOldValue Then
MsgBox "Student already waitlisted!"
Else 'code that needs to happen when "waitlisted" is selected
Target.Interior.ColorIndex = 20
End If
Case Is = "cancelled"
If Target.Value = anOldValue Then
MsgBox "Student already cancelled!"
Else 'code that needs to happen when "cancelled" is selected
Target.Interior.ColorIndex = 30
End If
End Select
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count = 1 Then
anOldValue = Target.Value
End If
End Sub

Protect cell depending on other cell's value

I have an Excel spreadsheet where I want to protect cells in column I if the respective cell of column H <> "yes".
I found a code but it will protect all the cells of column I.
Option explicit
Sub unprotected
Me.unprotect password:= "abc"
End sub
Sub protect
Me.protect userinterfaceonly:= true ,password:= "abc"
End sub
Private Sub Worksheet_change(ByVal Target As Range)
Dim Crow as Long
Call Unprotected
xrow = Target.Row
If not (intersect(Target, range("H3:H1000")) is nothing then
Cells(xrow, "I").locked = (Ucase(trim(cells(xrow, "H").value))<>"yes")
End if
Call protect
End sub
Try this:
Option Explicit
Const PW As String = "abc" '<< use a constant for fixed/shared values
Private Sub Worksheet_change(ByVal Target As Range)
Dim rng As Range, c As Range
'find changed cells in range of interest
Set rng = Application.Intersect(Target, Me.Range("H3:H1000"))
If Not rng Is Nothing Then
UnprotectMe
'process each cell
For Each c In rng.Cells
Me.Cells.Cells(c.Row, "I").Locked = _
(UCase(Trim(Me.Cells(c.Row, "H").Value)) <> "YES")
Next c
ProtectMe
End If
End Sub
Sub UnprotectMe()
Me.Unprotect Password:=PW
End Sub
Sub ProtectMe()
Me.protect userinterfaceonly:=True, Password:=PW
End Sub

How can I spread a sub to a multiple range of cells?

The purpose of this code is to update the date in a cell as a certain cell's contents are changed.
Since this was originally coded inside a sub, I now need to expand this code to a range of multiple cells. Ie. At this moment, the code only takes cell D4 and updates cell L4, I want to be able to drag this function down so it can reach a multiple range of cells; take D5 and update L5 etc.
Here's my code as the sub:
Dim oldValue
Public Sub Worksheet_SelectionChange(ByVal Target As Range)
oldValue = Target.Worksheet.Range("D4").Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("D4")) Is Nothing Then
If oldValue <> Target.Worksheet.Range("D4").Value Then
Target.Worksheet.Range("L4").Value = Date
End If
End If
End Sub
The problem here, is that I don't know how to properly expand my code to match a further selection of cells. Here's my attempt:
Dim oldValue
Public Sub Worksheet_SelectionChange(ByVal Target As Range)
oldValue = Target.Worksheet.Range("D4", "D21").Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("D4", "D21")) Is Nothing Then
If oldValue <> Target.Worksheet.Range("D4", "D21").Value Then
Target.Worksheet.Range("L4", "L21").Value = Date
End If
End If
End Sub
EDIT: The sub I have written only applies to one cell, I am trying to work out a way to have it spread out to a certain selection of cells. Ie. D4:D12 which updates the date in L4:L12 accordingly.
If anyone could help me, that would be greatly appreciated.
Try the following code:
Dim oldValue()
Public Sub Worksheet_SelectionChange(ByVal Target As Range)
oldValue = Me.Range("D4:D12").Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("D4:D12")) Is Nothing Then
Application.EnableEvents = False
Dim c As Range
For Each c In Intersect(Target, Me.Range("D4:D12"))
'Check value against what is stored in "oldValue" (row 4 is in position 1, row 5 in position 2, etc)
If oldValue(c.Row - 3, 1) <> c.Value Then
'Update value in column L (8 columns to the right of column D)
c.Offset(0, 8).Value = Date 'or possibly "= Now()" if you need the time of day that the cell was updated
End If
Next
Application.EnableEvents = True
End If
End Sub
Set up a hidden sheet to hold the old values.
Sub SetupMirrorValues()
With Worksheets.Add
.Name = "MirrorValues"
.visibilty = xlSheetVeryHidden
.Range("D4:D10,D12,D14:D20") = Worksheets("Sheet1").Range("D4:D10,D12,D14:D20")
End With
End Sub
In the Worksheet_Change event handler, you would check the Target cells that intersect with the range you want to monitor. If there are differences then you update the timestamp and the cell on the hidden sheet that corresponds to the changed cell.
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim cell As Range, DRange As Range
Set DRange = Range("D4:D10,D12,D14:D20")
If Not Intersect(DRange, Target) Is Nothing Then
For Each cell In Intersect(DRange, Target)
If cell.Value <> Worksheets("MirrorValues").Range(cell.Address) Then
cell.EntireRow.Cells(1, "L").Value = Now
Worksheets("MirrorValues").Range(cell.Address) = cell.Value
End If
Next
End If
Application.EnableEvents = True
Application.ScreenUpdating = False
End Sub

Resources