Trying to do an insert if formula in VBA for the following;
In my column K I want three conditions:
Date is Today or older (ie project is due today or earlier) = RED
Date is Today + up to 7 days = Amber
Date is Today less more than 7 days = Green
I was thinking of using something along the lines of:
Sub ChangeColor()
lRow = Range("K" & Rows.Count).End(xlUp).Row
Set MR = Range("K3:K" & lRow)
For Each cell In MR
If cell.Value = "TODAY" Then cell.Interior.ColorIndex = 10
If cell.Value = "TODAY-7days" Then cell.Interior.ColorIndex = 9
If cell.Value = "Morethan7Days" Then cell.Interior.ColorIndex = 8
Next
End Sub
I've been trying but I'm not sure how to do it.
I think my way is correct yet I am not sure how to code the If date=-7days then and so on.
Can someone provide some guidance? :)
VBA has a Date function that returns today's date. Dates in VBA are the number of days since December 31, 1900 (usually and with a leap year bug), so you can subtract or add integers to Date to get past and future days.
Sub ChangeColor()
Dim rCell As Range
With Sheet1
For Each rCell In .Range("K3", .Cells(.Rows.Count, 11).End(xlUp)).Cells
If rCell.Value <= Date Then
rCell.Interior.Color = vbRed
ElseIf rCell.Value <= Date + 7 Then
rCell.Interior.Color = vbYellow
Else
rCell.Interior.Color = vbGreen
End If
Next rCell
End With
End Sub
Mr. Anderson is correct that you could accomplish this with conditional formatting however if you want to do this in VBA Create a variable to hold the date and set it to the current day minus the time. Then you just want to Format the cells value to a date format. Once this is done you can use dateAdd to and and subtract the days. See below
Sub ChangeColor()
Dim myDate As Date
'format the date excluding time
myDate = FormatDateTime(Now, 2)
lRow = Range("K" & Rows.Count).End(xlUp).Row
Set MR = Range("K3:K" & lRow)
For Each cell In MR
If FormatDateTime(cell.Value, 2) = myDate Then cell.Interior.ColorIndex = 10
If FormatDateTime(cell.Value, 2) = DateAdd("d", -7, myDate) Then cell.Interior.ColorIndex = 9
If FormatDateTime(cell.Value, 2) = DateAdd("d", 7, myDate) Then cell.Interior.ColorIndex = 8
Next
End Sub
I did notice that your checking to see if it is equal so only dates that are exactly Todays date, 7 days from today and 7 days previous to today will have the interior color filled. greater than and less than to fill all interior cell colors
Sorry for all the edits
Related
I am trying to compare Dates in a vba script. I believe the main issue is my formatting however I am not sure how to solve it.
Sub Rem9()
Dim i As Long
Dim lr As Long
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
wsName = ws.Name
lr = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
FirstDateRead = CDate("1, 1,2018") 'Initialize the first Day of the year as the last day
For i = 1 To lr
Debug.Print FirstDateRead
Debug.Print ws.Cells(i, 1).Value
If FirstDateRead > ws.Cells(i, 1).Value Then
ws.Cells(i, 3).Value = 121325
End If
Next i
End Sub
According to my output the First Date Read is never greater than the values I am pulling, Which it is for all cases. I have included here an example of the debug.print from the script I am running to show the date formats. Additionally I want to confirm the values I am drawing from are indeed datevaluse as when I run them through the IsDate() Function it returns True.
One other issue if that my date format for the value I call is swapping the year and day. Does anyone know how to solve that. When I use the format function it returns the date as.
Assuming the cells containing the dates are in text format, try wrapping the comparison value in a cDate:
If FirstDateRead > Cdate(ws.Cells(i, 1).Value) Then
ws.Cells(i, 3).Value = 121325
End If
Try using the DateDiff function instead:
Sub dateDifference()
Dim d1 As Date, d2 As Date
d1 = CDate("1, 2,2018")
d2 = Range("A1").Value ' insert a date in A1 to test
Debug.Print DateDiff("d", d1, d2) ' first parameter set to days
End Sub
Edit #1
Use Format to compare apples with apples, so to speak:
d2 = Format(Range("A1").Value, "dd/mm/yyyy")
I'm just trying to check the latest Date cell, which is in Column A, against the current date. If the difference is 30 days, I write a new row.
When I execute, it says I can't call CheckAttendance on Sheet("Occurences"). But why?
Option Explicit
Public LastCell As Long
Public today As Date
Function CheckAttendance()
Dim DaysSinceOcc As Integer
'returns last occupied row
LastCell = Cells(Rows.Count, 1).End(xlUp).Row
'gets current date
today = Date
'subtracts last cell in specified column from today's date.
DaysSinceOcc = today - Cells(LastCell, 1).Value
'writes what I want written in the cells I want it written in.
If DaysSinceOcc > 29 Then
Cells(LastCell, 1).Offset(1, 1) = "winback"
Cells(LastCell, 1).Offset(1, 2) = -0.5
Cells(LastCell, 1).Offset(1, 4) = "Earned back 0.5 pts for 30 days perfect attendance (AutoGenerated)"
Cells(LastCell, 1).Offset(1, 5) = "AUTO"
Cells(LastCell, 1).Offset(1, 0) = today
Else
End If
End Function
Sub Attendance()
Sheets("Occurences").CheckAttendance
'yes Occurences is suppose to be spelled like that (don't ask)
End Sub
edit: there are probably multiple problems with this. I fixed a lot of things, but then got stuck.
It seems that you want to parametrize your CheckAttendance routine so that it can be called on different worksheets. To do that, make it a Sub that takes a worksheet as parameter. Moreover
qualify you cells and ranges in the code
dim your variables and use Option Explicit
Option Explicit
Sub CheckAttendance(ws As Worksheet)
Dim DaysSinceOcc As Long, lastRow As Long, today As Long
lastRow = ws.Cells(ws.Rows.count, 1).End(xlUp).row
'gets current date
today = Date
'subtracts last cell in specified column from today's date.
DaysSinceOcc = today - ws.Cells(lastRow, 1).Value2
'writes what I want written in the cells I want it written in.
If DaysSinceOcc > 29 Then
ws.Cells(lastRow + 1, 1) = today
ws.Cells(lastRow + 1, 2) = "winback"
ws.Cells(lastRow + 1, 3) = -0.5
ws.Cells(lastRow + 1, 5) = "Earned back 0.5 pts for 30 days perfect attendance (AutoGenerated)"
ws.Cells(lastRow + 1, 6) = "AUTO"
End If
End Sub
Sub Attendance()
CheckAttendance Sheets("Occurences") ' <-- this is how you call it on any worksheet
End Sub
I'm trying to use vba to replace last week's date with this week's to update figures. I've tried the below but I don't think I'm understanding how the replace function works in VBA.
Dim lastweek As String
lastweek = Format(Now - 7, "yyyymmdd")
Dim thisweek As String
thisweek = Format(Now, "yyyymmdd")
Replace (lastweek,lastweek,thisweek)
Also, am I using the correct formula for last week where I want to pull the date for 7 days ago?
Convert the last week to Date and add 7 days to it, to get next week value
Function MyWeek(lastweek As String) As String
lw = DateSerial(CInt(Left(lastweek, 4)), CInt(Mid(lastweek, 5, 2)), CInt(Right(lastweek, 2)))
MyWeek = Format(lw + 7, "yyyymmdd")
End Function
Then use,
=REPLACE(A1,SEARCH("2*]",A1,1),8,Myweek(MID(A1,SEARCH("2*]",A1,1),8)))
to replace the date with new date, assuming your string to be replaced is in the Cell A1
You can also use auto-filter option in VBA. Just paste the below code in a Module as follows:
Sub date_change()
Dim filter_column As Range
Dim start_date As Date
Dim end_date As Date
With ActiveSheet
.AutoFilterMode = False
Set filter_column = .Range("j1") 'give the column which has the date that needs to be changed
end_date = Now - Weekday(Now, vbSunday)
end_date = DateSerial(Year(end_date), Month(end_date), Day(end_date))
start_date = end_date - 6
start_date = DateSerial(Year(start_date), Month(start_date), Day(start_date))
.Rows(1).AutoFilter Field:=filter_column.Column, Criteria1:=">=" & start_date, Operator:=xlAnd, Criteria2:="<=" & end_date
.Range(.Cells(2, filter_column.Column), .Cells(.Rows.Count, filter_column.Column).End(xlUp)).Select
If WorksheetFunction.Subtotal(3, Selection) <> 1 Then
Selection.ClearContents
Selection = Now
End If
End With
End Sub
I have a column of dates in Column D in the mm-dd-yyyy format. Below is the code that I am trying to use to delete the entire row of data if the Active Cell in Column D is either Blank, Today's Date, or older than 8 days (i.e. today is 3/13/14, so it would erase blank entries, today's date, and anything older than 3/5/14).
Dim lastrow As Long
lastrow = Range("A65536").End(xlUp).Row
Range("D" & lastrow).Select
Do
If (ActiveCell = "" Or ActiveCell = Format(Now, "mm/dd/yyyy") Or ActiveCell < Format(Now -8, "mm/dd/yyyy")) _
Then ActiveCell.EntireRow.Delete
ActiveCell.Offset(-1, 0).Select
Loop Until ActiveCell = "Completed Date)"
If I use the "<" symbol, it erases everything basically, and if I use the ">" symbol, then it doesn't erase the rows with dates in February, etc. Can anyone suggest a method that will work, or why mine isn't?
I'm just thinking off the top of my head, but the moment you use the Format keyword in Excel, it probably converts the date to a text value, so you can't perform comparison operations on it...
Try this instead:
If (ActiveCell = "" Or (ActiveCell = Format(Now, "mm/dd/yyyy")) Or (Cdate(ActiveCell) < (Now -8))) _
In effect, rather than changing NOW()-8 to text, converting Activecell to a date you can use for comparison's sake.
Again, I didn't do this with VBA, but I'm guessing it should do the trick.
Good luck!!
Try use DateDiff:
If not isempty(activecell)
If DateDiff("d", Now(), ActiveCell.Value) < -8 then
'do your stuff
endif
endif
Paste the following code into a module:
Sub ScrubData()
Dim i As Long
Dim numRowsWithVal As Long
Dim myActiveCell As Range
Dim todaysDate As Date
Dim cutoffDate As Date
'Use a custom function to delete all blank rows in column specified
Call DeleteAllBlankRowsInColumn("D")
'Use VBA's Date() function to get current date (i.e. 3/13/14)
todaysDate = Date
'Set the cutoff date to anything older than 8 days
cutoffDate = todaysDate - 8
'***** Loop through all rows and clear values if rows are equal to today's date or older than 8 days ******
'Count the number of rows with values (subtract one because sheet has headers)
numRowsWithVal = (Range("D" & Rows.Count).End(xlUp).Row) - 1
'Start at Range("D2")
Set myActiveCell = ActiveSheet.Range("D2")
For i = 0 To numRowsWithVal - 1
Select Case True
'If value of cell is today's date OR older than 8 days clear the values
Case myActiveCell.Offset(i, 0).Value = todaysDate, myActiveCell.Offset(i, 0).Value <= cutoffDate
myActiveCell.Offset(i, 0).ClearContents
'Value is valid, do nothing
Case Else
End Select
Next
'***********************************************************************************************************
'Now that values are cleared, delete all blank rows again
Call DeleteAllBlankRowsInColumn("D")
End Sub
Public Function DeleteAllBlankRowsInColumn(ByVal columnLetter As String)
'Delete all blank rows in column specified (suppress errors just in case there aren't any blank cells)
On Error Resume Next
Columns(columnLetter).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
'Set error handling back to normal
On Error GoTo 0
End Function
Before:
After:
Facing such a problem when hadling with excels again...
I have an excel table with such cloumns
People Date
-------------------------
A 01/01/2013 - 05/01/2013
B 03/05/2013
C 08/06/2013
What I want to produce (For example A)
People Individual Date
-------------------------
A 01/01/2013
A 02/01/2013
A 03/01/2013
A 04/01/2013
A 05/01/2013
The year will be constant at 2013 and month are more or less kept constant as well.
Can someone give idea on how to achieve this?
Sub ExpandDates()
Dim rCell As Range
Dim i As Long
Dim vaDates As Variant
Dim rNext As Range
'Loop through the cells that contain dates or date ranges
For Each rCell In Sheet1.Range("B2:B4").Cells
'If there's a space, hyphen, space in the cell, it's a date range
If InStr(1, rCell.Value, " - ") > 0 Then
'Split the cell contents on space, hyphen, space
vaDates = Split(rCell.Value, " - ")
'Loop through the days of the range of dates
For i = CDate(vaDates(0)) To CDate(vaDates(1))
'Find the next blank cell in column E to record the results
Set rNext = Sheet1.Cells(Sheet1.Rows.Count, 5).End(xlUp).Offset(1, 0)
'Write column A to column E
rNext.Value = rCell.Offset(0, -1).Value
'Create a new date in column B using the month that the loop is currently processing
rNext.Offset(0, 1).Value = CDate(i)
Next i
'If no hyphen, it's just a date, so create one line in column E
Else
Set rNext = Sheet1.Cells(Sheet1.Rows.Count, 5).End(xlUp).Offset(1, 0)
rNext.Value = rCell.Offset(0, -1).Value
rNext.Offset(0, 1).Value = rCell.Value
End If
Next rCell
End Sub
Theory: Check the length of the cell. If the cell is longer than 10 characters, use the SPLIT function to get the 2 dates. Set the months equal to a variable, and do a loop based on those months to calculate the dates between them. You would probably store those dates in an array. Then write the array to the spreadsheet and move to the next cell to start the process over.
EDIT:
Sub prSplit()
If len(ActiveCell.Value) > 10 Then
Dim arr() As String
arr = Trim(Split(ActiveCell.Value, "-"))
For i = LBound(arr) To UBound(arr)
MsgBox arr(i)
Next
End If
End Sub
You can start with this and tweak the code until you get it. I just don't have the time to do the whole thing. Sorry. :o(