Find row with date, active cell in fixed column, and write timestamp - excel

I want create a excel to record some times (enter to work, exit to dinner...). I tought the best way to do it is excel with vba code.
I put some bottons (like in photo I upload) to record some important times, and I create a table with days in month and events to record.
But, the problem is in vba code. I'm very inexpert in excel vba and only get this code:
Sub time()
ActiveCell.Value = Now
End Sub
In active cell, this code write timestamp.... But I want more advanced code. For example, I have button 'Enter to work', and I want when I press it:
Excel find row refers to today date
Find column 'Enter to work'
And write timestamp (hour:minute:second) in this cell
I don't know how to do this. Can anyone help me?

You can do something like below. First you will get the last row of your date than just use a loop to cycle through and compare the date on the sheet with the Now() function that returns today's date. Then you can use the offset to write the time to next cell. You can assign the macro to the buttons on the spredsheet and will be triggered each time. I guess you can put another if statement to check if there are values in the cell before attempting to write just to avoid overriding data. Note the date format on the sheet should be 14/05/2019.
Option Explicit
Sub FillInForm()
Dim WS As Worksheet
Dim i As Long
Dim LRow As Long
Dim dateFormatter As String
Dim xDate As Date
Set WS = ActiveSheet
dateFormatter = Format(Now, "dd/mm/yyyy")
xDate = CDate(dateFormatter)
With WS
LRow = .Range("B" & .Rows.Count).End(xlUp).Row
For i = 5 To LRow
If CDate(.Range("B" & i).value) = CDate(xDate) Then
If .Range("B" & i).Offset(0, 1).value = vbNullString Then
.Range("B" & i).Offset(0, 1).value = VBA.DateTime.Time
End If
End If
Next i
End With
End Sub

Related

How to add Date every day to my first blank row

I would like every day, when I open excel, that my excel would add a today's date to it. I have this code, but it isn't working, sometimes it does what it's supposed to and sometimes it skips a line, any help please?
Sub Stretching()
'This procedure will run each time you open the workbook
'Specify the required worksheet name in double quotes
Dim ws As Worksheet
Set ws = Sheets("Stretching")
'Get the last row number filled with a value in Column A
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
'Check if the last entered date is the same as the current date, if so, exit
'You need this check to see if you close the workbook then open it on the same day
'so that the code does not enter the same date again in a new row.
If ws.Cells(lastRow, 1).Value = Date Then Exit Sub
'Fill a new row in Column A with the current date
If IsEmpty(Cells(lastRow, 1)) Then
ws.Cells(lastRow, 1).Value = Date
Else
ws.Cells(lastRow, 1).Offset(1, 0).Value = Date
End If
End Sub
Some suggestions on your code:
Fully qualifying the ranges help you avoiding inconsistent results. This means, you can be running the procedure when an active sheet is different than the one you are targeting, and this line: Cells(Rows.Count, 1).End(xlUp).Row would return a different "last row" than the one you'd expect
Also try to use variable names that are easily understandable. For example, ws vs targetSheet
Please try this code and let me know if it works:
Public Sub Stretching()
'This procedure will run each time you open the workbook
'Specify the required worksheet name in double quotes
Dim targetSheet As Worksheet
Set targetSheet = ThisWorkbook.Sheets("Stretching")
'Get the last row number filled with a value in Column A
Dim lastRow As Long
lastRow = targetSheet.Cells(targetSheet.Rows.Count, 1).End(xlUp).Row
'Check if the last entered date is the same as the current date, if so, exit
'You need this check to see if you close the workbook then open it on the same day
'so that the code does not enter the same date again in a new row.
If targetSheet.Cells(lastRow, 1).Value = Date Then Exit Sub
'Fill a new row in Column A with the current date
If IsEmpty(targetSheet.Cells(lastRow, 1)) Then
targetSheet.Cells(lastRow, 1).Value = Date
Else
targetSheet.Cells(lastRow, 1).Offset(1, 0).Value = Date
End If
End Sub

Vlookup in vba to find values between two worksheets

