Feb 11 2023 08:19 PM - edited Feb 12 2023 09:57 AM
Hello! I am very new to excel and can’t really do much beyond the basics and having trouble figuring this out.
I have a table full of tasks for my team in a sheet named ‘current’ and column d is for completion dates. I need it so once someone enters a date in that column the whole row will be moved to the sheet labeled ‘completed’ which has the same headers from the original sheet.
Any and all help and advice would be very much appreciated! Thank you!
Feb 17 2023 07:33 AM
The copying of data from one place to another can be done with a formula, but the movement of data (rows) from one place to another is not. You will need to use (VBA) procedural code. That requirement will limit you to a version of Excel that supports VBA scripts – a version of Excel for either Windows or Mac – and the workbook must be stored as a macro-enabled workbook (typically with a .xlsm extension). And it also means that the "someone" who enters a date will also have the ability to change the workbook's code – and potentially do something malicious. So you need to be more concerned with security than before. And you or someone at your workplace needs to become familiar with VBA and the Excel object model.
Each worksheet's code can optionally include a Worksheet_Change event handler; such an event handler will be invoked whenever a user (or software, but with exceptions) makes a change to a value on that worksheet. So the VBA code relevant to your requirement must go into a Worksheet_Change event handler for your Current worksheet. The code will be written to ignore changes other than in column D.
Here is code you might use:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim strMessage As String 'a message to the user
' -- In this worksheet:
Dim rngIntersection As Range 'changed cells of interest
Dim rngCell As Range
Dim in4RowNum As Long
Dim vntStoredValue As Variant
' -- For working with the Completed worksheet:
Dim objCompletedSht As Worksheet
Dim in4LastUsedRow As Long
'----
On Error GoTo WorkshtChg_ErrHndlr
'
Application.EnableEvents = False '...because this procedure may change _
the content of this and/or other worksheets, and we don't want _
those changes to fire additional events
CheckForChangeOfCompleted:
'---- Check for a change in value(s) in the CompletedDt column.
Set rngIntersection = Intersect(Target, Me.Range("D:D"))
If rngIntersection Is Nothing Then
'...the change(s) did not involve the column of interest.
GoTo CheckForNextChangeTypeOfInterest
End If
' Normally we would loop through the intersection cells using:
'For Each rngCell In rngIntersection
' ...but because the code in this loop may delete one or more rows,
' loop from the bottom up instead:
For in4RowNum = 200 To 2 Step -1 '[your range of rows may be different, _
depending on how many header rows you have and how much data you _
expect]
Set rngCell = Me.Range("D" & in4RowNum)
' -- Capture info.
vntStoredValue = rngCell.Value
If vntStoredValue = "" Then
' Either it was unchanged, or an invalid value was cleared.
' In either case, no action is needed for this row.
ElseIf IsDate(vntStoredValue) Then
If vntStoredValue < #1/1/2020# _
Or vntStoredValue > #12/31/2029# Then '[specify your own valid date range]
' Warn the user.
strMessage = "The Completion Date value in row " & in4RowNum _
& " is not a valid date: " & vntStoredValue
Call MsgBox(strMessage, vbExclamation)
Else
' -- Locate the last-used row in the Completed worksheet,
' based on content in column D.
Set objCompletedSht = Sheets("Completed")
With objCompletedSht
in4LastUsedRow = .Range("D" & .Rows.Count).End(xlUp).Row
End With
' -- Move this row in the Current worksheet to the bottom of
' the Completed worksheet.
Me.Range("A" & in4RowNum).EntireRow.Cut _
objCompletedSht.Range("A" & (in4LastUsedRow + 1)).EntireRow
Me.Range("A" & in4RowNum).EntireRow.Delete xlUp
End If
Else
' Warn the user.
strMessage = "The Completion Date value in row " & in4RowNum _
& " is not a valid date: " & vntStoredValue _
& " (" & TypeName(vntStoredValue) & ")"
Call MsgBox(strMessage, vbExclamation)
End If
Next
CheckForNextChangeTypeOfInterest:
'There is none, so:
Application.EnableEvents = True
Exit Sub
WorkshtChg_ErrHndlr:
Dim in4ErrorCode As Long
Dim strErrorDescr As String
' -- Capture info.
in4ErrorCode = Err.Number
strErrorDescr = Err.Description
' -- Notify the user.
strMessage = "Error " & in4ErrorCode & " occurred:" & vbCrLf & strErrorDescr
Call MsgBox(strMessage, vbCritical)
' --
Application.EnableEvents = True
Exit Sub
End Sub
(And I recommend always specifying an Option Explicit statement at the top of the code module. That makes VBA catch misspelled variable names.)