Excel (2003) - Automatic insert date on a cell - excel

I don't really know if this is a programming question, but I am sure one of you can easily help me with this one.
I am trying to create a automatic "inserted date" function inside excel. i.e. When a person inputs data in a row in my excel document I want another cell to automatically show the date of insertion.
Standing inside the cell i am trying to show the date, I've written the following:
=IF(ISBLANK(C20);1;TODAY())
This works great, until I open it the day after. Clearly it will set the date to "TODAY", but if I want it to only update once, at the time of the insertion - how would I do that?
Thinking something like this (Java - pseudo).
IF(!OTHER.CELL.ISBLANK() && THIS.CELL.ISBLANK()){
THIS.CELL = TODAY();
}
Now, how to do that in Excel?
Thanks in advance.

You would use the Worksheet_Change Event
Right click your sheet tab
View - Code
Copy and Paste in the code below
This code
tracks and change made to column C of the Activesheet
puts in the current data and user logon name to each corresponding cell in column D
Only changed column C cells are captured as specified in this line
Set rng1 = Intersect(Range("C:C"), Target)
The Application.EnableEvents = False is used to stop the code refiring when column D is writing to
You could easily adapt this to
1) write to a different (perhaps hidden) log sheet
2) write to a text file instead
Pls let me know if you want any updates
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng1 As Range
Set rng1 = Intersect(Range("C:C"), Target)
If rng1 Is Nothing Then Exit Sub
Application.EnableEvents = False
rng1.Offset(0, 1).Value = Now() & " - " & Environ("username")
Application.EnableEvents = True
End Sub

Related

VBA Excel: Write timestamp to cell on change of another cell

I want to insert a timestamp (E3) when the status (B3) changes. This should happen for at least 30 more such examples in the worksheet. The code currently works only for one example (Country1). Do you have an idea how this can be implemented?
I already tried different types but it just worked for example "Country 1" not for "Country 1", "Country 2", "Country 3" etc.
When I adjust the code for the range "B3:I3" then I received an adjustment in every 3rd column, example: I add a comment in D3 then a timestamp will be created in H3. That is not what I want. :(
Is there a way to adjust the code so that as soon as a change is made in the Status column (B3;F3;J3etc.), the Timestamp column (E3;I3 etc.) will reflect the time stamp?
Code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("B3:B5"))
Is Nothing Then Exit Sub
Application.EnableEvents = False
Target.Offset(0,3).Value = Now
Application.EnableEvents = True
Please, try the next adapted event. It will calculate how many groups of four columns exists and set a range of their first column intersected with rows 3 to 5. Only for this range the event will be triggered:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim lastCol As Long, rngCols As Range
lastCol = Me.cells(2, Me.Columns.count).End(xlToLeft).column 'last column on the second row
Set rngCols = Me.Range(trigData(Me.Range("B2", Me.cells(2, lastCol)))) 'create the range of the columns for what the event to be triggered
Set rngCols = Intersect(Me.rows("3:5"), rngCols) 'create the range inside which the change to trigger the event
If Not Intersect(rngCols, Target) Is Nothing Then
Application.EnableEvents = False
Target.Offset(0, 3).Value = Now
Application.EnableEvents = True
End If
End Sub
Function trigData(rngCols As Range) As String
Dim i As Long, strCols As String
For i = 1 To rngCols.Columns.count Step 4 'iterate from four to four and create the necessary columns string address
strCols = strCols & "," & rngCols.cells(i).EntireColumn.address
Next i
trigData = Mid(strCols, 2) 'Mid eliminates the first (unnecessary) comma...
End Function
The code will be confused if you place on the second row data after the necessary groups of four columns. If necessary, one or two such columns, the code can be adapted to work for a fix number extracting the divided integer (without decimals).
The code assumes that you need to be triggered for the mentioned rows (3 to 5). If you need something different in terms of rows to be affected, you should change Me.rows("3:5") according to your need.
Please, send some feedback after testing it.
Your request is a little unclear, and your table format may not have come across correctly in your post. Your code is written to add the current time to a cell 3 columns away from the target cell. It is dynamic, so if you set
If Intersect(Target, Range("B2:I3"))
You are going to get the value in cell 3 columns offset from the changed cell. If you always want it to update column E, then you can use the target.row property...
Cells(Target.Row,5).Value = Now
...to make the row dynamic, and the column static. Clarify your question if this is not what you're looking for. If country2 is in cell F2, where do you want to write the timestamp?
You can use this simple function:
Public Function TimeStamp(Status As Range) As Double
TimeStamp = Now
End Function
So, in Cell E3 will be the formula =TimeStamp(B3). (Format cell E3 appropriately as Time Format)

