VB6, CDate(sheet.range("B", counter)) - excel

I've been looking and looking for a solution but without success.
I need to populate list-view by date criteria, I know how to fill it with simple criteria but date criteria has given me a lot of problems.
I have dates (dd.mm.yyyy) in B column in my Excel document and I need to convert them to date and compare with date which I choose from calendar control on the form. How can I set that default date in VB6 be dd.mm.yyyy?
I am beginner and I don't know where I am wrong, please help me. Thanks in advance.
Do Until .Cells(myCounter, 1) & "" = ""
strDate = listObj.Range("B" & myCounter)
myDate= CDate(strDate) >>>>>>>>>> Run-time error "13" Mismatch type
If myDate > Calendar1.Value Then
.........................
End If
myCounter =myCounter + 1
Loop
edit: This is my whole code
Dim excelObj As excel.Application
Dim wbObj As excel.Workbook
Dim sheetObj As Worksheet
Dim myCounter As Long
Set excelObj = New excel.Application
excelObj.Visible = False
Set wbObj = excelObj.Workbooks.Open(App.Path & "\excel_document.xlsx")
Set sheetObj = excelObj.Worksheets("Sheet1")
Dim L As ListItem
Dim myDateAs Date
Dim strDate As String
ListView1.ListItems.Clear
With sheetObj
myCounter = 2
Do Until .Cells(myCounter, 1) & "" = ""
strDate = sheetObj.Range("B" & myCounter)
myDate= CDate(strDate)
If myDate > Calendar1.Value Then
........
End If
myCounter = myCounter + 1
Loop
End With
excelObj.Quit
In excel document B column is formatted as Date - dd/mm/yyyy. I tried also not to do CDate but without success.

How did you declare strDate? Dim strDate As String? Variant? Not declared?
Given what you're trying to do, it really should be declared as either Variant or Date. It looks like you declared it as a String, and that you are also entering strings on the cells.
When you Enter the date values in Excel, you should enter them as dates instead of strings. It's easy; just make sure that the cells are formatted with "dd.mm.yyyy" and they will accept such dates correctly when you type them. When you retrieve the values from VB, they will be retrieved as Dates and you will be able to manipulate them as such.
If you really want to transform a string that comes in that format into a Date value, you can use this method: Parse finnish date string to Date Type in VB6

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.

Run-time Error '6' Overflow when storing date in var

I am iterating through dates in a loop to execute different snippets of code.The following piece of code in the loop gives me a
runtime error '6' Overflow
when assigning the cell's value to dateClaim:
Dim dateClaim As Date
Dim rngDateClaimeMade As Range
Set rngDateClaimeMade = dfensCSheet.Range("AC7") 'AC contains dates in format dd.mm.yyyy
dateClaim = rngDateClaimeMade.value
dateClaimMonth = Format(Month(dateClaim), "00")
dateClaimYear = Year(dateClaim)
Any ideas/ help is very much appreciated!
So that looks like 24.12.2020 is a text not a date in that cell and therefore it cannot be converted automatically.
If your dates are always in this format dd.mm.yyyy you can convert it like below:
Option Explicit
Public Sub Example()
Dim TextDate As String ' this is a text looking like a date (but is not a date just a string)
TextDate = "24.12.2020" ' instead read your cell value here
' test if the string has a format that we can convert
If Not TextDate Like "??.??.????" Then
MsgBox "Date was not in expected format dd.mm.yyyy"
Exit Sub
End If
' split text into 3 parts by dot as delimiter
Dim SplitDate() As String
SplitDate = Split(TextDate, ".")
' reorder the 3 parts to make a real numeric date
Dim NumericDate As Date
NumericDate = DateSerial(SplitDate(2), SplitDate(1), SplitDate(0))
' this numeric date is now a real date that can be formatted as desired
Debug.Print Format$(NumericDate, "yyyy-mm-dd") 'returns 2020-12-24
End Sub
You can then use
Dim dateClaim As Date
dateClaim = DateSerial(SplitDate(2), SplitDate(1), SplitDate(0))
Dim dateClaimMonth As String
dateClaimMonth = Format$(dateClaim , "mm")
Dim dateClaimYear As String
dateClaimYear = Format$(dateClaim , "yyyy")
if you need month and year as text! If you need them numeric don't use Format$()!
VBA cannot convert text dates with dots directly. So try:
dateClaim = DateValue(Replace(rngDateClaimeMade.Value, ".", "/"))
dateClaimMonth = Month(dateClaim)
dateClaimYear = Year(dateClaim)
Apply the format 00 where the month is to be displayed.

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

How to display sub string in reverse order but read from left to right in VBA

I am processing a .txt file in VBA.
Amongst other tasks, I need to read in a string representing a date and display the actual date in Excel.
A date string in the .txt file looks like "190223"
This represents 23/02/2019
My challenge is to get this done.
What I have done so far is:
' ... loop
With ActiveWorkbook.Worksheets(1)
' Other statements here
' Event date time
.Range("N" & i).Value = StrReverse(Mid(.Range(keyword.Offset(0, 4).Address), 1, 2) & _
"/" & Mid(.Range(keyword.Offset(0, 4).Address), 3, 2) & _
"/" & Mid(.Range(keyword.Offset(0, 4).Address), 5, 2))
End With
But I get the undesired output:
32/20/91 ' For a date string 190223 the desired output should be 23/02/19
Any help would be much appreciated.
Thanks in advance.
Convert it into a real date
You must extract year, month and day of that string and then convert this into a real date.
Then you can format the date to what ever date format you like. The value that is saved in the cell is then a real date value (not a string!) so you can calculate with it.
I highly recommend to read How Dates Work in Excel – The Calendar System Explained + Video to understand the background and why real dates are so important.
Here is an example:
Option Explicit
Public Sub ConvertDateExample()
Const InputStr As String = "190223"
Dim InputYear As Integer
Dim InputMonth As Integer
Dim InputDay As Integer
'extract year, month and day
InputYear = Left(InputStr, 2)
InputMonth = Mid(InputStr, 3, 2)
InputDay = Right(InputStr, 2)
'put it together to a real date
Dim RealDate As Date
RealDate = DateSerial(InputYear, InputMonth, InputDay)
'write the date into a cell
Range("A1").Value = RealDate
'format that cell to your desired format
Range("A1").NumberFormat = "dd/mm/yyyy"
End Sub

