Setting Min Value of a Date cell of UltraWinGrid - vb.net

I have an UltraWinGrid in one of my forms that is used for the user to enter VAT rates into. There are 3 columns:
Rate
Date From
Date To
I need to validate the grid so that if there is a value entered in the "Date From" cell of a row, the user can only enter a minimum value of the "Date From" value + 1 day.
In which method would this go? And how do I do it?
I have tried doing
Private Sub ugVatRates_BeforeCellActivate(sender As Object, e As CancelableCellEventArgs) Handles ugVatRates.BeforeCellActivate
Dim dateFrom As Date
If IsDBNull(e.Cell.Row.Cells("DateFrom").Value) = False OrElse e.Cell.Row.Cells("DateFrom").Value <> Nothing Then
dateFrom = e.Cell.Row.Cells("DateFrom").Value
e.Cell.Row.Cells("DateTo").MinValue = dateFrom.AddDays(1)
End If
End Sub
However, MinValue is not a valid property here - Any advice?

Yes, MinValue and MaxValue are only exposed by UltraGridColumn. However, this will not work in your case. What you can do is handle BeforeCellUpdate event. In this event check if the cell user tries to update is DateTo cell as well as in DateFrom has value. If so you may suppress accepting of the new value by setting e.Cancel to true like this:
Private Sub ugVatRates_BeforeCellActivate(sender As Object, e As Infragistics.Win.UltraWinGrid.BeforeCellUpdateEventArgs) Handles ugVatRates.BeforeCellUpdate
If e.Cell.Column.Header.Caption = "DateTo" Then
Dim dateFrom As Date
Dim dateTo As Date
If IsDBNull(e.Cell.Row.Cells("DateFrom").Value) = False OrElse e.Cell.Row.Cells("DateFrom").Value <> Nothing Then
dateFrom = e.Cell.Row.Cells("DateFrom").Value
dateTo = Date.Parse(e.Cell.Row.Cells("DateTo").Text)
If dateTo < dateFrom.AddDays(1) Then
' Suppress accepting of new value
e.Cancel = True
End If
End If
End If
End Sub
When the user enters invalid date you may show a message box to inform him, or use UltraGrid's Data Validation.

Related

Get monday of current week based on userform input

