Date Format in VBA not Working - vba

I want to display an input message response to a cell which is date formatted using CDate (dd/mm/yyyy). Why is it the code is not showing the error message if input was done as dd/mm/yy? The program accepts it but output shows as yy/mm/dd.
below is the code I created:
Sub inputSettlementDate()
Dim varInputDate As Variant
Dim lngERow As Long
varInputDate = InputBox("Please enter the Settlement Date using this format dd/mm/yyyy.", "Settlement Date")
If IsDate(varInputDate) Then
varInputDate = Format(CDate(varInputDate), "dd/mm/yyyy")
Else
MsgBox "Please enter a valid date format dd/mm/yyyy"
End If
If IsDate(varInputDate) Then
lngERow = Range("B" & Rows.Count).End(xlUp).Row + 1
Range("B" & lngERow).Value = varInputDate
End If
End Sub

You may want to make sure Column B has a format as General, or that it doesn't have a yy/mm/dd format. I tested your code in a blank workbook without changing anything and it worked flawlessly.

Related

Confusing dd/mm/yyyy and mm/dd/yyyy

I have a VBA script that opens up a bunch of CSV files, and compiles them into one summary report.
However, I'm having a problem where it reads in UK style dates (dd/mm/yyyy), then interprets them as US-style dates when it makes the copy, before display them as UK-style dates again!
So 4th of July in original sheet becomes 7th of April in the summary sheet - verified by changing cell format to display month name.
This is odd, as when you open up the CSV file in Excel, it correctly interprets the UK style date.
Copy is made using code like this
SummarySheet.Cells(Y,X).value = CSVSheet.Cells(W,Z).value
What is going on here?
You did not post the code as to how you are opening your CSV files -- that is the critical area. The dates need to be parsed properly BEFORE being entered on the worksheet. The following code will selects and then opens a file that has UK style dates in a single column, and properly parse them. You will need to adapt it to your particular requirements.
The FieldInfo argument is what does the work. The formatting of the Excel worksheet is "for show" so you can see an unambiguous date.
Option Explicit
Sub OpenUKcsv()
Dim sFile As String
Dim WB As Workbook
Dim WS As Worksheet
sFile = Application.GetOpenFilename()
Workbooks.OpenText Filename:=sFile, DataType:=xlDelimited, comma:=True, other:=False, _
fieldinfo:=Array(1, 4)
Set WB = ActiveWorkbook
Set WS = ActiveSheet
With WS.Columns(1)
.NumberFormat = "dd-mmm-yyyy"
.EntireColumn.AutoFit
End With
End Sub
You could use .Text (text displayed in Excel cell) or .Value2 (value without formatting) instead of .Value (value with formatting).
But I strongly suggest that you set the format of the cells that you use to what you expect to have at the end with .NumberFormat = "mm/dd/yyyy"
Or you could use CDate function :
SummarySheet.Cells(Y,X).value = CDate(CSVSheet.Cells(W,Z).value)
Or use an UDF with DateSerial :
Sub test_CMaster()
MsgBox ParseDate("4/7/15") & vbCrLf & CDate("4/7/15")
End Sub
Function ParseDate(ByVal DateInCell As String, Optional Separator As String = "/") As Date
Dim D() As String
D = Split(DateInCell, Separator)
ParseDate = DateSerial(D(UBound(D)), D(1), D(0))
End Function
Try using the Workbooks.OpenText() method instead and set the Local flag to True
Set csvWB = Workbooks.OpenText(Filename:=myCSVfile, Local:=True)
Here is the MSDN article on this method which says for the Local setting:
Specify True if regional settings of the machine should be used for separators, numbers and data formatting.
Maybe you can convert the CSV files to show dates as numbers, ie. 10th Nov 15 will show as 42318. Or add a separate column where B1 is =DATEVALUE(A1) and work with that.
When you create the summary report, import the numbers and convert them to date using CDate and Format. Something like this:
Sub test()
Range("A2:A4").NumberFormat = "m/d/yyyy"
Range("A2").Value = Format(CDate(Range("A1").Value), "dd.mm.yyyy")
Range("A3").Value = Format(CDate(Range("A1").Value), "mm.dd.yyyy")
Range("A4").Value = Format(CDate(Range("A1").Value), "Long Date")
End Sub
EDIT:
For better formatting (no need for NumberFormat, I think it will use your regional settings right away) and auto-setting the cell format to date-type, use this:
Sub test()
Dim sDate As Date
sDate = CDate(Range("A1").Value)
Range("A2").Value = DateSerial(Year(sDate), Month(sDate), Day(sDate))
End Sub
Result:
References:
http://www.techonthenet.com/excel/formulas/format_date.php
http://www.techonthenet.com/excel/formulas/cdate.php

