I have a date in number form which looks like this: 20150529 is there a way to convert this into 29/05/2015 ?
I need to write a macro for this.
I have this code but it doesn't work:
Dim Current_Date As Date
Dim Date_String As String
Range("K2").Select
Date_String = Range("K2").Value
Current_Date = CDate(Date_String)
Range("Q2").Select
Range("Q2").Value = Current_Date
The Range.TextToColumns method can make quick work of one or more cells in a selection or an entire column of 20150629 like dates.
sub YMD_2_Date
with selection
.TextToColumns Destination:=.cells(1), DataType:=xlFixedWidth, _
FieldInfo:=Array(0, 5)
end with
end sub
The xlColumnDataType property of xlYMDFormat (e.g. 5) forces Excel to consider the number as Year-Month-Day.
This could be expanded from a selection (one or more cells in a single column) to multiple columns by cycling through them.
You have to rearrange your string in American format first (mm/dd/yyyy).
Then you can use CDate().
r = Mid(Date_String , 5, 2) & "/" & Right(Date_String , 2) & "/" & Left(Date_String , 4)
current_date = CDate(r)
This also works now
Range("K2", Range("K2").End(xlDown)).Select
For Each c In Selection.Cells
c.Value = DateSerial(Left(c.Value, 4), Mid(c.Value, 5, 2), Right(c.Value, 2))
'Following line added only to enforce the format.
c.NumberFormat = "mm/dd/yyyy"
Next
Related
I want to code something on VBA but I have no clue how to:
I have data with one column for the date (everyday from 1998 to today) and one column for the prices.
What I want to do is for every year, on the same day as today, show what was the price, on a different excel sheet.
For example : if today is 28/08/2018, I want to know what was the price on 28/08/2017, 28/08/2016,..., 28/08/1998.
Thanks a lot!
You could read the values into an array and loop that array. Compare if the 5 left characters of column 1 (dates) match the left 5 of today's date (returned with the Date function). Store qualifying values into a dictionary. Write the dictionary out to the a sheet at the end. You could also simply use:
If Format$(arr(i, 1), "dd/mm") = Format$(Date, "dd/mm") Then if dates.
Option Explicit
Public Sub test()
Dim arr(), i As Long, results As Object
Set results = CreateObject("Scripting.Dictionary")
With ThisWorkbook.Worksheets("Sheet1")
arr = .Range("A2:B" & .Cells(.Rows.Count, "A").End(xlUp).Row).Value '< read columns A and B into an array (Dates and Prices)
For i = LBound(arr, 1) To UBound(arr, 1) '< Loop the dates in the array (column 1)
If Left$(arr(i, 1), 5) = Left$(Date, 5) Then 'compare whether left 5 characters match i.e. same dd/mm irrespective of year
results(arr(i, 1)) = arr(i, 2) 'if match add the arr(i,1) date as key to dictionary; add the arr(i,2) price as the value associated with the key
End If
Next
End With
With ThisWorkbook.Worksheets("Sheet2")
.Range("A1").Resize(results.Count, 1) = Application.WorksheetFunction.Transpose(results.keys)
.Range("B1").Resize(results.Count, 1) = Application.WorksheetFunction.Transpose(results.items)
End With
End Sub
Here is an example of the comparison, if it were done in the sheet, showing a qualifying row. This comparison is done for every row which are stored in the array.
The dictionary, results, ends up having the qualifying row column A (date) as key, and column B (Price) as value.
You can access all the .Items or .Keys of the final dictionary producing an array in each case which can be tranposed to write to columns in the sheet.
Your dictionary will end up storing key value pairs of qualiying rows, a sample of which would look like:
Depending on formatting in sheet you might instead need:
If Format$(arr(i, 1), "dd/mm") = Format$(Date, "dd/mm") Then
Test run:
Not ideal but tried and it works, as long as the date and the target day is set to text:
Public Sub Test()
Dim i As Integer
i = 0
For Each c In ThisWorkbook.Sheets("Sheet1").Range("A1:A5")
If Left(c.Value, 6) = ThisWorkbook.Sheets("Sheet1").Range("D1:D1").Value Then
i = i + 1
ThisWorkbook.Sheets("Sheet1").Range("F" & i & ":F" & i).Value = c.Offset(0, 1).Value
End If
Next c
End Sub
For a VBA answer I would suggest something like:
Public Function GetPriceOnEachYear(source As Range, prices As Range) As Object()
Dim rng As Range
Dim answer() As Object
last = 0
For Each rng In source
If Month(rng.Value) = Month(Now) And Day(rng.Value) = Day(Now) Then
rowdiff = rng.Row - source.Row
columndiff = rng.Column - source.Column
ReDim Preserve answer(0 To last)
Set answer(last) = prices(rowdiff + 1, columndiff + 1)
last = last + 1
End If
Next rng
GetPriceOnEachYear = answer
End Function
I didn't do any type safety, and the answer is an array of ranges, if you would like only the value, then instead of Set answer(last) = prices(rowdiff + 1, columndiff + 1) you could use answer(last) = prices(rowdiff + 1, columndiff + 1).
I'm trying to extract the first 8 characters of a string while also inserting a "/" into the 8th character position using .FormulaR1C1. But, I don't think I have the concatenate function written quite right.
I need
MK442LLA-PB-3RC
to become
MK442LL/A
The R1C1 concatenate formula I used is as follows:
With Range("D2")
.FormulaR1C1 = "=CONCATENATE(LEFT(RC[-1], 7)""/""MID(RC[-1], 8, 1))"
.AutoFill Destination:=Range("D2:D" & lastRow)
End With
Note: I'm using Mid() instead of Right() because the initial numbers vary in length.
How about this instead of using '.FormulaR1C1'? Offset accordingly..
Sub concatFirstEight()
'last row
lastRow = range("D1048576").end(xlup).row
'set your range
Set concatRange = Range("D2:D" & lastRow)
'loop through range and add a "/" between the 7th and 8th character
For Each c In concatRange
c.Value = Mid(c, 1, 7) & "/" & Mid(c, 8, 1)
Next
End Sub
Ive a sheet which is generated using ADO select statement from another sheet. So I have to manually set some formatting. So here is the way I did.
With ThisWorkbook.Sheets("Invoice")
.Columns(1).Resize(.Rows.count - 1, 1).Offset(1, 0).NumberFormat = "yyyy-mmm"
.Columns(6).Resize(.Rows.count - 1, 1).Offset(1, 0).NumberFormat = "dd-mm-yyyy"
.Columns(10).Resize(.Rows.count - 1, 1).Offset(1, 0).NumberFormat = "0.00"
End With
Here column 1 and 6 am converting into two date formats. and column 10 I need to convert into Number format. But 1 and 6 converts fine. But 10 still showing as text and so alligned on left side. Screen grab disabled on our PC, otherwise I could share my actual screen. Hope its clear.
You need to parse it as General first using TextToColumns then apply your formatting. Something like below should work:
With .Columns(10).Resize(.Rows.count - 1, 1).Offset(1, 0)
.TextToColumns Destination:=.Range("A1"), DataType:=xlFixedWidth, _
FieldInfo:=Array(0, 1)
'DataType:=xlDelimited, _
'FieldInfo:=Array(1, 1)
.NumberFormat = "0.00"
End with
Or as #Whome commented, if it is all numbers, then you can simply:
With .Columns(10).Resize(.Rows.count - 1, 1).Offset(1, 0)
.Value2 = .Value2
.NumberFormat = "0.00"
End with
Edit1: Explained 1st code above. Using .Range("A1") as destination takes advantage of the Range.Range notation in Excel VBA. This means that you can re-index (not sure if this is the right term) a Range using Range Objects Range method. For example:
Dim r As Range: Set r = Range("B1:C10")
Debug.Print r.Range("A1").Address '/* this gives you $B$1 */
Degug.Print r.Range("B5").Address '/* this gives you $C$5 */
Illustration:
And applying that logic in your example:
.Columns(10).Resize(.Rows.count - 1, 1).Offset(1, 0) '/* refers to J2:J1048576 */
And Range("A1") of that range (or Cells(1) as Jeeped commented) is $J$2.
For your second inquiry, please refer to #Jeeped's comment:
"Sandeep brings up a valid point with his second inquiry. If you aren't going to force all delimiter parameters to false, perhaps DataType:=xlFixedWidth, FieldInfo:=Array(0, 1) would be better. You never know what has been left by the user in terms of TextToColumns delimiter(s) parameters."
The question is related to date & time. I was trying to create a macro in excel for editing the date column to change all the dates previously entered to the common format "dd/mm/yyyy". But when the date is separated using "." or "-" it is not being identified as a date. Tried replacing the separators to "/",and then the date was considered from right to left.
The macro I tried is as given below:
Sub Date_Edit()
Columns("C:C").Select
Selection.Insert Shift:=xlToRight
Sheets(1).Range("B1:B1000").Replace ".", "/"
For i = 2 To 1000
d = Cells(i, 2).Value
a = CDate(d)
Cells(i, 3) = FormatDateTime(d, 2)
Next i
Columns("C:C").Select
Selection.NumberFormat = "dd/mm/yyyy"
End Sub
I believe the problem is here:
d = Cells(i, 2).Value ' here you set d as the variable
a = CDate(d) ' at this point a is the current variable
Cells(i, 3) = FormatDateTime(d, 2) ' and here you use d again.
I think you need to replace the d with a in the FormatDateTime.
The CDate() converts a value to a date.
The FormateDateTime() needs a date-value to function. d is not a date-value.
The problem is that the standard format is "mm/dd/yyyy" not "dd/mm/yyyy". When you try and convert "dd/mm/yyyy" to a standard datevalue you have to swap the days and months.
This function will only handle date values.
Function FixDDMMYYYY(DateString As String) As Date
Dim arDateParts() As String
If InStr(DateString, ".") Then
arDateParts = Split(DateString, ".")
ElseIf InStr(DateString, "-") Then
arDateParts = Split(DateString, "-")
End If
On Error Resume Next
FixDDMMYYYY = DateSerial(arDateParts(2), arDateParts(1), arDateParts(0))
On Error GoTo 0
End Function
I have to add one month extra to the cell value date.
I have date in the cell i.e 201604. I need to add extra month to that date and have to use that data as a file name. example: sree 201605.xlsm
My code:
Sub vba()
Check_date = Worksheets("abc").Range("A2").Value
format_date = format(dateadd(check_date("m", 1), "yyyymm"))
end sub
can someone please answer me.
Consider:
Sub dural()
Dim n As Long, s As String, d As Date
n = Range("A1").Value
d = DateSerial(Left(n, 4), Right(n, 2) + 1, 1)
s = Format(d, "yyyymm") & ".xlsm"
MsgBox s
End Sub