I am very new to VBA, so please bear with me. I have a userform that is going to eventually create a 2 or 6 week schedule look ahead. The userform has a textbox which automatically populates the Monday of the current week as the lookahead start date. If the user inputs a date, it will use that date as the lookahead start date instead.
The part I can't seem to figure out, is the formula so that when the user inputs a date, it calculates the Monday of that week.
The code:
Private Sub UserForm_Initialize()
'Inserts date of Monday this week into "Start Date" field in UserForm
LookAheadDate1.Value = Date - Weekday(Date) + 2
End Sub
Private Sub Generate_Click()
Dim StartDate As Date
Dim EndDate As Date
Dim ws As Worksheet
Dim addme As Long
Set ws = Worksheets("Projects")
addme = ws.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
' Clears Look Ahead sheet - Row 5 and below
With Sheets("Look Ahead")
.Rows(5 & ":" & .Rows.Count).Delete
End With
'Force user to select either option button
If ((Me.OptionButton1.Value = 0) * (Me.OptionButton2.Value = 0)) Then
MsgBox "Please select 2 or 6 Week Look Ahead"
End If
'Force user to select either option button
If ((Me.OptionButton1.Value)) Then
ThisWorkbook.Worksheets("Look Ahead").Range("E6").Value = "2 Week Look Ahead"
End If
If ((Me.OptionButton2.Value)) Then
ThisWorkbook.Worksheets("Look Ahead").Range("E6").Value = "6 Week Look Ahead"
End If
' Set StartDate Variable - If Start Date field value is blank, use this weeks start date, otherwise use start date field value
If IsNull(Me.LookAheadDate1.Value) Or Me.LookAheadDate1.Value = "" Then
StartDate = Date
Else
StartDate = LookAheadDate1.Value
End If
' Option buttons / Code to create end date for 2 or 6 week look ahead
Dim res As Date
If OptionButton1.Value Then
EndDate = StartDate - Weekday(Date) + 16
ElseIf OptionButton2.Value Then
EndDate = StartDate - Weekday(Date) + 44
End If
'Write Look Ahead date range in cell "E7"
ThisWorkbook.Worksheets("Look Ahead").Range("E7").Value = StartDate - Weekday(Date) + 2 & " to " & EndDate
'Clear all fields in UserForm
Dim oneControl As Object
For Each oneControl In ProjectData.Controls
Select Case TypeName(oneControl)
Case "TextBox"
oneControl.Text = vbNullString
Case "CheckBox"
oneControl.Value = False
End Select
Next oneControl
'Close UserForm.
Unload Me
End Sub
Private Sub ToggleButton1_Click()
End Sub
Private Sub UserForm_Click()
End Sub
Private Sub LookAheadDate1_Change()
End Sub
Private Sub Cancel_Click()
'Close UserForm if "Cancel" Button is pressed
Unload Me
End Sub
'Checks for entry of valid date
Private Sub LookAheadDate1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If LookAheadDate1 = vbNullString Then Exit Sub
If IsDate(LookAheadDate1) Then
LookAheadDate1 = Format(LookAheadDate1, "Short Date")
Else
MsgBox "Please Enter Valid Date"
Cancel = True
End If
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
'If the user clicks the "X" to close the UserForm, then cancel
If CloseMode = 0 Then Cancel_Click
End Sub
If I understand your question about the date correctly, you want to edit this block of your code:
If IsNull(Me.LookAheadDate1.Value) Or Me.LookAheadDate1.Value = "" Then
StartDate = Date ' <--- this is where you want Monday, right?
Else
StartDate = LookAheadDate1.Value
End If
If so, replace the marked line with
StartDate = Date - Application.WorksheetFunction.Weekday(Date,3)
to get the date of Monday of this week as the StartDate.
Date returns the current date (similar to Now, but without the time part)
The use of Weekday (=WEEKDAY()) to get Monday is from this answer by Paul
Edit
In the Else branch:
Dim enteredDate as Date
enteredDate = CDate(LookAheadDate1.Value)
StartDate = enteredDate - Application.WorksheetFunction.Weekday(enteredDate,3)
CDate converts from text to date according to the current locale. You may need to parse the date text manually if you need a more sophisticated conversion.
I believe LookAheadDate1 is a text box because I see you are giving it a value using Format(..., "Short Date"). If it is a date/time picker, you may not need the CDate call.
I got it working. I added a calendar date picker to input the date into the textbox. Thanks for the help!

How to add 1 month to selected DateTimePicker