Why am I getting this error: Object Variable or With block variable not set?

I have found out what causes this error but I cannot pinpoint where it is coming from in my code. I even tested this macro in a separate worksheet in excel and it worked but in this worksheet it is not working. Can anyone guess as to why or offer any workarounds? I put a comment on the line with the error. Assume data is put in correctly.
Private Sub CommandButton1_Click()
Dim startDate As Date, endDate As Date, reason As String, name As String
name = InputBox("Please enter the name of the SLG as appears in column 1 on the worksheet:")
startDate = InputBox("Please enter the start date in MM/DD/YYYY format:")
endDate = InputBox("Please enter the end date in MM/DD/YYYY format:")
reason = InputBox("Please short description for the absence:")
Dim rng1 As Range, columnNumberStart As Integer, rowNumber As Integer, columnNumberEnd As Integer, test1 As String, test2 As String
Worksheets("FY-15 Schedule").Activate
Set rng1 = ActiveSheet.UsedRange.Find(name)
rowNumber = rng1.Row
Set rng1 = ActiveSheet.UsedRange.Find(startDate)
columnNumberStart = rng1.Column 'Says Error is on this line
Set rng1 = ActiveSheet.UsedRange.Find(endDate)
columnNumberEnd = ActiveSheet.UsedRange.Find(endDate).Column
test1 = Cells(rowNumber, columnNumberStart).Address
test2 = Cells(rowNumber, columnNumberEnd).Address
Dim rng2 As Range
Set rng2 = Range(test1, test2)
rng2.Value = reason
End Sub
First, explicitly coerce the date from the inputbox input:
startDate = CDate(InputBox("Please enter the start date in MM/DD/YYYY format:"))
And do the same for the other date field.
Then, there is still possible source of this same error: when the .Find method has returned Nothing to the range object, (e.g., the date is not found/doesn't exist in the sheet) then you are essentially doing Nothing.Column, which is an error.
If the date does not exist in the sheet, this will always raise an error, which you could trap like this, or use GoTo statements to return to the inputbox, etc...
Set rng3 = ActiveSheet.UsedRange.Find(startDate)
If rng3 Is Nothing Then
MsgBox "Start date" & Cstr(startDate) & " not found!", vbInformation
Exit Sub
End If
columnNumberStart = rng1.Column
I figured it out! The problem was this: It was not finding the dates because the dates were being generated by a formula!! My first date was manually typed in but the rest of them were a fill series from the second cell which was A2=A1+1 and all the way down the line. I wanted it that way so the start date could be changed but for some reason excel was not recognizing those as dates!?! How weird?!?!
Problem solved though. What you said was correct about it not finding the date but appearance wise when looking at the spreadsheet it is there in plain sight but when looking at the cells their values were formulas.

Date lookup issue: Unable to get VLookup property of WorksheetFunction class

I've tried almost everything in most of the other similar type questions but I can't seem to solve the runtime error. Help please!
What I want to achieve:
1) My macro is supposed to get date from report summary files that are created every day hence, it requires the user to input which date of report he wants the data from
2) I use the vlookup method to get the data from the relevant row and input it into the central workbook with the macro
3) Every part of the code works except using the date to Vlookup and it will give me this error message
4) I have tested the code using other text based lookup values and the whole macro works (i.e. i looked up the row which has the "Total" value so it looks up "Total" but i require the macro to look up the rows with the date as the look up value)
Addtional Info:
1) In the lookup file, the dates are in the format of "m/d/yyyy" but presented in the format of "dd-mmm-yy" (but i've tried both and they dont work)
Sub GetData()
Dim strDate As Date
strDate = InputBox("Input date of report to retrieve (Format: DD-MM-YYYY)", "Input Date", Format(Now(), "DD-MM-YYYY"))
If IsDate(strDate) Then
'there is some code here not relevant but basically i need to keep manipulating the date throughout the code
With ActiveSheet
Dim XstrDate
Dim Xfile As String
XstrDate = Format(strDate, "mmm DD, YYYY")
Xfile = "C:\...\...\...\Report " & XstrDate & ".xls"
Dim wb As Workbook
Dim ws As Worksheet
Dim rng As Range
Dim returnValue as Variant
Set wb = Application.Workbooks.Open(Xfile)
Set ws = wb.Worksheets("Summary")
Set rng = ws.Range("A:K")
Dim Xdate As String
Xdate = Format(XstrDate, "m/d/yyyy")
returnValue = Application.WorksheetFunction.VLookup(Xdate, rng, 2, 0)
'... more code
remember, i've tried looking up using the text in the same column and it returned me a value. So i suspect the problem lies with the date format or something
Any smart and kind soul want to offer some suggestions here:)
Excel internally stores dates as a Serial Number (e.g. 1/1/2014 = 41640), which you can observe yourself if you enter a date into a cell and then change the format to Number.
With this in mind it's unlikely that a VBA date and an Excel date can be matched using the VLookup function so in my experience the best solution is to convert your date into its serial number and then perform the VLookup on that value instead.
Dim Ndate As Long
Dim returnValue As Date
Ndate = DateSerial(<Year>, <Month>, <Day>)
returnValue = Application.WorksheetFunction.VLookup(Ndate, <rng>, <col>, False)
If you need to construct your DateSerial(...) function from a Date variable in VBA you can use the Year(<date>), Month(<date>), and Day(<date>) functions to break it down into the required components.
Note: I've tried this example in the format .VLookup(DateSerial(2014,1,1),...) and it still causes the same error, hence storing the return value of DateSerial in a numeric variable first.
Happy Coding!
I've taken a different approach and found another solution to this problem.
Rather than use Vlookup, this is the other method that bypass the problem of VLookup date format problem, (having defined vdate in previous statements)
Dim rnge As Range, i As Long
Sheets("Summary").Select
Columns("A:A").Select
Set rnge = Intersect(Selection, ActiveSheet.UsedRange)
If rnge Is Nothing Then
MsgBox "Date Not Found"
GoTo done
End If
For i = rnge.Count To 1 Step -1
If rnge.Cells(i).Value = vdate Then rnge.Cells(i).EntireRow.Copy _
Destination:=ThisWorkbook.Sheets("AnotherSheet").Range("A1")
Next
done:
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True

