Excel VBA - compare date in cell to current week - excel

please could someone help me. I have been trying and could not seems to resolve this.
I want to compare the date in Column J to the current week. My code also include finding the last row and automatically loop until the last row.
I currently trying with the following code but having issue with
Recievedate = Format(Cells(i, "J").Value, "ww-yyyy")
I have tried
Recievedate = Format(Range(i, "J").Value, "ww-yyyy")
which was found in another post but it doesn't work. Can someone tell me what have I done wrong please? Please ignore the code after MsgBox "OK" as I am trying to build this step by step. Thank you.
Sub macro1()
Range("A1").Select
Range("A" & Rows.Count).End(xlUp).Select ' Find last row in column A and remember the active cell
Dim i As Integer
Dim Recievedate As Date
For i = 2 To ActiveCell.Row 'start from row 2 and automatically +1 until it reach the active cell
Recievedate = Format(Cells(i, "J").Value, "ww-yyyy")
If Recievedate = Format(Date, "ww-yyyy") Then
MsgBox "OK"
End If
Next i
...

Try
Sub macro1()
Range("A1").Select
Range("A" & Rows.Count).End(xlUp).Select ' Find last row in column A and remember the active cell
Dim i As Integer
' Dim Recievedate As Date
Dim Recievedate As string
For i = 2 To ActiveCell.Row 'start from row 2 and automatically +1 until it reach the active cell
Recievedate = Format(Cells(i, "J").Value, "ww-yyyy")
If Recievedate = Format(Date, "ww-yyyy") Then
MsgBox "OK"
End If
Next i
With this statement Recievedate = Format(Cells(i, "J").Value, "ww-yyyy") you assign a string to Recievedate which cannot work in case Recievedate is declared as date.
Another approach could be to use WorksheetFunction.WeekNum instead.

A possible solution - note, no Selecting required.
Sub Test()
Dim lRow As Long
lRow = Range("A" & Rows.Count).End(xlUp).Row
Dim i As Long
Dim ReceivedDate As Date
For i = 2 To lRow
ReceivedDate = Cells(i, "J")
If Format(ReceivedDate, "ww-yyyy") = Format(Date, "ww-yyyy") Then
MsgBox "Row " & i & " is ok.", vbOKOnly + vbInformation
End If
Next i
End Sub

I suggest you look for a date that is between the start and end dates of the current week.
For example (assuming your week starts on Sunday and ends on the subsequent Saturday)
Sub CurrentWeek()
Dim dt As Date
Dim dtBOW As Date, dtEOW As Date
Dim c As Range, r As Range
dtBOW = Date - Weekday(Date - 1) 'Beginning of week
dtEOW = Date + 7 - Weekday(Date) 'End of week
Set r = ThisWorkbook.Worksheets("Sheet2").Columns(10) 'Column J, fully qualified
For Each c In r.Cells
If c >= dtBOW And c <= dtEOW Then
MsgBox "found it at " & c.Address
c.Select 'Selected only so as to highlight it on the worksheet
Exit Sub
End If
Next c
MsgBox "no luck"
End Sub

Related

Excel VBA will not locate date