Filtering all but todays date

I'm trying to filter out all but todays date using a macro (for the first time)
I want to create a macro or two that will show only rows using the date in which it's viewed. I've tried using the below, but it hides all rows containing a date
Dim cell As Range
For Each cell In Range("A10:A1000")
If cell.Value <= Date Then
cell.EntireRow.Hidden = False
End If
Next
End Sub
Basically you don't need VBA to achieve this: you could use the filter functionality of Excel.
But if you want to do it via VBA this is a routine that does what you want:
Option Explicit
Public Sub hideRowsIfNotDate(rgToCheckDate As Range, dateToBeVisible As Date)
Dim c As Range
For Each c In rgToCheckDate.Cells
If IsDate(c.Value) Then 'just to be on the safe side if there is no date
If c.Value <> dateToBeVisible Then
'hide rows with different date
c.EntireRow.Hidden = True
Else
'show rows that match the date - just in case they were hidden before
c.EntireRow.Hidden = False
End If
End If
Next
End Sub
Advantage of this solution:
you can pass different dates or ranges, therefore you can reuse the sub for different scenarios
when you call the sub from your main code you simply know by reading the subs name what it is doing (w/o reading the code itself) - someone else (or you in 3 months) will appreciate that :-)
You will call the routine from your main code like this:
Public Sub test_hideRows()
Dim dateToBeVisible As Date
dateToBeVisible = Date '= today
Dim rgToCheck As Range
Set rgToCheck = ActiveSheet.Range("A10:A1000")
hideRowsIfNotDate rgToCheck, Date
End Sub
Have you tried AutoFilter? I assume that your data are stored in Rows("10:1000"), dates - in the column A and you have some headers in Rows(9). With that in mind:
Set Source = Rows("9:1000")
Field = Range("A:A").Column
Value = Format(Date, Range("A10").NumberFormatLocal)
Source.AutoFilter Field, Value
If you have a custom date format, put that instead of ...NumberFormatLocal

In Excel, how do I have a line of code check what the value of a dropdown selection is. Then, how do I check that value vs another value

I am trying to create a macro that will first allow the user to easily transfer data to another sheet based on a dropdown list to select the month. I want the user to able to enter the date in the field I have created, then use buttons on the sheet to first select which month to paste though, then confirm the paste. I have twelve named ranges from Ref_Jan to Ref_Dec on a sheet named "DB - Ref Monthly" I am working on putting together the pieces but I'm stuck here with my test program:
Sub Button8_Click()
Dim MonthSelector As Range
Dim Ref_May As Range
If Range("MonthSelector") = Range("Ref_May") Then
Sheets("DB - Ref Current").Range("Ref_Current").Copy
Sheets("DB - Ref Monthly").Range("Ref_May").PasteSpecial xlPasteAll
Application.CutCopyMode = False
Application.ScreenUpdating = True
Else
End If
End Sub
My current plan is to use 12 if statements to refer to each month, as I already have the copy/paste portion of the code working in another sheet. If I am going about this all wrong I would not mind some guidance. Please let me know if I have been unclear and can provide additional information.
Use looping to iterate months then no need to duplicate a code logic.
Dim arrMonth As New Collection
Dim idx As Integer
Dim val As String
Call arrMonth.Add("Jan")
Call arrMonth.Add("Feb")
Call arrMonth.Add("Mar")
'..etc..
Call arrMonth.Add("Dec")
For idx = 1 To arrMonth.Count
val = arrMonth.Item(idx)
Call MsgBox(idx & "=" & val)
Next
Assuming Range("MonthSelector") is a cell that has a value from a list of months (Jan, Feb, Mar, etc.), and you've got corresponding named ranges Ref_Jan, Ref_Feb, Ref_Mar, etc., you could just do this:
Sub Button8_Click()
Sheets("DB - Ref Current").Range("Ref_Current").Copy
Sheets("DB - Ref Monthly").Range("Ref_" & Range("MonthSelector").Value).PasteSpecial xlPasteAll
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub

