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

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

Related

Restricting VBA code to certain range of cells within worksheet

I am currently running code that changes cell colour and value when clicked i.e. one click changes cell colour and sets value to 1, double click same cell to remove colour and number. This is to allow people to fill in a form in a visual way, and gives me the ability to count the "checked" cells. My problem is that I need it restricted to a certain range within that worksheet so that people can't overwrite other cells.
I have next to no coding experience, and the code below is a mix and match of a bunch of stuff found online.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
Worksheet_SelectionChange Target
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
With Target
If .Range("E4:K79") Is Nothing Or .Count > 1 Then Exit Sub
Select Case .Value
Case ""
.Interior.ColorIndex = 40
Case 1
.Interior.ColorIndex = xlNone
.Value = vbNullString
Exit Sub
Case Else
Exit Sub
End Select
.Value = .Value + 1
End With
End Sub
Solved.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
Worksheet_SelectionChange Target
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
With Target
If Intersect(.Cells, Range("E4:K120")) Is Nothing Or .Count > 1 Then Exit Sub
Select Case .Value
Case ""
.Interior.ColorIndex = 3
Case 1
.Interior.ColorIndex = xlNone
.Value = vbNullString
Exit Sub
Case Else
Exit Sub
End Select
.Value = .Value + 1
End With
End Sub

Check if two cells match specific values to create MsgBox

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

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

Calling one function from the other function in VBA (Excel)

I have two VBA functions, but i am unable to call the other from the first function.
Function 1:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim lastRow As Long
With ActiveSheet
lastRow = .Cells(.Rows.count, "A").End(xlUp).Row
Dim I, J As Integer
For I = 1 To lastRow
If Cells(I, "C").Value = "" Then
MsgBox "Please Enter Business Type Value", vbOKOnly
Exit Sub
End If
Next I
End With
End Sub
And the 2nd function:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
Application.EnableEvents = False
If Not Application.Intersect(Target, Me.Columns(3)) Is Nothing Then
ActiveSheet.Unprotect
Select Case Target.Value
Case Is = "CNS"
Target.Offset(0, 4).Locked = True
Case Is = "cns"
Target.Offset(0, 4).Locked = True
Case Is = "APL"
Target.Offset(0, 4).Locked = False
Case Is = "apl"
Target.Offset(0, 4).Locked = False
Case Else
MsgBox "Value not covered by the program", vbInformation + vbOKOnly
End Select
ActiveSheet.Protect
Else
End If
Application.EnableEvents = True
End Sub
please help somebody..
thanks in advance..
In the same module you just call nameoffunction
You can make function public
public sub function
But it's a poor (sometime good) solution. You should structure your code
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
call modul1.function1 ( Target ) ' As Range)
End sub
Private Sub Worksheet_Change(ByVal Target As Range)
call modul1.function1 ( Target ) ' as range
call modul1.function2 ( Target )
end sub
edit ok ugly way
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
....
call Worksheet_change ( Target)
End sub

worksheet_SelectionChange for a specific column

I have a worksheet that contains invoice numbers in column D. I'd like to copy the invoice number to another worksheet ("Details") when one is selected. I've added the "If IsNumeric" condition to make sure that only cells containing an invoice # will be copied over. The code seems to do nothing, can anyone help point me in the right direction?
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 4 Then
On Error Resume Next
Application.EnableEvents = False
If IsNumeric(Target.Value) Then
Sheets("Detail").Range("A5").Value = Target.Value
Application.EnableEvents = True
Sheets("Detail").Activate
End If
End If
End Sub
Rather than:
IsNumeric(Target.Address)
try
IsNumeric(Target)
EDIT#1:
Try this:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 4 Then
Application.EnableEvents = False
If IsNumeric(Target.Value) Then
Target.Copy Sheets("Detail").Range("A5")
End If
Application.EnableEvents = True
End If
End Sub
EDIT#2:
You need to re-enable events within the same IF
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 4 Then
On Error Resume Next
If IsNumeric(Target.Value) Then
Application.EnableEvents = False
Sheets("Detail").Range("A5").Value = Target.Value
Sheets("Detail").Activate
Application.EnableEvents = True
End If
End If
End Sub

Resources