I am working to create an add on style sheet to my company timesheet that will autofill company paid holidays by just the user inserting the dates. I use formulas on the excel timesheets to autofill the dates for the entire year so that I save time doing my bi-weekly payroll form. I have a holiday sheet that I name the holidays and input the date they are observed. The code is supposed to search all worksheets in the workbook until it finds the date for the corresponding holiday and input the number of hours off, the holiday code and name. The code I have written will find any date I insert up to 11/9/2022 and after this date it will not find any further dates. I have tried many things including changing the date column format, using different criteria settings for the .Find and even removing the formula from the date column and actually writing in 11/11/2022 and it is still unable to locate the date while using .Find. Please any help would be appreciated. I have added a few screens and code snippets of what I have so far.
Sub VeteransDay()
Dim ws As Worksheet
Dim FindString As String
Dim Rng As Range
FindString = Sheets("Holiday").Range("B9").Value
If Trim(FindString) <> "" Then
For Each ws In Worksheets
If ws.Name <> "Holiday" Then
With ws.UsedRange
Set Rng = .Find(What:=FindString, After:=.Cells(1, 1), LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False)
If Not Rng Is Nothing Then
sheetName = ws.Name
Cell_Add = Split(Rng.Address, "$")
ThisCol = Cell_Add(1)
ThisRow = Cell_Add(2)
Worksheets(sheetName).Range("K" & ThisRow).Value = 8
Worksheets(sheetName).Range("K" & ThisRow).Font.Color = vbRed
Worksheets(sheetName).Range("L" & ThisRow).Value = "HD"
Worksheets(sheetName).Range("L" & ThisRow).Font.Color = vbRed
Worksheets(sheetName).Range("M" & ThisRow).Value = Range("A9")
Worksheets(sheetName).Range("M" & ThisRow).Font.Color = vbRed
Exit Sub
End If
End With
End If
Next ws
End If
End Sub
enter image description here
enter image description here
Try this, the search is restricted to the range B1:B37 on each sheet.
Option Explicit
Sub VeteransDay()
Dim ws As Worksheet, ar, r
Dim dt As Date, sName As String, n As Long
Dim arHoliday, lastrow As Long, i As Long
With Sheets("Holiday")
lastrow = .Cells(.Rows.Count, "B").End(xlUp).Row
arHoliday = .Range("A1:B" & lastrow).Value
End With
For Each ws In Worksheets
If ws.Name <> "Holiday" Then
' loop through holidays
For i = 1 To UBound(arHoliday)
dt = arHoliday(i, 2)
r = Application.Match(CDbl(dt), ws.Range("B1:B37").Value2, 0)
If Not IsError(r) Then
'MsgBox ws.Name & " row " & r
With ws.Range("K" & r)
.Value = 8
.Offset(, 1) = "HD"
.Offset(, 2) = arHoliday(i, 1) ' col A
.Resize(, 3).Font.Color = vbRed
n = n + 1
End With
End If
Next
End If
Next ws
MsgBox n & " found for all dates", vbInformation
End Sub

Find Duplicate Entry

