How to change 6 digit number into Date String - vb.net

So, I've found this thread, which talks about my issue exactly, however the solution doesn't work for me: How to Change Format column in Datagridview to date type for this value
I've got a different number patter, in which my data is: YYMMDD, just 6 numerical digits (000901 - September 1st, 2000)
Does the data structure make a difference when converting it to a data string? Does it need to be in an initial format?
This is my current string of code:
DataGridView1.Columns(1).DefaultCellStyle.Format = "yy/MM/dd"
Just trying to get any format what-so-ever, but it just remains as 6 digits.

OK, try this. Set your format in the datagridview to the date format you want to use. For my example, I had 3 columns and the far right column contained the 6 digit strings.
In my 3rd column I set a format of yyyy/MM/dd in the datagridview.
In the button click I looped through the dgv and parsed the values to a datetime which allowed the format to work as it was now working with a date type.
For Each r As DataGridViewRow In DataGridView1.Rows
If Not r.IsNewRow Then
r.Cells(2).Value = DateTime.ParseExact(r.Cells(2).Value.ToString, "yyMMdd", CultureInfo.InvariantCulture)
End If
Next
Upon clicking the button, I got the following results.
Now that the column is a date datatype, we can just change the format and the columns format to the new format setting.
I added a second button and in that button I placed the code
DataGridView1.Columns(2).DefaultCellStyle.Format = "MMM dd, yyyy"
which immediately change the 3rd column to the new format

After some thought and experimentation, I realised how to do this on the GUI instead of when loading the data.
You can achieve this particular formatting by handling the CellFormatting event of the DataGridView.
Test Data I used:
Private Property MyData As DataTable
Private Sub InitialiseData()
MyData = New DataTable
MyData.Columns.Add("YMDString", GetType(String))
Dim dr As DataRow
dr = MyData.NewRow()
dr(0) = "000901"
MyData.Rows.Add(dr)
dr = MyData.NewRow()
dr(0) = "010901"
MyData.Rows.Add(dr)
dr = MyData.NewRow()
dr(0) = "020901"
MyData.Rows.Add(dr)
End Sub
DataGridView configuration
Private Sub SetupDataGridView()
InitialiseData()
DataGridView1.AutoGenerateColumns = False
DataGridView1.Columns.Add("YMDString", "YMD String")
DataGridView1.Columns.Add("YMDDateTime", "YMD DateTime")
DataGridView1.Columns(0).DataPropertyName = "YMDString"
DataGridView1.Columns(1).DataPropertyName = "YMDString"
DataGridView1.DataSource = MyData
AddHandler DataGridView1.CellFormatting, AddressOf DataGridView1OnCellFormatting
End Sub
And the CellFormatting event handler that does the hard work. The DateTime parsing isn't the best you can use, but it does illustrate the principal of what you want to achieve.
Private Sub DataGridView1OnCellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs)
Dim thisGrid As DataGridView = CType(sender, DataGridView)
If (thisGrid IsNot Nothing AndAlso e.Value IsNot Nothing) Then
If (thisGrid.Columns(e.ColumnIndex).Name = "YMDDateTime") Then
Dim stringValue As String = e.Value.ToString()
Dim year As Integer = 2000 + stringValue.Substring(0, 2)
Dim month As Integer = stringValue.Substring(2, 2)
Dim day As Integer = stringValue.Substring(4, 2)
Dim dt As New DateTime(year, month, day)
e.Value = dt.ToString("yyyy/MM/dd")
End If
End If
End Sub
When run, I get this result:

I took your six digit string and converted to a DateTime then formatted as you wished.
Dim strDate As String = "180211"
Dim myDate As New DateTime(CInt("20" & strDate.Substring(0, 2)), CInt(strDate.Substring(2, 2)), CInt(strDate.Substring(4)))
Debug.Print(myDate.ToString("yy/MM/dd"))
EDIT:
I found a better answer thanks to user1751825 at VB.NET compare date time from string format
Dim myDate As Date = DateTime.ParseExact(strDate, "yyMMdd", CultureInfo.InvariantCulture)

Related

VB.Net find last day of month with date format