Date function without updating according to current date on recalculation

ENTRY DATE DES AMOUNT
1-Oct-14 A 100
3-Oct-14 B 50
4-Oct-14 M 25
8-Oct-14 F 25
i have formatted entry date column by used this function:
=IF(B2&C2="", " ", TODAY())
The problem is once i make a new entry each entry date is updated automatically according to current date. so I wanted previous entry date should not be changed
If you've reviewed the article noted above you should have a good idea of what is required for generating a static date/time stamp into your input worksheet. Here is an example that will survive copying many values into columns B & C as well as controlling any errors that might arise.
To incorporate this into your input worksheet right-click the worksheet's name tab at the bottom and choose View Code. When the VBE opens, paste the following into the pane titled something like Book1 - Sheet1 - (Code).
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Columns("B:C")) Is Nothing Then
On Error GoTo FallThrough
Application.EnableEvents = False
Dim t As Range
For Each t In Intersect(Target, Columns("B:C"))
If Application.IsText(Cells(t.Row, 2)) And _
IsNumeric(Cells(t.Row, 3)) And Not IsEmpty(Cells(t.Row, 3)) Then
Cells(t.Row, 2) = UCase(Cells(t.Row, 2).Value)
Cells(t.Row, 1) = Date
'Cells(t.Row, 1) = now
Else
Cells(t.Row, 1).ClearContents
End If
Next t
End If
FallThrough:
Application.EnableEvents = True
End Sub
Tap Alt+Q to return to your worksheet. You can commence inputting DES and Amount values immediately.
I've included a commented line that puts the date and time into column A rather than just the date. If you choose to use it (remove the single quote), remove the line above it that only puts hte date in.

Enter value in cell, have display value result of formula

I'm sure there's a very easy answer to this (and I don't know that I have the excel chops to ask the "right" question, or google would give me the answer).
I have the following formula:
=DATE(YEAR(V1), MONTH(V1)+V2-1,8)
I'd like to be able to enter a number into a cell (say, 14) and have that formula run, except the number that I enter into the cell should replace the number 8 in the formula. So, again, entering 14, the formula that would execute would be:
=DATE(YEAR(V1), MONTH(V1)+V2-1, 14)
So to recap, the workflow is this:
I enter the value '14' into cell A3.
The above formula is executed
The displayed value of A3 is something like 3/14/2012 (depending on my V1/V2 cell values)
Can I do this without VBA? (I'm a .NET programmer by trade, so VBA isn't foreign to me, I just feel like Excel should be able to do this native without code).
No - because you are transferring a value in A3 via a formula into a new value within A3.
The code below will update A1:A5 when any of these cells are changed (all 5 if all are changed at once) with the result you ask for
right click your sheet tab
View Code
Copy and paste the code below
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng1 As Range
Dim rng2 As Range
Set rng1 = Intersect(Range("a1:A5"), Target)
If rng1 Is Nothing Then Exit Sub
Application.EnableEvents = False
For Each rng2 In rng1
rng2.Value = Format(Evaluate("DATE(YEAR(V1), MONTH(V1)+V2-1," & CLng(rng2.Value) & ")"), "mm/dd/yyyy")
Next rng2
Application.EnableEvents = True
End Sub

Resources