I'm having an issue with DateTimePicker.
What I am currently trying to do is based off of what text is in lblPrevSem(Previous Semester), which is getting its selection from a drop down on a previous screen, i want to add a certain amount of time to the DateTimePicker.
Public Property CustomFormat As String
Dim SemesterMonths As Integer
Dim SemesterDays As Integer
Private Sub DeptCreatePrevSch_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim SemesterYear() As String = DeptPrevSch.CboSem.Text.Split(",")
lblPrevSem.Text = SemesterYear(0)
cboYear.Text = Date.Now.Year
For i As Integer = 0 To 5
cboYear.Items.Add(Date.Now.Year + i)
cboYear.SelectedIndex = 0
Next
If InStr(lblPrevSem.Text, "Fall") Then
SemesterMonths = 1
ElseIf InStr(lblPrevSem.Text, "Spring") Then
SemesterMonths = 1
ElseIf InStr(lblPrevSem.Text, "Summer") Then
SemesterDays = 14
End If
Call dtpStart_ValueChanged(sender, e)
End Sub
Private Sub dtpStart_ValueChanged(sender As Object, e As EventArgs) Handles dtpStart.ValueChanged
Dim StartDate As Date
Dim StartStringDate As String
Dim EndDate As Date
Dim EndStringDate As String
dtpStart.Format = DateTimePickerFormat.Custom
dtpStart.CustomFormat = "MMMM dd, yyyy dddd"
StartDate = dtpStart.Value.ToString
StartStringDate = StartDate.ToString("MMMM dd, yyyy dddd")
lblRegStartDate.Text = StartStringDate
EndDate = dtpStart.Value.AddMonths(SemesterMonths)
EndDate = dtpStart.Value.AddDays(SemesterDays)
EndStringDate = EndDate.ToString("MMMM dd, yyyy dddd")
lblRegEndDate.Text = EndStringDate
End Sub
I can get it to add in days just fine but when ever i try and add in 1 month, it doesn't seem to work at all.
I've tried multiple different ways to add in a 1 month but nothing so far has worked. The closet ive been was adding in 30 days but then that doesn't account for months that have 31 days.
Reg Start Date is what ever the DateTimePicker is and Reg End Date should be the added days based off of what lblPrevSem is
Both Reg Start/End Date are displayed as labels
(i.e. Fall = 1 Month, Spring = 1 Month, Summer = 2 Weeks)
Your problem is that you are resetting the value for EndDate after adding the SemesterMonths value. You should add the SemesterDays value to the EndDate variable, not reset the value of EndDate with dtpStart.Value.AddDays(SemesterDays):
EndDate = dtpStart.Value.AddMonths(SemesterMonths)
EndDate = EndDate.AddDays(SemesterDays)
Just get the datetimepicker value and put .AddYears(0) or .AddDays(0) or AddMonths(0) behind it.
But you can also use them all at the same time.
nextServiceDateTimePicker.Value.AddYears(0).AddDays(0).AddMonths(0);
Just replace the 0 with lets say i and give it the value you need it to be.

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

Monthview Bolding Every Value

I created a Monthview and TimePicker in a form. I want the user to pick the time, and select a month which will bold the value selected each time, then select OK which will insert the value. I have all of this working fine. The issue is that if a user selects a date, then selects another date, or another date, all the dates are getting Bolded. I want the BOLD to only follow each most recent click.. if that makes sense, so that the user knows what value he chose.
Here is my click code:
Private Sub MonthView1_DateClick(ByVal DateClicked As Date)
Dim x As Date
x = MonthView1.value
MonthView1.DayBold(x) = True ' Bold the date
End Sub
What method do I need? Is there some kind of most-recent clicked property?
Try the following code:
Private Sub MonthView1_DateClick(ByVal DateClicked As Date)
Dim x As Date
Dim MaxDate As Date
Dim MinDate As Date
MinDate = DateSerial(Year(DateClicked), Month(DateClicked), 1) 'Get first date of current month based on clicked date
MaxDate = DateSerial(Year(DateClicked), Month(DateClicked) + 1, 0) 'Get last date of current month based on clicked date
x = ActiveCell.Value 'Retreive value of last Bold date
If x >= MinDate And x <= MaxDate Then 'If last Bold date is in the current month then unbold it
MonthView1.DayBold(x) = False
End If
MonthView1.DayBold(DateClicked) = True 'Bold the clicked date
ActiveCell.Value = DateClicked 'Store current date in a sheet
End Sub
The idea is to save the Bold date in a sheet (you may hide it if you wish) and retrieve it when another date is selected. The Bold formatting is removed from the previous date and applied to the current one.
a bit more on bolding in a MonthView
'<code>
Private Sub CommandButton1_Click()
Dim Ss(50) As Boolean
'put in module DaysToBold$ and DatesToBold$ as public variables
DaysToBold = "713" ' sat Sun Tue
' DaysToBold = "" ' for none
DatesToBold = "x,1,2,12,22,30"
' DatesToBold = "x" ' if none
MonthView21_GetDayBold Now, 49, Ss
End Sub
Private Sub MonthView21_GetDayBold(ByVal StartDate As Date, _
ByVal Count As Integer, State() As Boolean)
Dim I As Integer, Mi%, DTB, DI%, DAd%
On Error Resume Next ' seem to be negative indices into State() even if declared ( -10 to 50)
For Mi = 1 To Len(DaysToBold) ' mark of the Days of week to bold
I = Mid(DaysToBold, Mi, 1) ' single digits 1 ..7 excel translate to integer
While I < Count
State(I - MonthView21.StartOfWeek) = True
I = I + 7 ' down the column
Wend
Next Mi
DTB = Split(DatesToBold, ",")
If UBound(DTB) > 0 Then
With MonthView21
For I = 1 To UBound(DTB) ' mark the date numbers to bold
DI = Weekday(DateSerial(Year(.Value), Month(.Value), 1), .StartOfWeek)
If DI = 1 Then DAd = 5 Else DAd = -2 ' 7 days of last month there if Di=1
State(DTB(I) + DI + DAd) = True
Next I
End With
End If
End Sub
'</code>

