Am using the following code that works for populating static dates in column C when data is filled in column B.
I would like to also have column E populated with static dates if data is filled in column D. Please advise tq
Private Sub Worksheet_Change(ByVal Target As Range)
'Update 20140722
Dim WorkRng As Range
Dim Rng As Range Dim xOffsetColumn As Integer
Set WorkRng = Intersect(Application.ActiveSheet.Range("B:B"), Target)
xOffsetColumn = 1
If Not WorkRng Is Nothing Then
Application.EnableEvents = False
For Each Rng In WorkRng
If Not VBA.IsEmpty(Rng.Value) Then
Rng.Offset(0, xOffsetColumn).Value = Now
Rng.Offset(0, xOffsetColumn).NumberFormat = "dd-mm-yyyy, hh:mm:ss"
Else
Rng.Offset(0, xOffsetColumn).ClearContents
End If
Next
Application.EnableEvents = True
End If
End Sub
A Worksheet Change: Time Stamp and Clear
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Const fRow As Long = 1 ' possibly 2 or more to exclude headers
Const cOffset As Long = 1
' Reference the intersecting range.
Dim irg As Range ' Intersect
With Columns("B")
With .Resize(.Rows.Count - fRow + 1).Offset(fRow - 1)
'Debug.Print Union(.Cells, .EntireRow.Columns("D")).Address
Set irg = Intersect(Union(.Cells, .EntireRow.Columns("D")), Target)
End With
End With
If irg Is Nothing Then Exit Sub
Dim trg As Range ' Time
Dim crg As Range ' Clear
Dim iCell As Range
' Combine cells into the Time and Clear ranges.
For Each iCell In irg.Cells
If Not VBA.IsEmpty(iCell.Value) Then
If trg Is Nothing Then Set trg = iCell _
Else Set trg = Union(trg, iCell)
Else
If crg Is Nothing Then Set crg = iCell _
Else Set crg = Union(crg, iCell)
End If
Next iCell
Application.EnableEvents = False
' Write.
If Not trg Is Nothing Then
With trg.Offset(, cOffset)
.NumberFormat = "dd-mm-yyyy, hh:mm:ss"
.Value = Now
End With
End If
If Not crg Is Nothing Then
crg.Offset(, cOffset).ClearContents
End If
Application.EnableEvents = True
End Sub
Related
I have below code when the date is changing while any of cells is updated. But the challenge that I have is with the cell where the date is display. I need the data to be updated always only in column E. How to change - xOffsetColumn = 1 to get there?
Private Sub Worksheet_Change(ByVal Target As Range)
'Update 20140722
Dim WorkRng As Range
Dim Rng As Range
Dim xOffsetColumn As Integer
Set WorkRng = Intersect(Application.ActiveSheet.Range("B:B"), Target)
xOffsetColumn = 1
If Not WorkRng Is Nothing Then
Application.EnableEvents = False
For Each Rng In WorkRng
If Not VBA.IsEmpty(Rng.Value) Then
Rng.Offset(0, xOffsetColumn).Value = Now
Rng.Offset(0, xOffsetColumn).NumberFormat = "dd-mm-yyyy, hh:mm:ss"
Else
Rng.Offset(0, xOffsetColumn).ClearContents
End If
Next
Application.EnableEvents = True
End If
End Sub
This now works for any intersect range.
I tested the below and it works for me.
Private Sub Worksheet_Change(ByVal Target As Range)
'Update 20140722
Dim dateCol%, xOffsetColumn%
Dim Rng As Range, WorkRng As Range
Dim WS As Worksheet
Set WS = ThisWorkbook.Sheets(Target.Parent.Name)
'Set WorkRng = Intersect(Application.ActiveSheet.Range("B:B"), Target)
Set WorkRng = Intersect(Application.ActiveSheet.Range("E:AV"), Target)
'dateCol = 5
dateCol = 4
xOffsetColumn = 3
If Not WorkRng Is Nothing Then
Application.EnableEvents = False
For Each Rng In WorkRng
If Not VBA.IsEmpty(Rng.value) Then
' Rng.Offset(0, xOffsetColumn).value = Now
' Rng.Offset(0, xOffsetColumn).NumberFormat = "dd-mm-yyyy, hh:mm:ss"
WS.Cells(Rng.row, dateCol) = Now()
WS.Cells(Rng.row, dateCol).NumberFormat = "dd-mm-yyyy, hh:mm:ss"
Else
Rng.Offset(0, xOffsetColumn).ClearContents
End If
Next
Application.EnableEvents = True
End If
End Sub
I have received a request to fill in date based on specific status chosen (cell value) in a column representing that status.
For example if I choose a Status "Event_1" in column A from a drop down list, macro should find a column with the same name (Event_1) and fill in date in that column for the Row where the status was changed.
I only got as far as filling adjacent cell with a date when said cell is changed. I know I should probably adjust offset to a column number representing my status, however I'm not sure how to achieve this.
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim ColNum As Integer
With Target
If .Count > 1 Then Exit Sub
If Not Intersect(Range("A:A"), .Cells) Is Nothing Then
Application.EnableEvents = False
If IsEmpty(.Value) Then
.Offset(0, 1).ClearContents
Else
With .Offset(0, 1)
.NumberFormat = "dd mmm yyyy"
.Value = Now
End With
End If
Application.EnableEvents = True
End If
End With
End Sub
What about this?
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ColNum As Integer
With Target
If .Count > 1 Then Exit Sub
If Not Intersect(Range("A:A"), .Cells) Is Nothing Then
Application.EnableEvents = False
If IsEmpty(.Value) Then
'.Offset(0, 1).ClearContents
'Why???
Else
ColNum = Application.WorksheetFunction.Match(Target.Value, Range("1:1"), 0)
With .Offset(0, ColNum - 1)
.NumberFormat = "dd mmm yyyy"
.Value = Now
End With
End If
Application.EnableEvents = True
End If
End With
End Sub
The only part I don't get is this one:
If IsEmpty(.Value) Then
.Offset(0, 1).ClearContents
Why? You should specify what you want to do when there is no option selected.
A Worksheet Change: One Timestamp Per Row
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo ClearError
Const FirstColCellAddress As String = "B1"
Const FirstRowCellAddress As String = "A2"
Const TimeFormat As String = "dd/mm/yyyy hh:mm:ss"
Dim scrg As Range
With Range(FirstRowCellAddress)
Set scrg = .Resize(.Worksheet.Rows.Count - .Row + 1)
End With
Dim irg As Range: Set irg = Intersect(scrg, Target)
If irg Is Nothing Then Exit Sub
Dim srrg As Range
Dim sCell As Range
With Range(FirstColCellAddress)
Set sCell = .Resize(, .Worksheet.Columns.Count - .Column + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
Set srrg = .Resize(, sCell.Column - .Column + 1)
End With
Dim sIndex As Variant
Dim sString As String
Dim drrg As Range
Dim dCell As Range
Dim rgClear As Range
Dim rgTime As Range
For Each sCell In irg.Cells
Set drrg = srrg.Rows(sCell.Row - srrg.Row + 1)
If rgClear Is Nothing Then
Set rgClear = drrg
Else
Set rgClear = Union(rgClear, drrg)
End If
sString = CStr(sCell.Value)
sIndex = Application.Match(sString, srrg, 0)
If IsNumeric(sIndex) Then
Set dCell = drrg.Cells(sIndex)
If rgTime Is Nothing Then
Set rgTime = dCell
Else
Set rgTime = Union(rgTime, dCell)
End If
End If
Next sCell
Application.EnableEvents = False
If Not rgClear Is Nothing Then rgClear.Clear
If Not rgTime Is Nothing Then
Dim TimeStamp As Date: TimeStamp = Now
With rgTime
.NumberFormat = TimeFormat
.Value = TimeStamp
End With
End If
SafeExit:
If Not Application.EnableEvents Then Application.EnableEvents = True
Exit Sub
ClearError:
Debug.Print "Run-time error '" & Err.Number & "': " & Err.Description
Resume SafeExit
End Sub
I am using the following VBA code to automatically timestamp dates when I edit or change cells. It works perfectly however, whenever i delete a row it will cause the cell directly under it to refresh its timestamp, this is very annoying and has led me to hide unwanted rows instead of deleting them, appreciate if you can help me fix this through changes in the VBA.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim WorkRng As Range
Dim Rng As Range
Dim xOffsetColumn As Integer
Set WorkRng = Intersect(Application.ActiveSheet.Range("B:B"), Target)
xOffsetColumn = 1
If Not WorkRng Is Nothing Then
Application.EnableEvents = False
For Each Rng In WorkRng
If Not VBA.IsEmpty(Rng.Value) Then
Rng.Offset(0, xOffsetColumn).Value = Now
Rng.Offset(0, xOffsetColumn).NumberFormat = "dd-mm-yyyy, hh:mm:ss"
Else
Rng.Offset(0, xOffsetColumn).ClearContents
End If
Next
Application.EnableEvents = True
End If
End Sub
You can ignore changes which involve a whole row or rows:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim WorkRng As Range, c As Range
Dim Rng As Range
Dim xOffsetColumn As Integer
'whole row(s) changed - do not process
If Target.Columns.Count = Me.Columns.Count Then Exit Sub
Set WorkRng = Intersect(Application.ActiveSheet.Range("B:B"), Target)
xOffsetColumn = 1
If Not WorkRng Is Nothing Then
Application.EnableEvents = False
For Each Rng In WorkRng
Set c = Rng.Offset(0, xOffsetColumn) '****
If Not VBA.IsEmpty(Rng.Value) Then
c.Value = Now
c.NumberFormat = "dd-mm-yyyy, hh:mm:ss"
Else
c.ClearContents
End If
Next
Application.EnableEvents = True
End If
End Sub
I'm trying to delete any rows in the range "Y3:Y50" where in column "Y", the value is "0".
Dim aRange As Range, aRow As Range, aCell As Range
Set aRange = Range("Y3:Y50")
For Each aRow In aRange.Rows
For Each aCell In aRow.Cells
If aCell.Value = "0" Then
aRow.EntireRow.Delete
Exit For
End If
Next aCell
Next aRow
It is deleting some but not all the rows it should.
The alternative is to delete rows where there is no data in column "A". I feel that would probably be a cleaner option in case I have a row where 0 is the correct value in the future.
Full macro below.
Sub SubbyRunsheet()
Dim rng As Range, URng As Range, cel As Range
Dim wb As Workbook: Set wb = ActiveWorkbook
Dim ws As Worksheet: Set ws = wb.Worksheets("Runsheet")
Application.ScreenUpdating = False
'Clean up SOR sheet
Sheets("SOR").Activate
With ActiveSheet
.AutoFilterMode = False
With Range("A1", Range("A" & Rows.Count).End(xlUp))
.AutoFilter 1, "<>" & Worksheets("Runsheet").Range("E1")
On Error Resume Next
.Offset(1).SpecialCells(12).EntireRow.Delete
End With
.AutoFilterMode = False
End With
'Clean up the runsheet
Sheets("Runsheet").Activate
ActiveSheet.Range("A:A").Delete
ActiveSheet.Cells.Select
Cells.WrapText = False
Selection.EntireColumn.AutoFit
'VBasic's code
Const Addr As String = "Y3:Y50"
Const Criteria As Variant = 0
Set rng = ws.Range(Addr)
For Each cel In rng.Cells
If cel.Value = Criteria Then GoSub collectCells
Next cel
If Not URng Is Nothing Then URng.EntireRow.Hidden = True
Exit Sub
collectCells:
If Not URng Is Nothing Then
Set URng = Union(URng, cel)
Else
Set URng = cel
End If
Return
Cells(1, 1).Select
Cells.WrapText = True
ActiveSheet.Range("A2:Y100").RowHeight = 15
Application.DisplayAlerts = False
Worksheets("Reference").Delete
Worksheets("Format Helper").Delete
Worksheets("Airtable Upload").Delete
Worksheets("Formula Sheet").Delete
Application.DisplayAlerts = True
WeekEnding = Format(ActiveSheet.Range("B3").Value, "yyyymmdd")
ActiveWorkbook.SaveAs Filename:="C&I Subcontractor Weekly Runsheet - " & Worksheets("Runsheet").Range("D1") & " WE " & WeekEnding
Application.ScreenUpdating = True
End Sub
Delete Rows With Criteria
Option Explicit
Sub deleteRowsY()
' Constants
Const Addr As String = "Y3:Y50"
Const Criteria As Variant = 0
' If this is happening in the workbook containing this code,
' then use 'Set wb = ThisWorkbook' instead.
Dim wb As Workbook: Set wb = ActiveWorkbook
' The worksheet is better defined by its name,
' e.g. Set ws = wb.Worksheets("Sheet1")
Dim ws As Worksheet: Set ws = wb.ActiveSheet
' Define Column Range.
Dim rng As Range: Set rng = ws.Range(Addr)
' Loop through each cell in Column Range.
Dim cel As Range, URng As Range
For Each cel In rng.Cells
If cel.Value = Criteria Then GoSub collectCells
Next cel
' Test with hiding, you cannot undo the deletion.
If Not URng Is Nothing Then URng.EntireRow.Hidden = True
' When ready, outcomment the previous and uncomment the following line.
'If Not URng Is Nothing Then URng.EntireRow.Delete
Exit Sub
collectCells:
If Not URng Is Nothing Then
Set URng = Union(URng, cel)
Else
Set URng = cel
End If
Return
End Sub
Sub deleteRowsA()
' Constants
Const FirstRow As Long = 3
Const tgtCol As Variant = "A" ' e.g. 1 or "A"
Const Criteria As Variant = Empty
' If this is happening in the workbook containing this code,
' then use 'Set wb = ThisWorkbook' instead.
Dim wb As Workbook: Set wb = ActiveWorkbook
' The worksheet is better defined by its name,
' e.g. Set ws = wb.Worksheets("Sheet1")
Dim ws As Worksheet: Set ws = wb.ActiveSheet
' Define Column Range.
Dim LastRow As Long: LastRow = ws.Cells(ws.Rows.Count, tgtCol).End(xlUp).Row
Dim rng As Range
Set rng = ws.Range(ws.Cells(FirstRow, tgtCol), ws.Cells(LastRow, tgtCol))
' Loop through each cell in Column Range.
Dim cel As Range, URng As Range
For Each cel In rng.Cells
If cel.Value = Criteria Then GoSub collectCells
Next cel
' Test with hiding, you cannot undo the deletion.
If Not URng Is Nothing Then URng.EntireRow.Hidden = True
' When ready, outcomment the previous and uncomment the following line.
'If Not URng Is Nothing Then URng.EntireRow.Delete
Exit Sub
collectCells:
If Not URng Is Nothing Then
Set URng = Union(URng, cel)
Else
Set URng = cel
End If
Return
End Sub
EDIT:
Option Explicit
Sub deleteY(Sheet As Worksheet, RangeAddress As String, Criteria As Variant)
' Define Column Range.
Dim rng As Range: Set rng = Sheet.Range(RangeAddress)
' Loop through each cell in Column Range.
Dim cel As Range, URng As Range
For Each cel In rng.Cells
If cel.Value = Criteria Then GoSub collectCells
Next cel
' Test with hiding, you cannot undo the deletion.
If Not URng Is Nothing Then URng.EntireRow.Hidden = True
' When ready, outcomment the previous and uncomment the following line.
'If Not URng Is Nothing Then URng.EntireRow.Delete
Exit Sub
collectCells:
If Not URng Is Nothing Then
Set URng = Union(URng, cel)
Else
Set URng = cel
End If
Return
End Sub
Sub delY()
' Constants
Const ColumnAddress As String = "Y3:Y50"
Const Criteria As Variant = 0
' Define worksheet.
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet1")
deleteY ws, ColumnAddress, Criteria
End Sub
Sub deleteA(Sheet As Worksheet, _
FirstRow As Long, _
ColumnID As Variant, _
Criteria As Variant)
' Define Column Range.
Dim LastRow As Long
LastRow = Sheet.Cells(Sheet.Rows.Count, ColumnID).End(xlUp).Row
Dim rng As Range
Set rng = ws.Range(ws.Cells(FirstRow, ColumnID), _
ws.Cells(LastRow, ColumnID))
' Loop through each cell in Column Range.
Dim cel As Range, URng As Range
For Each cel In rng.Cells
If cel.Value = Criteria Then GoSub collectCells
Next cel
' Test with hiding, you cannot undo the deletion.
If Not URng Is Nothing Then URng.EntireRow.Hidden = True
' When ready, outcomment the previous and uncomment the following line.
'If Not URng Is Nothing Then URng.EntireRow.Delete
Exit Sub
collectCells:
If Not URng Is Nothing Then
Set URng = Union(URng, cel)
Else
Set URng = cel
End If
Return
End Sub
Sub delA()
' Constants
Const FirstRow As Long = 3
Const ColumnID As Variant = "A" ' e.g. 1 or "A"
Const Criteria As Variant = Empty
' Define worksheet.
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet1")
deleteA ws, FirstRow, ColumnID, Criteria
End Sub
Your Final Solution
Option Explicit
Sub SubbyRunsheet()
Const RangeAddress As String = "Y3:Y50"
Const Criteria As Variant = 0
Dim wb As Workbook: Set wb = ActiveWorkbook
Dim ws As Worksheet: Set ws = wb.Worksheets("Runsheet")
Application.ScreenUpdating = False
'Clean up SOR
Sheets("SOR").Activate
With ActiveSheet
.AutoFilterMode = False
With Range("A1", Range("A" & Rows.Count).End(xlUp))
.AutoFilter 1, "<>" & Worksheets("Runsheet").Range("E1")
On Error Resume Next
.Offset(1).SpecialCells(12).EntireRow.Delete
End With
.AutoFilterMode = False
End With
'Clean up Runsheet
ws.Activate
ActiveSheet.Range("A:A").Delete
ActiveSheet.Cells.Select
Cells.WrapText = False
Selection.EntireColumn.AutoFit
' Delete rows containing 0-s in Y-column of Runsheet
deleteY ws, RangeAddress, Criteria
Cells(1, 1).Select
Cells.WrapText = True
ActiveSheet.Range("A2:Y100").RowHeight = 15
Application.DisplayAlerts = False
Worksheets("Reference").Delete
Worksheets("Format Helper").Delete
Worksheets("Airtable Upload").Delete
Worksheets("Formula Sheet").Delete
Application.DisplayAlerts = True
WeekEnding = Format(ActiveSheet.Range("B3").Value, "yyyymmdd")
ActiveWorkbook.SaveAs Filename:="C&I Subcontractor Weekly Runsheet - " _
& ws.Range("D1") & " WE " & WeekEnding
Application.ScreenUpdating = True
End Sub
Sub deleteY(Sheet As Worksheet, RangeAddress As String, Criteria As Variant)
' Define Column Range.
Dim rng As Range: Set rng = Sheet.Range(RangeAddress)
' Loop through each cell in Column Range.
Dim cel As Range, URng As Range
For Each cel In rng.Cells
If cel.Value = Criteria Then GoSub collectCells
Next cel
' Test with hiding, you cannot undo the deletion.
If Not URng Is Nothing Then URng.EntireRow.Hidden = True
' When ready, outcomment the previous and uncomment the following line.
'If Not URng Is Nothing Then URng.EntireRow.Delete
Exit Sub
collectCells:
If Not URng Is Nothing Then
Set URng = Union(URng, cel)
Else
Set URng = cel
End If
Return
End Sub
I'm trying to tweak the following code which enters today's date in column B when you change column A. I'd only like this code to run when column B is empty as I'm experiencing an issue where worksheet_change is too broad and past dates entered are getting overwritten when new changes are made inadvertently.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim WorkRng As Range
Dim Rng As Range
Dim xOffsetColumn As Integer
Set WorkRng = Intersect(Application.ActiveSheet.Range("A:A"), Target)
xOffsetColumn = 1
If Not WorkRng Is Nothing Then
Application.EnableEvents = False
For Each Rng In WorkRng
If Not VBA.IsEmpty(Rng.Value) Then
Rng.Offset(0, xOffsetColumn).Value = Date
Rng.Offset(0, xOffsetColumn).NumberFormat = "mm-dd-yyyy"
Else
Rng.Offset(0, xOffsetColumn).ClearContents
End If
Next
Application.EnableEvents = True
End If
End Sub
You could check if the value is already a date
Private Sub Worksheet_Change(ByVal Target As Range)
Dim WorkRng As Range
Dim Rng As Range
Dim xOffsetColumn As Integer
Set WorkRng = Intersect(Application.ActiveSheet.Range("A:A"), Target)
xOffsetColumn = 1
If Not WorkRng Is Nothing Then
Application.EnableEvents = False
For Each Rng In WorkRng
If Not VBA.IsEmpty(Rng.Value) Then
With Rng.Offset(0, xOffsetColumn)
If Not VBA.Information.IsDate(.Value) Then
.Value = Date
.NumberFormat = "mm-dd-yyyy"
End If
End With
Else
Rng.Offset(0, xOffsetColumn).ClearContents
End If
Next
Application.EnableEvents = True
End If
End Sub