I am trying to find the last day of the month and compare it to today's date
I do NOT want the integer number I would like the result in this format "MM-dd-yyyy"
Date Picker will not work for this project
Here is the code I using but the process seems overly complicated concocting strings
Side note when today is after the 4th Tue I write True and the Last Day of the month to a DB
when today is after the last day of the month and the bool is now True I write the new last day of the new month and false to the DB
Function FourthTueOfMonth(dt As Date) As Date
Dim currDate = New Date(dt.Year, dt.Month, 1)
Dim nTuesday = 0
While nTuesday < 4
If currDate.DayOfWeek = DayOfWeek.Tuesday Then
nTuesday += 1
End If
currDate = currDate.AddDays(1)
End While
Return New Date(dt.Year, dt.Month, currDate.Day - 1)
End Function
Private Sub btnFindDate_Click(sender As Object, e As EventArgs) Handles btnFindDate.Click
Dim tORf As Boolean = False
Dim dateToday = Date.Today
Dim dateFourthTue = (FourthTueOfMonth(Date.Today))
tbFourthTue.Text = dateFourthTue.ToString("MMM-dd-yyyy")
tbThree.Text = dateFourthTue.ToString("yyyy-MM-dd")
tbEndOFMonth.Text = Date.DaysInMonth(Date.Now.Year, Date.Now.AddMonths(0).Month).ToString
Dim dToday As Date
dToday = Date.Parse("10-01-2021")
Dim dtY = dateToday.ToString("yyyy")
Dim dtM = dateToday.ToString("MM")
Dim eom As String = Date.DaysInMonth(Date.Now.Year, Date.Now.AddMonths(0).Month).ToString
Dim dtALL As String
dtALL = dtM & "-" & eom & "-" + dtY
Dim testD As Date
testD = Date.Parse(dtALL)
If tORf = False And dToday > dateFourthTue Then
MessageBox.Show("Today > Fourth Tue")
'tORf = True'Write True
'tbMessage.Text = tORf.ToString
End If
If tORf = True And dToday > testD Then
MessageBox.Show("Today > End Of Last Month")
'tORf = False write False
'tbMessage.Text = tORf.ToString
End If
End Sub
The solution provided by #Albert D. Kallal is great for Visual Basic since DateSerial is in the Visual Basic namespace in the DateAndTime class. Here is a solution that should work in both vb and C#.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dtToday As Date = Date.Today
Dim dtEndOfMonth = New Date(dtToday.Year, dtToday.Month + 1, 1).AddDays(-1)
Debug.Print(dtToday.ToString)
Debug.Print(dtEndOfMonth.ToString("MM-dd-yyyy"))
End Sub
A few things:
You want to use today - not "now()" as that includes a time portion. While a date type only has date, you should consider if you have datetime, and either way, no need to introduce and use a value that includes both date and time such as now does.
I reocmmend this code:
Dim dtToday As Date = Date.Today
Dim dtEndOfMonth As Date = DateSerial(dtToday.Year, dtToday.Month + 1, 0)
Debug.Print(dtToday)
Debug.Print(dtEndOfMonth)
Output:
Today happens to be the 1st, but any date would work. This includes end of year, and even leap years.
2021-10-01
2021-10-31
So, this is a long time old trick - goes back to old VB6, and even old VBA code from 20 years ago.
So, we use date serial to produce a date, but if you use 0 for the day, then you get the previous day, and thus gets you the last day of the current month.
So we toss in year, month + 1, and 0 for the date - that results in the last day of the current month.
I hate to admit I might have gave up the search too quick
found the answer here
Answer Here
Here is the code
Dim dateToday = Date.Now.AddMonths(0)
Dim dateEndOfMonth = New Date(dateToday.Year, dateToday.Month, DateTime.DaysInMonth(dateToday.Year, dateToday.Month))
tbMsg.Text = dateEndOfMonth.ToString("MM-dd-yyyy")
Code seems to be working ?
I have seen suggestions to use this format for comparing dates
TEST DATES use this format yyyyMMdd Please comment if you can add to the answer

Updating values in .csv file depend to values in second .csv