I am using Excel 2010.
I have some VBA code which creates a unique key and then looks for duplicate unique key entries. Any duplicates are coloured in red.
I need to automate this a little further. If there is a duplicate unique key, copy the information from the newest entry, and paste it into the line where the original entry is. I then want the newest entry deleted.
The unique key is a concat of the customer name and the date the file was created. There will only ever be at most one duplicate entry per customer and that will be because the date the file was last updated has changed. I need the duplicate concat entry with the newest date to copy the info over the top of the entry with the oldest date on it then delete the original newest date entry. This is because we have other checks that have been completed further along the sheet that we need to keep intact.
Ideally I would like for the message box to still advise how many duplicate entries were found and for the entry to remain coloured red once the copy/paste/delete has taken place to highlight the entry that has been changed.
Private Sub CommandButton1_Click()
'Start of Concatenate Code
Dim i As Integer
Dim r As Range
On Error Resume Next
' Tells Excel to look in column 3 (Column C) for the last one with data in it
lRow = Cells(Rows.Count, 3).End(xlUp).Row
' Tell Excel to focus on cells 4 to 5000
For i = 4 To lRow
' Tell Excel to paste the contents of cell 4 (column D) followed by |
' then the contents of cell 8 (column H) into cell 2 (column B)
Cells(i, 2).Value = Cells(i, 11) & " | " & Cells(i, 7)
Next i
'End of Concatenate Code
'Start of Check for Duplicates code
Dim j As Integer
Dim myCell As Range
Dim myRange As Integer
myRange = Range("A4:A5000").Count
j = 0
' Select the Range
For Each myCell In Range("B4:B5000")
' Check that the cells in the range are not blank
If WorksheetFunction.CountIf(Range("B4:B5000"), myCell.Value) > 1 Then
' Colour the duplicate entries in red
myCell.EntireRow.Interior.ColorIndex = 3
j = j + 1
End If
Next
MsgBox "There are " & j & " duplicates found." & vbCrLf & vbCrLf & _
"Any duplicates have been highlighted in red.", vbInformation + vbOKOnly, _
"Duplicate Entry Checker"
' End of Check for Duplicates code
End Sub
Screenshot of spreadsheet
Thank you #rickmanalexander, I just tried your code (and changed the name of the sheet) but I get a subscript out of range error with the number 9 in the msgbox title. There must be something i have missed but i am not sure what?
Here is the code I used:
Private Sub CommandButton1_Click()
On Error GoTo CleanFail
Dim wrkSht As Worksheet
Set wrkSht = Sheets("Raw Data")
Dim lRow As Long
lRow = wrkSht.Cells(wrkSht.Rows.Count, 3).End(xlUp).Row
Dim arrySheet As Variant
'get the worksheet data into an array
arrySheet = wrkSht.Range("D1:H" & lRow).Value2
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
Dim keyValue As Variant
Dim i As Long
Dim rowNum As Long
Dim dupCount As Long
For i = LBound(arrySheet, 1) To UBound(arrySheet, 1)
'a concatenated key consisting of the:
'row number
'customer's name
keyValue = Join(Array(i, arrySheet(i, 1)), "|")
If Not dict.Exists(keyValue) Then
dict(keyValue) = arrySheet(i, 8) 'save the date for this unique key
Else
'if we make it here, then this is a duplicate customer
'for which we want to check the date
'If the current row's date is greater than the previouly saved date, then
'delete the current row
'determine the row umber for the previously saved entry
'place the most recent date in place of the old date
'color it red
'increase the duplicate counter
If arrySheet(i, 8) > dict(keyValue) Then
wrkSht.Rows(i).EntireRow.Delete
rowNum = CLng(Split(keyValue, "|")(0))
wrkSht.Cells(rowNum, "B").Value = CDate(arrySheet(i, 8))
wrkSht.Rows(rowNum).EntireRow.Interior.ColorIndex = 3
dupCount = dupCount = dupCount + 1
End If
End If
'clear variables
keyValue = vbNullString: rowNum = 0
Next i
MsgBox "There were " & dupCount & " duplicates found." & _
vbCrLf & vbCrLf & _
"Any duplicates have been highlighted in red.", _
vbInformation + vbOKOnly, "Duplicate Entry Checker"
CleanExit:
Exit Sub
CleanFail:
MsgBox Err.Description, vbCritical, Err.Number
Resume CleanExit
End Sub
Edit:
OP was getting Error 9 subscript out of range, because I used arrySheet(i, 8) instead of arrySheet(i, 4). I was thinking that I defined the array from the range starting at column A. Simple mistake with an easy fix.
The Dictionary Object is the perfect candidate for duplicate checks, so that is what I went with. The code below is untested, but should work for your needs.
Option Explicit
Private Sub CommandButton1_Click()
On Error GoTo CleanFail
Dim wrkSht As Worksheet
Set wrkSht = Sheets("Raw Data")
Dim lRow As Long
lRow = wrkSht.Cells(wrkSht.Rows.Count, 3).End(xlUp).Row
Dim arrySheet As Variant
'get the worksheet data into an array
arrySheet = wrkSht.Range("D1:H" & lRow).Value2
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
Dim keyValue As Variant
Dim i As Long
Dim rowNum As Long
Dim dupCount As Long
For i = LBound(arrySheet, 1) To UBound(arrySheet, 1)
'a concatenated key consisting of the:
'row number
'customer's name
keyValue = Join(Array(i, arrySheet(i, 1)), "|")
If Not dict.Exists(keyValue) Then
dict(keyValue) = arrySheet(i, 4) 'save the date for this unique key
Else
'if we make it here, then this is a duplicate customer
'for which we want to check the date
'If the current row's date is greater than the previouly saved date, then
'delete the current row
'determine the row umber for the previously saved entry
'place the most recent date in place of the old date
'color it red
'increase the duplicate counter
If arrySheet(i,4) > dict(keyValue) Then
wrkSht.Rows(i).EntireRow.Delete
rowNum = CLng(Split(keyValue, "|")(0))
wrkSht.Cells(rowNum, "B").Value = CDate(arrySheet(i, 4))
wrkSht.Rows(rowNum).EntireRow.Interior.ColorIndex = 3
dupCount = dupCount = dupCount + 1
End If
End If
'clear variables
keyValue = vbNullString: rowNum = 0
Next i
MsgBox "There were " & dupCount & " duplicates found." & _
vbCrLf & vbCrLf & _
"Any duplicates have been highlighted in red.", _
vbInformation + vbOKOnly, "Duplicate Entry Checker"
CleanExit:
Exit Sub
CleanFail:
MsgBox Err.Description, vbCritical, Err.Number
Resume CleanExit
End Sub

