The Calendar Application
Initializing the Calandar, Page 3
I wanted my Calendar application to be able to be passed a parameter of a date and then be able to load and display the calendar positioned at the desired date. To achieve this I use a hidden label control (lblLastDate) that will hold the value of the parameter that is passed to it. The Change event of this control triggers the Calendar_do function to position the calendar to the date in the Caption property of the lblLastDate control.
Private Sub lblLastDate_Change()
If Not IsDate(lblLastDate) Then
lblLastDate = Date
End If
formisloading = True ' don't invoke combo Click events
cboMonth.ListIndex = Month(lblLastDate) - 1
cboYear.ListIndex = Year(lblLastDate) - Year(Date) + 10
formisloading = False ' enable combo Click events
Calendar_do Format(lblLastDate, "dd"), Str(cboMonth.ListIndex + 1),
cboYear.Text, Me
End Sub
The decision to change the caption property of the lblLastDate control (and
therefore trigger its Change event) is made in the form's load event.
Private Sub Form_Load()
Screen.MousePointer = 11
formisloading = True ' Prevent combo boxes from triggering Click events
during loading
cboYear_Init cboYear ' Fill the combo with a list of years
cboMonth_Init cboMonth ' Fill the combo with a list of months
lblDay_Init ' Set the names of the days of the week
If IsDate(Command$) Then ' Test the command line for a date
lblLastDate = Command$ ' Trigger lblLastDate_Change
' Make sure the date passed is in Long Date format
Else
lblLastDate = Date ' Default to todays date
End If
formisloading = False
Screen.MousePointer = 0
End Sub
(You may want to change the highlighted code above depending upon how
you want to implement the calendar component into you VB
applications.)
Whereas Delphi uses a grid control to imitate the outline of a calendar in VB I chose to use a Command button array so that I would not have to include any OCX controls when I distributed the application. Nor would I need to add a grid OCX to a project that did not use a grid control in the first place just to add the functionality of a calendar to my application.
Add an array of command buttons (37 buttons arranged in row's of 7, one for each day of the week). The caption property will display the day numbers of the chosen date. All code that decides which buttons to display and what the value of their captions will be occurs in the subroutine Calendar_do :
Sub Calendar_do(ByVal dy As String, ByVal m As String, ByVal Y As String, Frm
As Form)
' Calculates and sets the values of the calButton controls according
' the start day of the chosen month.
Dim k As Integer
Dim lmth As Integer
Dim DayOne As Variant
Dim Offset As Integer
shaButton.Visible = False ' hide the button highlight shape
DayOne = DateValue("1/" & m & "/" & Y) ' handles all date formats
Offset = WeekDay(DayOne) - 2 ' find the first button that will be visible
lmth = LenMonth(DayOne) ' find the number of buttons that will be displayed
For k = 0 To 37
If (k < 1 + Offset) Or k > Offset + lmth Then ' are they in range
Frm.CalButton(k).Caption = "" ' hide the button
Frm.CalButton(k).Visible = False
Else
Frm.CalButton(k).Visible = True ' show the button
Frm.CalButton(k).Caption = k - Offset ' set its caption value to the day number
End If
Next
calButton_Click (Offset + Val(dy)) ' Highlights the button of the selected date
End Sub
(The function above includes a form control as an argument in order to maintain
compatability with VBA implementations)
The completed Calendar form :
The Reload command button simply calls the form load event to refresh
the combo and label initialization routines so that the calendar
application could be tested when the international settings in the
Control folder where changed without having to restart the Visual
Basic session.
Users can navigate through dates by selecting the month and year from the dropdown lists or by clicking on the button corresponding to the day of the date.
The Click events of the combo boxes both call the Calendar_do utility to redisplay the button days in the correct order for the chosen Month/Year combination.
Sub cboMonth_Click() If formisloading Then Exit Sub ' don't do anything during form load event Screen.MousePointer = 11 Calendar_do "1", Str(cboMonth.ListIndex + 1), cboYear.Text, Me Screen.MousePointer = 0 End Sub Sub cboYear_Click() If formisloading Then Exit Sub Screen.MousePointer = 11 Calendar_do "1", Str(cboMonth.ListIndex + 1), cboYear.Text, Me Screen.MousePointer = 0 End Sub