Getting DATEVALUE from Dates in mmm-YY format - excel

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.

Related

taking a Custom Number field to Split String giving type mismatch

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.

Convert date to Date Function

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

Date Field Mixed (Date and Text) Formatting

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.

Generate serial numbers and barcodes as per logic defined based on the count mention in certain cell

I need to generate lot numbers for my products and since my software doesn't auto generate them, I have defined a logic in Excel for the same. It is quite basic and combines data in 2 or more cells to create a unique code.
To be more specific, I shall introduce our operations to you. We have a few collection centers for our products and we require them to apply lot number labels onto their bags of coffee before transferring it to our main warehouse. I have created an excel sheet in which I enter the current date in one cell and select the name of the center in another which then generates a lot number for the same. For example, cell A1 has today's date and A2 has center 'MBR' selected. The formula in cell C2 =IF(A2="MBR","MB:"&TEXT(A1,"YYYYMMDD")&"-001",IF(A2="MAY","AY:"&TEXT(A1,"YYYYMMDD")&"-001",IF(A2="MZM","MM:"&TEXT(A1,"YYYYMMDD")&"-001",""))) shall give me a result as MB:20171010-001
Now comes the tricky part. I want to mention in cell A3 the number of lots to be generated. For example, if I say I want 10 labels, then the formula should give me 10 labels from "-001" to "-010." If possible, it could start with the number which I would define in possibly cell A4 and then give me the sequence as required.
Lastly, I use this info to generate barcodes using an add-on in excel which I downloaded from the internet which converts the text into barcodes and then I can print them. I have tried barcode fonts but they don't work at all. If you have another alternative to this where I could generate sequential lot numbers based on the logic defined and create barcodes for the same, please share it with me. If not, please give me a formula which will work with excel.
Enter your data in columns A - C, run the bit of sample code below, result is in column D. You can modify the code to suit your needs but here is a start for you:
Public Sub RunTags()
Dim oWS As Worksheet
Dim lRow As Long
Dim lNextTagRow As Long
Set oWS = Worksheets("Sheet1")
lRow = 2
lNextTagRow = 2
Do Until oWS.Range("A" & lRow) = ""
Select Case oWS.Range("A" & lRow)
Case "MBR"
PrintTags oWS, lNextTagRow, "MB:", oWS.Range("B" & lRow), oWS.Range("C" & lRow)
Case "MAY"
PrintTags oWS, lNextTagRow, "MA:", oWS.Range("B" & lRow), oWS.Range("C" & lRow)
Case "MZM"
PrintTags oWS, lNextTagRow, "MZ:", oWS.Range("B" & lRow), oWS.Range("C" & lRow)
End Select
lRow = lRow + 1
Loop
End Sub
.
Private Sub PrintTags(ByRef oWS As Worksheet, ByRef lTagRowStart As Long, sPrefix As String, lQty As Long, lStart As Long)
Dim x As Long
Dim dtNow As Date
dtNow = Now()
For x = lStart To lStart + lQty - 1
oWS.Range("D" & lTagRowStart) = sPrefix & Format(dtNow, "YYYYMMDD") & "-" & Format(x, "000")
lTagRowStart = lTagRowStart + 1
Next x
End Sub

Create new Excel rows based on column data