Code executing on only a few entries and missing entries that pass the rule?

Good Morning,
I have a database of safety data sheets for the benefit of COSHH, i am trying to create a function in which the user can enter a date into "H7" and any entried with dates less than that one will have the entire row transferred into sheet2.
the code i have written is as below
Sub checkdatasheets()
Dim datefrom As Variant
'select first entry
Sheet1.Range("E2").Select
'continue until an empty cell is reached
Do Until ActiveCell.Offset(1, 0).Value = ""
If ActiveCell.Value = "" Then GoTo skipto:
'aquire date parameter
datefrom = Sheet1.Range("H7")
'if revision date is less than the date parameter copy and add to sheet2
If ActiveCell.Value <= datefrom Then
ActiveCell.Rows.EntireRow.Copy
Sheets("Sheet2").Select
NextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
Cells(NextRow, 1).Select
ActiveSheet.Paste
Sheets("Sheet1").Select
End If
'move onto next cell
ActiveCell.Offset(1, 0).Select
Loop
skipto: MsgBox "Missing Data Sheet"
End Sub
The issue i am having is that this code takes certain rows but lots of rows are missed, even though they are less than the datefrom variable?
Thank you in advance for your help, any feedback on the writing of my code would be appreciated.
You should avoid using select and also reference your sheets better. Something like code below should work better allready:
Sub checkdatasheets2()
For X = 2 To Sheets(1).Cells(Rows.Count, 5).End(xlUp).Row
If Sheets(1).Cells(X, 5).Value < Sheets(1).Cells(7, 8).Value Then
Sheets(1).Rows(X).Copy Destination:=Sheets(2).Range("A" & Sheets(2).Cells(Sheets(2).Rows.Count, 5).End(xlUp).Row + 1)
End If
Next X
End Sub
Import the below code in the change event of the sheet which you will import the date.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim sDate As Date
Dim LastRow1 As Long, LastRow2 As Long, i As Long
If Not Intersect(Target, Range("A1")) Is Nothing Then
If IsDate(Target.Value) Then
sDate = CDate(Target.Value)
LastRow1 = Sheet1.Cells(Sheet1.Rows.Count, "A").End(xlUp).Row
For i = 3 To LastRow1
If CDate(Sheet1.Range("A" & i).Value) < sDate Then
LastRow2 = Sheet2.Cells(Sheet2.Rows.Count, "A").End(xlUp).Row
Sheet1.Rows(i).Copy Sheet2.Rows(LastRow2 + 1)
End If
Next i
Else
MsgBox "Please insert a valid date."
End If
End If
End Sub
Sheet 1 (includes the date)
Sheet 2 (Results)

Excel VBA Columns B and C OR Column D required