I'm trying to grab the values from a different worksheet and match them to the their sister data in my main sheet in column A but I'm having issues with getting the right results, I was thinking of going the Vlookup route but I can't quite get it to work properly. I found a funky way of getting it done but I'm trying to save just the values and not the formula itself.
This is what I tried at first
Sub matchID()
'Dim wb As Workbook
'Set wb = ActiveWorkbook
'
'With wb.Sheets("Data")
' .Range("E2:E" & .Range("A" & .Rows.Count).End(xlUp).Row).Formula = "=VLOOKUP(A2,ID!A:B,2,FALSE)"
'End With
'the above works but need to save values and not formula
It kinda works but I need that values and not the formula, my plan is to find the data I need and then save a copy of the file as a csv
I tried using a different method but I'm running into runtime error '1004'
I'm still learning VBA so I feel like I'm spinning my wheels right now.
Can someone show me what I'm doing wrong?
Sub matchID()
'this is what I'm trying to get to work but unsure if I will still end up with formula and not just values
Dim result As String
Dim sheet As Worksheet
Dim lrow As Integer
Dim i As Integer
Set sheet = ActiveWorkbook.Sheets("Data")
lrow = sheet.UsedRange.Rows(sheet.UsedRange.Rows.Count).Row
For i = 2 To lrow
result = Application.WorksheetFunction.VLookup("A2", Sheets("ID").Range("A:B"), 2, False)
Cells(i, 5).Value = result
Next
End Sub
I'm trying to lookup all IDs(in column B) from my second sheet("ID") using the values in column A from my primary sheet("Data") and then populate the all results in column E in my primary sheet to their match.
My first try kinda worked but instead of leaving just the value it leaves the formula in the cell e.g. =VLOOKUP(A2,ID!A:B,2,FALSE) when really I'm looking for just the value 8447 that it shows before clicking on the cell.
If you want to get rid of the formula, just paste as values:
Sub matchID()
Dim wb As Workbook
Set wb = ActiveWorkbook
With wb.Sheets("Data")
.Range("E2:E" & .Range("A" & .Rows.Count).End(xlUp).Row).Formula = "=VLOOKUP(A2,ID!A:B,2,FALSE)"
.Range("E2:E" & .Range("A" & .Rows.Count).End(xlUp).Row).Value = .Range("E2:E" & .Range("A" & .Rows.Count).End(xlUp).Row).Value
End With
End Sub

How to Delete rows according to criteria in cells

I am trying to automate some date filtering for work.
I want to delete rows if they do not fall under this time stamp
2:00am - 10:00am
So if the time is before 2:00am or after 10:00am delete the entire row.
There are multiple rows like this.
I am not sure where to even start because I am very beginner and need an easy code to follow.
Here is what the data would look like
This is similar to this question here where I gave a similar answer. You can give this a try, though this assumes your times are in the 24 hour format and assumes you only want to delete that specific cell and not the entire row.
Sub TimeDelete()
'Declare your variables
Dim timeRng As Range, early As Long, late As Long, lrow As Long
'Finds the last row with a time in it in Column F
lrow = ThisWorkbook.Worksheets("Sheet1").Cells(Rows.Count, 6).End(xlUp).Row
'Define the times you want to compare against
early = "02:00:00"
late = "10:00:00"
'Specifies the range the times are in
Set timeRng = ThisWorkbook.Worksheets("Sheet1").Range(Cells(1,6), Cells(lrow,6))
'Use a For loop to check each value in the range
For Each Cell In timeRng.Cells
If TimeValue(Cell.Value) >= TimeValue(early) And TimeValue(Cell.Value) <= TimeValue(late) Then
Cell.Delete Shift:=xlToLeft 'Deletes cell if it meets the criteria and shifts remaining cells in the row to the left.
End If
Next Cell
End Sub
My VBA is a bit rusty, but this should work
Sub DelStuff()
Dim WB As Workbook
Dim Sheet As Worksheet
Set WB = ActiveWorkbook
Set Sheet = WB.ActiveSheet
For Each r In Sheet.UsedRange.Rows
If Cells(r.Row, "F").Value <= Date & " " & #2:00:00 AM# Or Cells(r.Row, "F").Value >= Date & " " & #10:00:00 AM# Then
r.EntireRow.Delete
End If
Next r
End Sub