I have two csv files, which contains some data. One of them looks like this:
drid;aid;1date;2date;res;
2121;12;"01.11.2019 06:49";"01.11.2019 19:05";50;
9;10;"01.11.2019 10:47";"01.11.2019 11:33";0;
72;33;"01.11.2019 09:29";"01.11.2019 14:19";0;
777;31;"03.11.2019 04:34";"03.11.2019 20:38";167,35;
Second scv looks like this
datetime;res;drid
"2019-11-01 09:02:00";14,59;2121
"2019-11-03 12:59:00";25,00;777
My target to compare day of date also "drid" and if they are the same in both files then get sum of "res" and replace values of "res" in first csv. Result have to looks like this:
2121;12;"01.11.2019 06:49";"01.11.2019 19:05";64,59;
9;10;"01.11.2019 10:47";"01.11.2019 11:33";0;
72;33;"01.11.2019 09:29";"01.11.2019 14:19";0;
777;31;"03.11.2019 04:34";"03.11.2019 20:38";192,35;
What I have to do to obtain that results in vb.net? I tried to use LINQ Query, but with no results, because I'm newbie and I didn't find way to declare variables in two files and then compare it.
Ok, with .bat I made join both csv in one big.csv and tried to obtain results from same file, but again without success. Last one code is:
Private Sub Button12_Click(sender As Object, e As EventArgs) Handles Button12.Click
Dim Raplines As String() = IO.File.ReadAllLines("C:\Users\big.csv")
Dim strList As New List(Of String)
Dim readFirst As Boolean
For Each line In Raplines
If readFirst Then
Dim strValues As String() = line.Split(";")
Dim kn1 As String = strValues(0)
Dim kn2 As String = strValues(59)
Dim pvm1 As Date = strValues(2)
Dim pvm1Changed = pvm1.ToString("dd")
Dim pvm2 As Date = strValues(3)
Dim pvm2Changed = pvm2.ToString("dd")
Dim pvm3 As Date = strValues(60)
Dim pvm3Changed = pvm3.ToString("dd")
Dim Las1 As Decimal = strValues(9)
Dim Las2 As Decimal = strValues(61)
Dim sum As Decimal = Las1 - Las2
If kn1 = kn2 And pvm3Changed = pvm1Changed Or pvm3Changed = pvm2Changed Then
strValues(9) = sum
strList.Add(String.Join(";", strValues))
End If
End If
readFirst = True
Next
IO.File.WriteAllLines("C:\Users\big_new.csv", strList.ToArray())
End Sub
Instead of changing the existing file I wrote a new one. I used a StringBuilder so the runtime would not have to create and throw away so many strings. StringBuilder are mutable unlike Strings. I parsed the different formats of the dates and used .Date to disregard the Times.
Private Sub ChangeCVSFile()
Dim lines1 = File.ReadAllLines("C:\Users\someone\Desktop\CSV1.cvs")
Dim lines2 = File.ReadAllLines("C:\Users\someone\Desktop\CSV2.cvs")
Dim sb As New StringBuilder
For Each line1 In lines1
Dim Fields1 = line1.Split(";"c) 'drid;aid;1date;2date;res
For Each line2 In lines2
Dim Fields2 = line2.Split(";"c) 'datetime;res;drid
'
' Trim the exta double quotes "01.11.2019 06:49"
Dim d1 = DateTime.ParseExact(Fields1(2).Trim(Chr(34)), "dd.MM.yyyy hh:mm", CultureInfo.InvariantCulture).Date
' "2019-11-01 09:02:00"
Dim d2 = DateTime.ParseExact(Fields2(0).Trim(Chr(34)), "yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture).Date
If Fields1(0) = Fields2(2) AndAlso d1 = d2 Then
Dim sum = CDec(Fields1(4)) + CDec(Fields2(1))
Fields1(4) = sum.ToString
End If
Next
sb.AppendLine(String.Join(";", Fields1))
Next
File.WriteAllText("C:\Users\someone\Desktop\CSV3.cvs", sb.ToString)
End Sub

Read data from dynamically created text-box

I'm trying to collect data after creating dynamic text-box with vb.net
Private Sub btn_OK_lines_number_Click(sender As Object, e As EventArgs)
Handles btn_OK_lines_number.Click
Dim i As Integer
Dim x As Integer
Dim Z As Integer
Z = 150
If IsNumeric(txt_lines_number.Text) Then
Int32.TryParse(txt_lines_number.Text, x)
For i = 1 To x
Dim newTB As New TextBox
Dim newLB As New Label
newLB.Name = "lbl_workstation_number_line" & i
newLB.Text = "Nbr Work Station in Line" & i
newLB.Size = New Size(190, 20)
newLB.ForeColor = Color.White
newLB.Font = New Font("consolas", 12, FontStyle.Regular, GraphicsUnit.Pixel)
newLB.Location = New Point(20, Z + i * 30)
newTB.Name = "Textbox" & i
newTB.Size = New Size(170, 20)
newTB.Location = New Point(200, Z + i * 30)
Me.Controls.Add(newTB)
Me.Controls.Add(newLB)
Next
i = i + 1
Else
MessageBox.Show("please enter a number")
txt_lines_number.Text = ""
End If
End Sub
Let's say you just have one row, and only create one TextBox. You set the name here:
newTB.Name = "Textbox" & i
where the resulting TextBox is named Textbox1. The problem is you can't just reference the identifier Textbox1 directly in your code, as you do with txt_lines_number. You can't even reference it as a member of the class (Me.Textbox1). This name didn't exist at compile time, and so it's not an identifier you can use, and it's not a member of the class at all. There was never a matching Dim statement for that name.
What you can do, though, is look again in the Controls collection where you added the TextBox to the form:
Me.Controls("Textbox1")
or
Me.Controls("Textbox1").Text
You may also need to cast the value to a TextBox:
Dim box As TextBox = DirectCast(Me.Controls("Textbox1"), TextBox)
MessageBox.Show(box.Text)
Remember that case matters here.
Further saving this in a DB is out of scope for one question. There are as many ways to do that as there are programmers in the world. You should make your own attempt first, and come back here with a new question when you run into specific problems.
Thank you,
this is my attempt and it is done !
Dim userInput As TextBox = Form1.Controls.Item("TextBox" & i.ToString)
mycommand.Parameters.AddWithValue("#workstation", userInput.Text)
:D
Because you creating dynamic amount of input controls, right tool for the job will be DataGridView control.
Create a class to represent your data
Public Class LineInfo
Public Property Number As Integer
Public Property WorkStationNumber As Integer
End Class
Create `DataGridView in the form designer.
Private Sub btn_OK_lines_number_Click(sender As Object, e As EventArgs) Handles btn_OK_lines_number.Click
Dim linesAmount As Integer
If Integer.TryParse(txt_lines_number.Text, linesAmount) = False Then
MessageBox.Show("please enter a number")
txt_lines_number.Text = ""
Exit Sub
End If
' Create class instance for every line
Dim lines =
Enumerable.Range(1, linesAmount)
.Select(Function(i) New LineInfo With { .Number = i })
.ToList()
'Set lines as DataSource to the DataGridView
Me.DataGridView1.DataSource = lines
End Sub
DataGridView will display all lines and provide input fields to update work station numbers.
You can access updated lines later by casting DataSource back to the List
Dim lines = DirectCast(Me.DataGridView1.DataSource, List(Of LineInfo))
' Now you can access all data and save it to the database
Dim parameters =
lines.Select(Function(line)
Return new SqlParameter With
{
.ParameterName = $"#workstation{line.Number}",
.SqlDbType = SqlDbType.Int,
.Value = line.WorkStationNumber
}
End Function)
.ToList()
myCommand.Parameters.AddRange(parameters)
You can freely change style, font colors of different columns in the datagridview.

VB form load event based on date

I'm attempting to display a button on a secondary form in vb based on what the date is (Trying to get a reset button to show only on the last day of the year).
I've tried a few different things with the code below...
I originally put it in the Form Load Event of Form 2, no msgbox displayed, button didn't display.
I cut the code out of my project and pasted it into the Form Load Event of a new project to test it on it's own... Msgbox displayed and button displayed!! :)
This got me thinking maybe I had to put the code into the Form Load Event of the Main Form. I pasted it there and made the modifications to point to form2 (Current version of the code)....
Once again , no msgbox, no button
What am I missing?
Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim date1 As String = String.Format("{0:MM/dd/yyyy}", DateTime.Now)
Dim todaysdate As String = Format(Now, "Long Date")
Dim dayofweek = todaysdate.Substring(0, todaysdate.IndexOf(","))
Dim year As String = Now.Year
Dim datecheck As String = "12/29/"
Dim datecheck1 As String = "12/30/"
Dim datecheck2 As String = "12/31/"
' Add Current Year to Date to Check variables
datecheck = datecheck + year
datecheck1 = datecheck1 + year
datecheck2 = datecheck2 + year
Dim expenddt As Date = Date.ParseExact(date1, date1, System.Globalization.DateTimeFormatInfo.InvariantInfo)
Dim expenddt1 As Date = Date.ParseExact(datecheck, datecheck,
System.Globalization.DateTimeFormatInfo.InvariantInfo)
Dim expenddt2 As Date = Date.ParseExact(datecheck1, datecheck1,
System.Globalization.DateTimeFormatInfo.InvariantInfo)
Dim expenddt3 As Date = Date.ParseExact(datecheck2, datecheck2,
System.Globalization.DateTimeFormatInfo.InvariantInfo)
' If DEC 29 or 30 Falls Fiday, Display Reset Button
If date1 = datecheck And dayofweek = "Friday" Then
' MsgBox Used Only For Testing
MsgBox("THIS ONE WORKED!")
Form2.Reset.Visible = True
End If
If date1 = datecheck1 And dayofweek = "Friday" Then
' MsgBox Used Only For Testing
MsgBox("THIS ONE WORKED!!")
Form2.Reset.Visible = True
End If
' If it's Dec 31 and it's Not Saturday or Sunday, Display Reset Button
If date1 = datecheck2 and dayofweek <> "Saturday" and dayofweek <> "Sunday" Then
' MsgBox Used Only For Testing
MsgBox("THIS ONE WORKED!!!")
Form2.Reset.Visible = True
End If
End Sub
First things first, have a read through the documentation for the DateTime structure. You can do everything that you're trying to do without using Strings. The DateTime structure has a DayOfWeek property, and Month and Day properties that will help you here.
Secondly, the way you are using the ParseExact method is wrong (not that you should end up using it). The second parameter to the ParseExact method is the format string that you expect the date to be in (something like "MM/dd/yyyy"). Passing in a formatted date will not work, and from my experiments, will simply return the current date without any parsing occurring.
So, with all that in mind (and assuming you want to show the button on the last weekday in the year as your code suggests, and not just the last day in the year as your question stated), try something like this:
Private Sub Main_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Form2.Reset.Visible = ShouldShowResetButton(DateTime.Now)
End Sub
Private Function ShouldShowResetButton(currentDate As DateTime) As Boolean
Return GetLastWeekdayInYear(currentDate.Year) = currentDate.Date
End Function
Private Function GetLastWeekdayInYear(year As Integer) As Date
Dim lastDayInYear As Date
lastDayInYear = New Date(year, 12, 31)
Select Case lastDayInYear.DayOfWeek
Case DayOfWeek.Sunday
Return New Date(year, 12, 29)
Case DayOfWeek.Saturday
Return New Date(year, 12, 30)
Case Else
Return lastDayInYear
End Select
End Function

How to set 2 different time display in textbox

I have 2 textbox in vb.net form.
In one textbox it displays system time.
In second textbox i want to display time that is 2 hrs later than system time.
How can i do that with timespan.
Does it have to be a timespan? You can do it with a Date variable.
Dim dt As Date = Date.Now
textbox1.Text = dt.ToString()
textbox2.Text = AddTimeZoneDiff(2, dt)
Private Function AddTimeZoneDiff(offset As Double, dt As Date) As String
Return dt.AddHours(offset).ToShortTimeString()
End Function