I have a spreadsheet which is used enterprise-wide. I am trying to put in checks such that certain fields are required. Specifically, columns B (last name) AND C (first name) are required, OR Column D (Organization) is required. However, B, C, and D cannot all three be filled in. If the row has any data at all in it, B and C or D are required.
My idea is to put in a button to run this macro. That I can do.
I've tried many things at this point. I can include the spreadsheet in case anyone can offer any insight. I had a macro that worked on a test sheet, but does not work on this sheet, if that will help at all.
Here is the macro
Sub CheckVal2()
Dim ws As Worksheet
Dim wsCurr As Worksheet
Dim cel As Range
Dim lngLastRow As Long
Dim lngRow As Long
For Each ws In Worksheets
If Left$(ws.Name, 7) = "Current" Then
Set wsCurr = ws
Exit For
End If
Next
With wsCurr
lngLastRow = .Range("B5000").End(xlUp).Row
For lngRow = 2 To lngLastRow
For Each cel In .Range("B" & lngRow & ":E" & lngRow)
If cel = "" Then
MsgBox "First and Last Name or HCO must be populated."
Cancel = True
Exit Sub
End If
If cel <> "" Then
If .Cells(lngRow, "D") = "" Then
If .Cells(lngRow, "B") = "" Or _
.Cells(lngRow, "C") = "" Then
MsgBox "First and Last Name or HCO must be populated."
Cancel = True
Exit Sub
End If
End If
End If
Next
Next
End With
'
End Sub
Once you get past whatever is causing the error trying to access wsCurr (which I suspect is just a case of the worksheet not existing), you should modify your code as follows:
With wsCurr
lngLastRow = .Range("E5000").End(xlUp).Row
For lngRow = 2 To lngLastRow
'First check whether first/last name has been consistently advised
If (.Cells(lngRow, 2) = "") <> _
(.Cells(lngRow, 3) = "") Then
MsgBox "Row " & lngRow & " - First Name and Last Name must both be advised or both be blank"
Cancel = True ' I assume this is a global variable?
Exit Sub
End If
'Now check that last name has not been advised if HCO has been, and vice-versa
If (.Cells(lngRow, 2) = "") = _
(.Cells(lngRow, 4) = "") Then
MsgBox "Row " & lngRow & " - First and Last Name, or HCO, must be populated but not both."
Cancel = True
Exit Sub
End If
Next
End With
This will get around the existing problem with your tests, which (as far as I can tell) aren't allowing for the case where all three columns have been advised.
I also changed the column on which lngLastRow was being set because, if it is set based on column B and the last row(s) of your data only contained values in column C and/or D, those final row(s) would not be being tested.

VBA Inbut box with loop

I have just started learning VBA (and coding in general) and I am faced with a problem to which I have not yet found a solution. I'd like to create an input box with a loop so that the output from the input box will be printed to separate cell. For example, I would like to write number "5" to the input box and the output will be printed to Cell "A1" and the next input, say number "9", will be printed to Cell "A2".
So far, I have managed to this and everything works fine except the last row as I don't know how to continue from here.
Private Sub CommandButton1_Click()
Dim myValue As Variant
myValue = InputBox("Please insert number")
Range("A1").Select
ActiveCell.Value = myValue
Range(ActiveCell) = Range(ActiveCell) + 1
End Sub
All help is appreciated
Try with below code
Private Sub CommandButton1_Click()
Dim myValue As Variant
myValue = InputBox("Please insert number")
Range("A" & Range("A" & Rows.Count).End(xlUp).Row + 1) = myValue
End Sub
EDIT #1:
Updated the code as per the advice of user3598756
Private Sub CommandButton1_Click()
Dim myValue As Variant
myValue = InputBox("Please insert number")
If Range("A" & Range("A" & Rows.Count).End(xlUp).Row).Value = "" Then
Range("A" & Range("A" & Rows.Count).End(xlUp).Row) = myValue
Else
Range("A" & Range("A" & Rows.Count).End(xlUp).Row + 1) = myValue
End If
End Sub
edited to
shorten the code
add solution should cell "A1" be already filled with header
the following code will do:
Sub CommandButton1_Click()
With Cells(Rows.Count, 1).End(xlUp)
.Offset(IIf(.Value <> "", 1, 0)) = InputBox("Please insert number")
End With
End Sub
where the "conditional" offset is necessary to manage the first empty cell being in row 1 (no offset) or lower (1 row offset)
should cell "A1" be already filled with header, the code shortens down to:
Sub CommandButton1_Click()
Cells(Rows.Count, 1).End(xlUp).Offset(1) = InputBox("Please insert number")
End Sub
If you want to do a loop - for example 10 times - then you can use this example code:
Sub CommandButton1_Click()
Dim counter As Integer
Dim myValue As Variant
For counter = 1 To 10
myValue = InputBox("Please insert number")
Sheets("Sheet1").Cells(counter, 1).Value = myValue
Next counter
End Sub

Resources