Reputation: 93
I have this VBA code to change or to update the time stamp for 2 cells at the same row in Excel, but some how I can only have the first column to update the time stamp when I change the value but nothing happen to the second column, it return blank value. I also want to have the sheet protected so when the time stamp is update, it is locked and not be edit but dont know how to put it into protection
Private Sub Worksheet_Change(ByVal Target As Range)
Dim xRg As Range
On Error Resume Next
Dim I As Range, J As Range, L As Range, M As Range
Set I = Range("I:I")
Set L = Range("L:L")
Set T = Target
' Timestamp for Trackin
If Intersect(I, T) Is Nothing Then Exit Sub
If Intersect(I, T).Value = "Yes" Then Range("J" & T.Row).Value = Now
' Timestamp for Completion
If Intersect(L, T) Is Nothing Then Exit Sub
If Intersect(L, T).Value = "Complete" Then Range("M" & T.Row).Value = Now
Application.EnableEvents = True
End Sub
Upvotes: 3
Views: 885
Reputation: 54807
PW
)).The Code
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Const cCheckList As String = "I,L"
Const cWriteList As String = "J,M"
Const CriteriaList As String = "Yes,Complete"
Const PW As String = ""
Const FirstRow As Long = 2
Dim cCheck() As String: cCheck = Split(cCheckList, ",")
Dim cWrite() As String: cWrite = Split(cWriteList, ",")
Dim Criteria() As String: Criteria = Split(CriteriaList, ",")
Dim rng As Range
Dim ColOffset As Long
Dim n As Long
For n = 0 To UBound(cCheck)
Set rng = Intersect(Columns(cCheck(n)) _
.Resize(Rows.Count - FirstRow + 1).Offset(FirstRow - 1), Target)
If Not rng Is Nothing Then
ColOffset = Columns(cWrite(n)).Column - Columns(cCheck(n)).Column
Application.ScreenUpdating = False
Application.EnableEvents = False
Me.Unprotect Password:=PW
updateLock rng, Criteria(n), ColOffset, Now
Me.Protect Password:=PW
Application.EnableEvents = True
Application.ScreenUpdating = True
End If
Next n
End Sub
Sub updateLock( _
rng As Range, _
ByVal s As String, _
ByVal ColOffset As Long, _
ByVal TimeStamp As Date)
Const ProcName As String = "updateLock"
On Error GoTo clearError
Dim aRng As Range
Dim cel As Range
For Each aRng In rng.Areas
For Each cel In aRng.Cells
If Not IsError(cel) Then
With cel
If StrComp(.Value, s, vbTextCompare) = 0 Then
If Not StrComp(.Value, s, vbBinaryCompare) = 0 Then
.Value = s
End If
.Locked = True
With .Offset(, ColOffset)
.Value = TimeStamp
'.Locked = True
End With
End If
End With
End If
Next cel
Next aRng
ProcExit:
Exit Sub
clearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Sub
Sub doEnableEvents()
Application.EnableEvents = True
End Sub
Upvotes: 2
Reputation: 96753
How about:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim I As Range, L As Range, T As Range
Dim rw As Long, v As String
Set I = Range("I:I")
Set L = Range("L:L")
Set T = Target
rw = T.Row
v = T.Value
If Not Intersect(T, I) Is Nothing Then
If v = "Yes" Then
Application.EnableEvents = False
Range("J" & rw) = Now
Application.EnableEvents = True
End If
End If
If Not Intersect(T, L) Is Nothing Then
If v = "Complete" Then
Application.EnableEvents = False
Range("M" & rw) = Now
Application.EnableEvents = True
End If
End If
End Sub
EDIT#1:
This version of the code will not over-write a timestanp after it has been entered.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim I As Range, L As Range, M As Range
Dim rw As Long, v As String
Set I = Range("I:I")
Set L = Range("L:L")
Set T = Target
rw = T.Row
v = T.Value
If Not Intersect(T, I) Is Nothing Then
If v = "Yes" And Range("J" & rw) = "" Then
Application.EnableEvents = False
Range("J" & rw) = Now
Application.EnableEvents = True
End If
End If
If Not Intersect(T, L) Is Nothing Then
If v = "Complete" And Range("M" & rw) = "" Then
Application.EnableEvents = False
Range("M" & rw) = Now
Application.EnableEvents = True
End If
End If
End Sub
The code won't change a timestamp, but you still can.
Upvotes: 2