Good afternoon all,
I have an issue where I have users who have multiple bank account details. I need to try and create a new row for each employee who has more than one bank account, with the second bank account being allocated a new row.
Employee Number User ID BSB Account number
10000591 WOODSP0 306089,116879 343509,041145273
10000592 THOMSOS0 037125 317166
I need it to look something like this:
Employee Number User ID BSB Account number
10000591 WOODSP0 306089 343509
10000591 WOODSP0 116879 041145273
10000592 THOMSOS0 037125 317166
Any thoughts? Your input is greatly appreciated!
Screenshots are here to demonstrate:
Right click on the tab and choose "View Code"
Paste this code in:
Sub SplitOnAccount()
Dim X As Long, Y As Long, EmpNo As String, UserID As String, BSB As Variant, AccNo As Variant
Range("F1:I1") = Application.Transpose(Application.Transpose(Array(Range("A1:D1"))))
For X = 2 To Range("A" & Rows.Count).End(xlUp).Row
EmpNo = Range("A" & X).Text
UserID = Range("B" & X).Text
BSB = Split(Range("C" & X).Text, ",")
AccNo = Split(Range("D" & X).Text, ",")
For Y = LBound(AccNo) To UBound(AccNo)
Range("F" & Range("F" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = EmpNo
Range("G" & Range("G" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = UserID
Range("H" & Range("H" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = BSB(Y)
Range("I" & Range("I" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = AccNo(Y)
Next
Next
End Sub
Close the window to go back to excel
Press ALT-F8
Choose SplitOnAccount and click run.
Note, this is going to populate the split data to rows F to I, make sure there is nothing in there. If there is post back and we can change it.
Also format columns F - I as text before you run it or Excel will strip leading zeros off as it will interpret it as a number.
Here is another sub that appears to perform what you are looking for.
Sub stack_accounts()
Dim rw As Long, b As Long
Dim vVALs As Variant, vBSBs As Variant, vACTs As Variant
With ActiveSheet '<-define this worksheet properly!
For rw = .Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
vVALs = .Cells(rw, 1).Resize(1, 4).Value
vBSBs = Split(vVALs(1, 3), Chr(44))
vACTs = Split(vVALs(1, 4), Chr(44))
If UBound(vBSBs) = UBound(vBSBs) Then
For b = UBound(vBSBs) To LBound(vBSBs) Step -1
If b > LBound(vBSBs) Then _
.Rows(rw + 1).Insert
.Cells(rw - (b > LBound(vBSBs)), 1).Resize(1, 4) = vVALs
.Cells(rw - (b > LBound(vBSBs)), 3).Resize(1, 2).NumberFormat = "#"
.Cells(rw - (b > LBound(vBSBs)), 3) = CStr(vBSBs(b))
.Cells(rw - (b > LBound(vBSBs)), 4) = CStr(vACTs(b))
Next b
End If
Next rw
End With
End Sub
I was originally only going to process the rows that had comma delimited values in columns C and D but I thought that processing all of them would allow the macro to set the Text number format and get rid of the Number as text error warnings and keep the leading zero in 041145273.
        
You Can definitely use Power Query to transform the data to generate new rows using split column option.
Check this article it explains the process in detail.
Load Data in Power Query section of excel.
Create an Index (Not required step)
Use Split column function with advance options and split them into new rows.
Save this result into new table for your use.
I did it myself and it worked like a charm.
A formula solution:
Delimiter: Can be a real delimiter or an absolute reference to a cell containing only the delimiter.
HelperCol: I have to use a helper column to make it work. You need to give the column letter.
StartCol: The column letter of the first column containing data.
SplitCol: The column letter of the column to be splitted.
Formula1: Used to generate the formula for the first column not to be splitted. You can fill this formula down and then fill to right.
Formula2: Used to generate the formula for the column to be splitted(only support split one column).
Formula3: Used to generate the formula for the Helper column.
(If the title of the column to be splitted contains the delimiter, you must change the first value of the helper column to 1 manually.)
Formula1:=SUBSTITUTE(SUBSTITUTE("=LOOKUP(ROW(1:1),$J:$J,A:A)&""""","$J:$J","$"&B2&":$"&B2),"A:A",B3&":"&B3)
Formula2:=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE("=MID($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,FIND(""艹"",SUBSTITUTE($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,$M$1,"&"""艹"",ROW(A2)-LOOKUP(ROW(A1),$J:$J)))+1,FIND(""艹"",SUBSTITUTE($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,$M$1,""艹"",ROW(A2)-LOOKUP(ROW(A1),$J:$J)+1))-FIND(""艹"",SUBSTITUTE($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,$M$1,""艹"",ROW(A2)-LOOKUP(ROW(A1),$J:$J)))-1)&""""","$M$1",IF(ISERROR(INDIRECT(B1)),""""&B1&"""",B1)),"$J:$J","$"&B2&":$"&B2),"F:F",B4&":"&B4)
Formula3:=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE("=SUM(E1,LEN(B1)-LEN(SUBSTITUTE(B1,$H$1,"""")))+1","B1",B4&1),"$H$1",IF(ISERROR(INDIRECT(B1)),""""&B1&"""",B1)),"E1",B2&1)
Helper must filled one row more than the data.
How to use:
Copy the formula generated by the above three formula.
Use Paste Special only paste the value.
Make the formula into effect.
Fill the formula.
Bug:
Numbers will be converted to Text. Of course you can remove the &"" at the end of the formula, but blank cells will be filled with 0.
ps. This method may by very hard to comprehend. But once you master it, it can be very useful to solve relative problems.

Resources