How can I do a Calculation in Microsoft Excel VBA?

I'm 15 and I'm doing a Internship as a Developer and I've got a kinda hard exercise.
I have a Table with 3 columns, A is "Number" B is "percent" and C is "Value". The column "value" is blank and I Need to calculate the value with a macro button. I've tried this, but it was wrong because I didnĀ“t calculate it in VBA:
Public Sub PushButton ()
Range("C2:C11").Formula = "=A2*B2/100"
Range("C2:C11").Value = Range("C1:C6).Value
End Sub
How do I solve this?
You are using a defined range, you could do it with a dynamic range like this:
Option Explicit
Sub PushButton()
Dim i As Long, LastRow As Long
With ThisWorkbook.ActiveSheet
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row 'first you need to find the last row on the active sheet
For i = 2 To LastRow 'then iterate through all the rows starting from 2, if row 1 has headers
.Cells(i, 3) = .Cells(i, 1) * .Cells(i, 2) / 100
Next i
End With
End Sub
If you need help understanding this code, let me know.
Edit: Explanation
Well, the first thing you must do is Dimension all your variables, and to help that you can use the Option Explicitright above all your code.
I've dimensioned 1 variable for the loop and another one to find the last row with text.
To find the last row what you are actually doing is going to excel, select the last row (1048576) and the column where it will have text, in this case 1 or column "A" and then pushing ctrl+Up excel and vba will get you to the last cell with text.
To do that you use Cells(Row, column) instead of manually inserting row 1048576 you can just use rows.count and it will be the same.
Once you get the last row you just iterate with a For iloop meaning For a variable called i which equals 2 (For i = 2) To LastRow (to the last row you calculated) VBA will repeat the code in between the ForAnd Next adding 1 number to i everytime the loop restarts.
In this case is just adding a number to the rows on Cells(i, 3) so you can modify that cell depending of its i value.
I think you need to question why Excel needs to calculate on demand rather than automatically like normal. Failing that there are a few options
You could change your calculation method to Manual using the following in the ThisWorkbook object
Option Explicit
Dim xlCalcMethod As XlCalculation
Private Sub Workbook_Open()
With Application
' Store users current method for when closing the workbook
xlCalcMethod = .Calculation
.Calculation = xlCalculationManual
End With
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
' Reset calculation
Application.Calculation = xlCalcMethod
End Sub
and then when the button is pressed use the following code to calculate placed in a Module
Option Explicit
Public Sub Button_Click()
Application.Calculate
End Sub
Another option to do this without looping would be:
Sub CalculateRange()
Dim rng As Range
' Update for your Range
With ActiveSheet
Set rng = .Range("C2:C" & .Cells(.Rows.Count, "A").End(xlUp).Row)
End With
rng.Value2 = Evaluate(rng.Offset(0, -2).Address & "*" & rng.Offset(0, -1).Address & "/100")
End Sub
Finally, the way you've come up with is perfectly acceptable as VBA

Using a Loop to count number of days between TODAY() and date in a cell in VBA

Semi-new to VBA but need help. I have the following code that I am trying to convert into a loop to provide the number of days between today's date and a date found in column A. The number of rows can change based on data entered and want it to stop when the cell in column A is blank. I also want only the value to appear. Any help is greatly appreciated. The below works great for the first row. I believe the loop should appear on row 2 but don't know how to go about it. Thank you in advance.
Range(ActiveSheet.Range("E2"), ActiveSheet.Range("E2").End(xlDown).Select
ActiveCell.FormulaR1C1 = "=SUM(TODAY()-OFFSET(R2C1,0,0,COUNTA(c[-4]),1))"
ActiveCell.Value = ActiveCell.Value
You do not need a loop for this. This will determine the used range in Column A and apply the formula (but only paste value) in the same used range down Column E
Also, notice that you do not need to use .Select, .Active, or .Selection. here. Directly qualify your ranges and you will save yourself trouble down the road. For learning purposes, it is best to act like those lines do not exist :)
Sub DateDif()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim LRow As Long: LRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
With ws.Range("E2:E" & LRow)
.Formula = "=NOW() - A2"
.Value = .Value 'If you want the formula to remain, remove this line
End With
End Sub

Resources