I've had a look around and can't find an actual answer to this.
I have a .csv to download every day. In it includes a text field 7+2 digits long. The 7 digits are in format CYYMMDD and the 2 digits are blank spaces.
This would be today's date: "1190729 " (without the quotes)
I've tried about 20 ways to convert this to a regular date, but I can't get every record to update properly
So far
The QueryTable uses type 2 (Text)
I =TRIM the text, place it back in the same location
I change the text into a recognisable date
"Paste as Text"
Then I get the same thing every time. Any date where the DAY is 13 or more, is a text field. 12 and under is a date field
The best way to fix it is to F2 but this is meant to be a totally automated report
I have tried changing dd/mm/yyyy to every other version I can think of (as for my excel m/d/yyyy is the default)
I've also tried moving .Value = .Value to the bottom, putting it in twice etc. but to no avail
Private Sub CopyDateTime(ByVal lastRowBeforeImport As Long)
Dim ws As Worksheet, ws2 As Worksheet
Dim tempsheet As String
Dim lastRowAfterImport, lastRowTemp
Set ws = Worksheets("Report")
'Bottom populated cell of Column "B"
lastRowAfterImport = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
tempsheet = "temp"
Worksheets.Add
ActiveSheet.Name = tempsheet
Set ws2 = Worksheets("temp")
With ws.Range(ws.Cells(lastRowBeforeImport, 5), ws.Cells(lastRowAfterImport, 6))
'Copy new date and time to tempsheet'
.Copy Destination:=ws2.Range("A1")
End With
lastRowTemp = ws.Cells(ws.Rows.Count, 3).End(xlUp).Row
With ws2.Range(Cells(1, 3), Cells(lastRowTemp, 3))
.FormulaR1C1 = "=TRIM(RC[-2])"
.Value = .Value
.Copy Destination:=ws2.Range("A1")
.Delete
End With
With ws2.Range(Cells(1, 3), Cells(lastRowTemp, 3))
.FormulaR1C1 = "=RIGHT(RC[-2],2)&""/""&MID(RC[-2],4,2)&""/20""&MID(RC[-2],2,2)"
.Value = .Value
.NumberFormat = "dd/mm/yyyy"
End With
With ws2.Cells(1, 4)
.FormulaR1C1 = "=MID(TEXT(RC[-2],""000000""),3,2)&"":""&LEFT(TEXT(RC[-2],""000000""),2)&"":""&RIGHT(RC[-2],2)"
End With
'Delete tempsheet'
Application.DisplayAlerts = False
'Worksheets(tempsheet).Delete
Application.DisplayAlerts = True
End Sub
If you have "1190729 " in A2 then the formula
=DATE(2000+(MID(A2,2,2)),(MID(A2,4,2)),(RIGHT(TRIM(A2),2)))
will produce the date 29th July 2019 in your current date format
From MSDN:
Date variables are stored as IEEE 64-bit (8-byte) floating-point
numbers that represent dates ranging from 1 January 100, to 31
December 9999, and times from 0:00:00 to 23:59:59.
Your VBA function may parse well string formats from CSV, but you are creating a string value which is not a proper Excel data type for dates.
Use =DATEVALUE function to convert the string representation of the DATE (ex. 29/7/2019) to the actual Excel date.
For example in your case: cell.Value = DATEVALUE(TRIM(RC[-2]))
Once in the proper data type, you can change the date format using the NumberFormat property.
More about DATEVALUE from MSDN.
Related
I have a data field that is on the worksheet as a custom number format
geo:
[![![data column example][1]][1]
sum:[![![data column example][2]][2]
I am taking that field and comparing it to wo other fields on another worksheet to determine if this one is in between those. So I've got the below code that uses variants for the arrays and splits along spaces. I think the best way is to use the datevalue and timevalue functions with inequalities, both of which take strings. any ideas why I'm getting a type mismatch error at the split?
UPDATE: Based on the #### comment, and the column reference mistake, I autosized the dateTime co and changed my column references. Now my sumfull string gets the text of the column. I am still getting a type match error on the next line. I've updated the code below. The code breaks at sumsplit = Split(sumfull, " ") with a Type mismatch error. The contents of .Cells(i.row, 4).text is "01/23/2022 18:53". This is also the value of sumfill when it breaks.
Option Explicit
Sub O_face()
Dim geo As Workbook
Dim sum As Workbook
Dim geowks As Worksheet
Dim sumwks As Worksheet
Dim i As Variant
Dim j As Variant
Dim lastrow As Long
Dim georng As Range
Dim sumrng As Range
Dim geofull As Date
Dim sumfull As Date
Dim sumfull2 As Date
Set geo = ThisWorkbook
Set sum = Workbooks.Open("MyFile.csv")
Set geowks = geo.Workshets(1)
geowks.Range("B:B").EntireColumn.AutoFit
Set sumwks = sum.Worksheets(1)
sumwks.Range("F:G").EntireColumn.AutoFit
lastrow = geowks.Cells(Rows.Count, "a").End(xlUp).Row
geowks.AutoFilterMode = False
geowks.Range("A1:L" & lastrow).AutoFilter Field:=5, Criteria1:="<>", Operator:=xlFilterValues
Set georng = geowks.Range("E2:E" & lastrow).SpecialCells(xlCellTypeVisible)
lastrow = sumwks.Cells(Rows.Count, "a").End(xlUp).Row
sumwks.AutoFilterMode = False
sumwks.Range("A1:P" & lastrow).AutoFilter Field:=3, Criteria1:="<>", Operator:=xlFilterValues
Set sumrng = sumwks.Range("C2:C" & lastrow).SpecialCells(xlCellTypeVisible)
'have to split the date time cell because it's a custome data type in the worksheet. Then compare the date and time seperately.....
For i = 1 To sumrng.Rows.Count
sumfull = sumrng.Cells(i, 4)
sumfull2 = sumrng.Cells(i, 5)
For j = 1 To georng.Rows.Count
geofull = georng.Cells(j, -2)
If sumrng(i, 1) = georng(j, 1) And _
geofull >= sumfull And geofull >= sumfull2 Then
sumrng.Cells(i, 15) = "IS THIS WHAT YOU WANT!!!!"
End If
End If
Next j
Next i
End Sub
(a)
Split returns an array of strings. You can assign the result to a dynamic String-Array or to a Variant-Variable, see https://stackoverflow.com/a/57113178/7599798 . What you try to do is assign it to a Variant Array - this will fail. You also don't need to set the dimensions of that array, split will take care about that anyhow. So that would be:
Dim sumsplit() As String
sumfull = CStr(sumrng.Cells(i.Row, "f").Text)
sumsplit = Split(sumfull)
(b)
Assuming that your data in Excel are Dates (not Strings that look like a Date), there is neither a reason to convert them to a string nor split that string to get the date and time part. Just use Date variables. In the background, Dates are Floating point Numbers (=Double). The number before the decimal defines the Date-Part (Days since 31.12.1899), the remainder the Time. To get Date and Time of an Excel-Date:
Dim sumfull As Date, fsumdate As Date, fsumtime As Date
sumfull = sumrng.Cells(i.Row, "f").value
fsumdate = int(sumfull) ' Remove the digits after the decimal
fsumtime = sumFull-int(sumfull) ' The digits after the decimal is the Time.
(c) I don't fully understand the logic of your If-statement, but you can simply compare date variables with < and > - a higher number means a later date/time. I assume that you will not need to compare date and time parts separately. Probably this will do:
Dim geoDate As Date, fsumDate As Date, lSumDate As Date
fsumDate = sumrng.Cells(i.Row, "f").value
lsumDate = sumrng.Cells(i.Row, "g").value
geoDate = georng.Cells(j.Row, "b").value
If geodate >= fsumdate And geodate <= lsumdate Then
(d)
Generally, you should avoid using the Text-property. If for any reason the width of a cell is too small to display the date, Excel will display "######" instead - and you will get exact this into your program.
I have a spreadsheet with many columns for each month in the project timeline and each header is in mmm-YY format (like May-20 for 5/1/2020). I'd like to add some more features that act on date values, but when I use DATEVALUE on a cell that has a value of 'May-20', it calculates to "5/20/2021". I believe I have the cell format for the headers correctly set to Number>Date>Mon-Year style, so I'm not sure why excel is misinterpreting the header values.
Is there a way I can get excel to recognize that "May-20" means 05/01/2020?
Use:
=--("1-"&A1)
Where your text is in A1.
You can format the cells as Custom Format --> mmm-yy It will appear as May-20 in the cell, but will have the value 5/20/20 (I'm assuming the day doesn't matter here).
This will however mess up your existing dates. If you need to get them to the proper values you can use this:
Dim i As Long
Dim lr As Long
Dim mth As String
Dim yr As String
With ActiveSheet 'Use a real sheet name
lr = .Cells(.Rows.Count, 2).End(xlUp).Row 'I used column B here
For i = 1 To lr
mth = Split(.Cells(i, 2).Value, "-")(0) 'I used column B here
yr = Split(.Cells(i, 2).Value, "-")(1)'I used column B here
Cells(i, 2).Value = DateValue("01 " & mth & " " & yr) 'I used column B here
Next i
End With
You may want to test it first by not modifying in place.
I want to convert a date in a cell to the date function so it is a formula. How do I get the date (using VBA), any date, say, 13 Jun 2020 to =DATE(2020, 6, 13) using variables for the year, month, and day. My code I have tried but won't work. The activecell shows 13-Jun-2020 as a date but appears in the function box as 13/06/2020
Sub ConvertDateToDateFunction()
Dim mvDay, mvMth, mvYr As Integer
mvDay = Left(ActiveCell, 2)
mvMth = Mid(ActiveCell, 4, 2)
mvYr = Right(ActiveCell, 4)
ActiveCell.Value = "=DATE(mvYr, mvMth, mvDay)"
End Sub
You have two problems. Here is the solution to the smaller one. The code below would do what you intend. It would convert a text string in the ActiveCell to a function of similar value and insert it in the cell below the ActiveCell.
Sub ConvertDateToDateFunction()
' if you don't say what it's supposed to be it'll be a Variant
Dim mvDay As String, mvMth As String, mvYr As String
mvDay = Left(ActiveCell.Value, 2)
mvMth = Mid(ActiveCell.Value, 4, 2)
mvYr = Right(ActiveCell.Value, 4)
ActiveCell.Offset(1).Formula = "=DATE(" & mvYr & "," & mvMth & "," & mvDay & ")"
End Sub
It's not entirely easy to insert a date as a text string in Excel because Excel will try to recognize a date for a date. Observe that any part of a string is a string, not an integer.
Now about your much bigger problem which is that you don't understand how Excel handles dates. It is such a big problem because you are trying to create a date in Excel in various ways and you run into all sorts of trouble. Read up on the subject here.
To give you a taste of what you will learn: what you see displayed in a cell isn't what the cell contains. There might be a formula in it and you see a number. And there might be a date and you see a string. What you see is determined by the cell's format. I think Chip Pearson's article will cover that topic. If you need to know more, look for "Cell formatting" on the web.
Your macro won't work because the date is a "real date" and not a string.
Try the following to convert the contents of cells containing a real date to a formula which will return the same date:
Option Explicit
Sub dtToFormula()
Dim R As Range, C As Range
Dim vDateParts(2)
Set R = [a1:a10]
'Set R = ActiveCell 'or Selection whatever range you want to convert
For Each C In R
If IsDate(C) And Not C.HasFormula Then
vDateParts(0) = Year(C.Value2)
vDateParts(1) = Month(C.Value2)
vDateParts(2) = Day(C.Value2)
C.Formula = "=DATE(" & Join(vDateParts, ",") & ")"
End If
Next C
End Sub
I have a sheet with tens of thousands of dates in the following format :-
31.01.2018 (so, dd.mm.yyyy)
The cell format of each of these is General. I need to convert each of these to UK date format.
To do so, I am using :-
With ThisWorkbook.Worksheets("Report")
For i = 2 To Lastrow
DateString = .Range("J" & i).Value
Year = Right(DateString , 4)
Month = Mid(DateString , 4, 2)
Day = Left(DateString , 2)
With .Range("J" & i)
.Value = CDate(Day & "/" & Month & "/" & Year)
.NumberFormat = "dd/mm/yyyy"
End With
Next i
End With
This takes quite a while, and I wanted to know if there was a more effective way of converting the dates?
If i understand correctly and I am not missing something, you don't need VBA to do that.
Just select column J and find and replace . with /.
If you want to do it using VBA anyway, you can do this:
Sub test()
Dim sht As Worksheet
Dim rng As Range
Set sht = ThisWorkbook.Worksheets("Report")
Set rng = sht.Columns("J")
rng.Replace what:=".", replacement:="/"
End Sub
It takes less than a second to execute for around 10k dates.
EDIT:
When it's done the values will be recognized by excel as dates.
The format of these dates can be set to the European one. Select column J press CTRL+1, in the Number tab, under Category choose Date and set it to European format.
Or simply add this line to he code above:
rng.NumberFormat = "dd/mm/yyyy"
I was able to resolve this using the answer supplied here :-
https://stackoverflow.com/a/30609676/1936588
Changing
.TextToColumns Destination:=.Cells(1), DataType:=xlFixedWidth, FieldInfo:=Array(0, xlYMDFormat)
To
.TextToColumns Destination:=.Cells(1), DataType:=xlFixedWidth, FieldInfo:=Array(0, xlDMYFormat)
An often asked question, when I search the internet, but none of the answers seem to fit my problem. I hope you can help.
I am trying to collect dates from a DB, using code:
Sheets("Data").Select
Dim sh1 As Worksheet
Set sh1 = ActiveWorkbook.ActiveSheet
sh1.Activate
If ActiveSheet.FilterMode Then
Range("ActivityPlan[[#Headers],[AIDA]]").Select
ActiveSheet.ShowAllData
End If
Dim lLastRow As Long
'Get Last row
lLastRow = sh1.Range("C" & Rows.Count).End(xlUp).Row
And having defined my values using the type of the three following examples
If Not sh1.Cells(i, 19) = "" Then
tMaintSimulStartDate = Format(sh1.Cells(i, 19), "MM/dd/yyyy")
End If
tMaintExpDate = Format(sh1.Cells(i, 20), "MM/dd/yyyy")
If Not sh1.Cells(i, 21) = "" Then
tUpBaseDteFix = Format(sh1.Cells(i, 21), "MM/dd/yyyy")
Else
tUpBaseDteFix = vbNull
End If
None of them seem to work. I just get the error "conversion failed when converting date and/or time from character string", VBA marking my " CN.Execute (SQL) "
I think it's very likely that the values in your cells sh1.cells(i,19), (i, 20), (i,21) are just strings. They may look like dates, but Excel doesn't recognize them as such.
Your best bet is to use DateValue() function in VBA. This will take in a string and spit out an actual, honest to goodness date. If this fails, it's because your Date format in the cell is something that DateValue() can't recognize. In which case you'll probably have to parse out the values of the date from the cell and then send it over to DateValue() to turned into a proper date.