Validating a date in a textbox

I am trying to valid user input in a textbox which will only takes dates or an empty value (hence the textbox vs a date time picker). Here are the conditions:
Only a date value ("dd-mm-yyyy" or "dd-mm-yy)
Must contain only slashes or numbers
The date has to be on the day it is being typed in
This is what I have so far:
Private Sub tbApp1_TextChanged(sender As System.Object, e As System.EventArgs) Handles tbApp1.TextChanged
If Not Me.tbApp1.Text = String.Empty Then
If Not DateTime.TryParseExact(tbApp1.Text.Trim, formats, New Globalization.CultureInfo("en-US"), Globalization.DateTimeStyles.None, dtTemp) Then
If Not tbApp1.Text.Trim = DateTime.Today.Date Then
ErrorProvider1.SetError(tbApp1, "This is not a valid date; Enter in this format ('M/d/yyyy' or 'M/d/yy')")
End If
Else
ErrorProvider1.Clear()
End If
ElseIf Me.tbApp1.Text.Trim = "" Then
ErrorProvider1.Clear()
End If
End Sub
Masked Textbox use
'Private Sub mtbApp1_TypeValidationCompleted(ByVal sender As Object, ByVal e As TypeValidationEventArgs) Handles mtbApp1.TypeValidationCompleted
If Not Me.mtbApp1.Text = String.Empty Then
If (Not e.IsValidInput) Then
ErrorProvider1.SetError(mtbApp1, "The data you supplied must be a valid date in the format mm/dd/yyyy.")
Else
' Now that the type has passed basic type validation, enforce more specific type rules.
Dim UserDate As DateTime = CDate(e.ReturnValue)
If (UserDate = DateTime.Now) Then
ErrorProvider1.SetError(mtbApp1, "The data you supplied must be today's date")
e.Cancel = True
End If
End If
ErrorProvider1.Clear()
End If
End Sub'
I noticed for a date like 03/18/2014 when it loaded back into the masked textbox it converts to 31/82/014. How could i fix this? The query pulls back the field as
CONVERT(VARCHAR(10),Date,101) AS Date
I set it in vb as :
Dim Approval1 As Date = Nothing
and then
If Not IsDBNull(((WorklistsDS.Tables(0).Rows(0).Item("Approval1")))) Then
Approval1 = ((WorklistsDS.Tables(0).Rows(0).Item("Approval1")))
End If
and then loaded into the masked textbox as:
If Approval1 <> Nothing Then
Me.mtbApp1.Text = Approval1
End If
You could also simplify your validation with
If IsDate(tbApp1.Text) Then
'valid date now just check if date falled within permitted range
Dim CompDate As Date = CDate(tbApp1.Text)
Dim MidDate As Date = *enter your min date here*
Dim MaxDate As Date = *enter your max date here*
If CompDate >= MinDate AndAlso CompDate <= MaxDate Then
'Date is within permitted range
......
Else
'Date outside range
'Display error
End If
Else
'text in tbApp1 is not a date
'Display Error
End If