Replace Underscores characters with Space inside a String value

This is a rather simple question.
I have a date variables formated like: 25_December_2010
I would like a statement or a bit of code in the VBA macro that will transform that string value from: 25_December_2010 to 25 December 2010.
Somehow be able to remove the underscores from inside the String value....
As I mentioned in comments, use code below:
Dim strDate As String
strDate = "25_December_2010"
strDate = Replace(strDate,"_"," ")
I wanted something similar in a macro I'm using for data cleaning so I took #simoco's answer and created a simple but mostly safe macro/sub.
Sub ConvertSpaceToUnderscore()
Dim strCellValue As String
' Use basic error handling if more than 1 cell is selected, or
' possibly if something that isn't a cell is selected.
On Error GoTo SelectionTooBig
strCellValue = Selection.Value
strCellValue = Replace(strCellValue, " ", "_")
Selection.Value = strCellValue
On Error GoTo 0
' Exit the sub if things went well
Exit Sub
SelectionTooBig:
MsgBox "Please select one cell at a time.", vbCritical, "Selection too large"
End Sub

Event(s) for opening the workbook AND worksheets

I'm looking for an elegant solution to trigger an event for opening the workbook as well as opening different worksheets. I don't need seperate operations for each worksheet: they all trigger the same method.
I know I can use the events Workbook_Activate / Workbook_Open and Workbook_SheetActivate at the same time but I don't know if this is 'the official way' to do it. Perhaps there's a way to do this with one event.
I was also wondering if it is relevant in this matter where I put the code. I now have all the code inside "ThisWorkbook" and not in a "Module"...
Here is some code I developed a while ago to ensure that a report my managers use is always opened to the correct tab based on time of day. I house this code in the "ThisWorkbook" module of my VBA.
Sub Workbook_Open()
' Set The Office
Dim begin As String
Dim myNum As String
Dim myNum1 As String
Dim TheDate As String
' Set Date
TheDate = Format(DateTime.Now(), "mm-dd-yy")
Sheets("MORNING").Range("H3").Value = TheDate
Sheets("AFTERNOON").Range("G3").Value = TheDate
'Sheets("EVENING").Range("G3").Value = TheDate
' Select Sheet Based on Time of Day
If Time >= 0.1 And Time < 0.5 Then
Sheets("MORNING").Select
Range("A53").Value = "Report completed by:"
Range("C53").Value = Application.UserName
Range("I53").Value = Date & " " & Time
Range("B27").Select
Call Populate 'Your next code
ElseIf Time >= 0.5 And Time < 0.75 Then
Sheets("AFTERNOON").Select
Range("A54").Value = "Report completed by:"
Range("C54").Value = Application.UserName
Range("I54").Value = Date & " " & Time
Range("C28").Select
Call Populate 'Your next code
End If
End Sub
Notice that I have also added code to auto sign the form output with the userid and update date and time. I hope this helps.
Like others have mentioned: there's no single event to do this. There might be workarounds, but I prefer just using _Open and _SheetActive in that case. Thanks everyone!