excel vba string to date

Windows 10 Pro, Regional Settings to UK English.
In Excel VBA I have a string "02/05/2017 16:30"
That, in the UK, means "02 May 2017 16:30"
But VBA turns this to US format somehow and in the cell puts "05/02/2017 16:30"
The VBA code is like this
Dim sField As String
sField = "02/05/2017 16:30"
ws.Cells(1,1) = sField
I can use CDate to get around this but CDate but that requires extra code to determine which cells are dates and which aren't, whereas the implicit conversion works for all types.
Use a Date variable instead, and always provide your date in MDY in VBA.
Dim sField As Date
sField = #05/02/2017 16:30#
ws.Cells(1,1) = sField
AFAIK in VBA you must always work the 'American way', with dates MDY. It does NOT follow regional settings. Which is good, because that enables running the same code on heterogeneous environments.
This is some workaround in the VBA code:
Sub Main()
Dim myInput As String
Dim splitMe As Variant
Dim outputDate As Date
myInput = "02/05/2017 16:30"
splitMe = Split(myInput, "/")
outputDate = DateSerial(Left(splitMe(2), 4), splitMe(1), splitMe(0))
Debug.Print Format(outputDate, "DD-MMM-YY")
Debug.Print Format(outputDate, "DD-MM-YYYY")
End Sub
It takes the date as a string and it splits it by /. Then it takes the year, the month and the day and it builds a new date with the help of DateSerial(). DateSerial MSDN.
In cases like this, make sure that you are passing the correct date to excel and there you may change the format through something as easy as this:
Range("A1").NumberFormat = "m/d/yyyy"
To make sure, that you are passing the correct date, simply try Month(YourDate) over the date or Day(YourDate).
I rather use the built-in VBA functions DateSerial(year, month, day) and TimeSerial(hour, min, sec).
Dim myDateTime as date
mydateTime = DateSerial(2017, 5, 2) + TimeSerial(16, 30, 0)
ws.Cells(1,1) = myDateTime
You can then set the number formatting on the Excel cell to your liking.
I assume this is faster because there is not need to translate any string beforehand. More importantly for me as a programmer, the parameters are explicit. I don't have to worry about different regional setting.
I solved a related problem. My workbook is for use only in the UK. It has a sheet for entering details of cash collected at various venues. The user has two single-cell fields to identify each venue; typically a location and a date, but sometimes the "date" field will contain an extended location name instead.
Dates should be entered as dd/mm/yy, but almost anything recognisable is accepted except mm/dd/yy.
The details are stored in memory, then later copied to formatted worksheets for printing. I verified the storage in memory. But after the workbook had been in use for a few months, I found that if the user entered a valid date in a cell in the format dd/mm/[yy]yy (e.g. 05/11/17), and its interpretation as mm/dd/[yy]yy would also give a valid date, then the date would obscurely be printed as 11-Mar instead of 05-Nov.
Some code snippets:
'Data structure:
Public Type BkItem 'An item of income, for banking.
ItemName As String 'The first field, just a text name.
ItemDate As Date 'The second field, interpreted as a date.
ItemDateNumber As Long 'The date as internally stored as an integer.
ItemDateString As String 'Re-formatted string, e.g. "05-Nov-17".
' ...
End Type 'BkItem.
'Input validation:
BankData = Range(.Cells(BankFirstRow, BankFirstCol), _
.Cells(BankLastItemLastRow, BankLastCol))
With BankItem(BankTotalItems)
.ItemName = IName
.ItemDateString = BankData(<row>, <col>)
.ItemDateNumber = DateToLong(.ItemDateString)
End With
'Utility routine. "Paper" is a 2-dimensional array of all the data to be printed
'on one or more pages; "Dest" is a global range.:
Sub OutputDataToSheet(ByVal Size As Long, ByRef CurrentSheet As String, _
ByRef Paper() As Variant)
Worksheets(CurrentSheet).Activate
Set Dest = Worksheets(CurrentSheet).Range((Cells(1, 1)), _
(Cells(Size, LastCol)))
Dest.Value = Paper 'Copy data to final sheet for printing.
End Sub 'OutputDataToSheet.
'As we build the array "Paper", it helps to format those cells on the final
'printout worksheet which are going to contain dates.
.Range(Cells(CurRow, L15c01), Cells(CurRow, L15c01)).NumberFormat = "dd-Mmm-yyyy"
'For the item date.
.Range(Cells(CurRow, L15c01), Cells(CurRow, L15c01)).HorizontalAlignment = xlCenter
If IsDate(BankItem(item).ItemDateString) Then
Paper(<row>, <col>) = BankItem(item).ItemDateNumber
'Date as a number, so OutputDataToSheet preserves UK date format.
Else
Paper(<row>, <col>) = BankItem(item).ItemDateString
'Extension of name.
End If 'IsDate(.ItemDateString).

Resources