Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Form That Displays Data As a Calendar 5

Status
Not open for further replies.

rickj65

Programmer
Jun 5, 2002
79
0
0
US
I've just created an extremely useful and relatively simple form that displays like a 35-box (7-days Sun-Sat across by 5 weeks down) wall calendar. You could easily customize it to be a 42-box calendar if desired.

In the 35-box calendar, for 30 and 31-day months where the first day of the month begins on a Fri. or Sat. and causes the last day or 2 of the month to overflow to a 6th row, I have those days appear back in the first row of the calendar.

The form is set up with 35 text boxes to capture the numeric day of the month, and superimposed in front of the text boxes are 35 corresponding list boxes that display the detailed data you wish to display for that day.

A user selects the month from a dropdown box and the year from a text box both located in the form header. After selecting the month and year, the calendar form refreshes to properly display the correct dates in the correct place on the calendar. The listbox data is filtered according to the date of the particular calendar box so that it only displays the data for that day...assuming there is data on that date. If not, it is just left blank...displaying the numerical day of the month.

The list box displaying the data is obviously compact (approx 1 3/4" wide by 2" tall) due to screen size restraints, but utilizes the horizontal and vertical scroll bars so that when you click on a particular day, you can view more data than what is actually initially displayed initially on the calendar. It at least provides the user an initial view that there is data on that date to be viewed.

I am using this form to display a monthly calendar view of activities that salespeople have done on any day in the month. I'm only displaying the salesperson's last name and the account they visited/contacted on that date. When a user clicks on that particular activity (which is a row in the appropriate list box filtered by the date it applies to), it will open up the detail form of that activity. Since I'm using horizontal and vertical scroll bars in each of the 35 day listboxes, you can probably add more information, but I kept it to 2 data fields cause that was all I really needed to display.

Really the only requirement you would need to use this form for your own purposes is that the query (or table) used as the row source of the listbox must include a date field. You would tailor your query to fit within the constructs of the form I created (simpler than it sounds), and then with a couple of minor customizations you should be good to go.

I was really psyched about the solution I came up because for years I've been asked by clients for something similar. In addition, it looks completely professional despite its simplicity. I'm willing to share it with anyone who needs it. I'm not looking for anything in return except some positive karma. I post this just as a thank you to all of the people who in this forum who anonymously helped me with their tips and code in the past.

Regards,

Rick

PS - Note that the same concept would work to make a calendar display report; however, a report doesn't have the luxury of horizontal and vertical scroll bars, so space is really an issue with reports.
 
Whule I applaud your initiave, soloutions to this issue have been posted on thes and many other fora over many years. Doing it yourself has some advantage, but there are also advantages in seeing how others have accomplished similar execrises.



MichaelRed


 
Anybody who presents a concept to share, even if similar ideas have been posted before, deserves praise. New members might not yet know how to search our great resource yet and this posting by rickj65 could inspire them to look at different ways to do the same thing. We all have our own preferences for how we want our applications to look and behave. Thanks rickj65.
 
I would like to have a copy of the form along with the code. I too have been trying to develope such a form.

Thanks
MrBigO
 
I wouild also like a copy of what you have done, along with the code
Please
Thanks
 
There was a time in Tek-Tips that I used to e-mail other members with solutions. I guess that policy has changed because I don't see how to e-mail other users and the site's privacy policy discourages posting e-mail addresses. That's a shame because sometimes describing a solution and providing code isn't as easy as simply sending a file with the solution.

In any event, tomorrow I'll post the code (there's very little) and describe how to set up the form.

Rick

 
where is the listbox situated? does it appear from the date selected or is it beside the calendar? I'd be interested to know because I've been working on several calendar stlye forms and there various guises myself.


Program Error
Programmers do it one finger at a time!
 
OK, here is how you set up the calendar form:

I linked to the Northwinds Customers, Orders and Employees tables for this example.

I set up the form (frmCalendar) as follows:

1. In the header put a dropdown list box (cboMonth) containing two columns for the numerical and text values for all 12 months.

RowSourceType = "Value List",
RowSource = 1;"January";2;"February";3;"March"...etc.
Columns = 2
ColumnWidths = 0";1"

2. In the header add a text box (txtYear) with a default value = Year(Date()).

3. Set the back color of the form's detail section to white (16777215). In the detail section create a row of seven square unbound text boxes without labels. Mine have a height of 1.7292" and width of 1.6875". They are all lined up next to each other without any spaces between them, so that they display one single line as the border between each of them. The backstyle of these text boxes is = transparent. Name each text box txt1, txt2, txt3, txt4, etc. from left to right. The font properties are Tahoma, Size = 8, Weight = bold, but you can customize this to your preference.

The purpose of these text boxes is to display the number date 1 through 31 where/when appropriate.

4. Superimposed in front of each text box create an unbound listbox (it's easier to create one and then just copy it 6 more times) that is two pixels narrower than the text box so that the list box does not block the border of the text in back of it. Shorten the height of the list box so that you can clearly view "Unbound" in the text box in back of it. My list boxes have a height of 1.5417". The border style is transparent, the back color is white, font = Tahoma, size 8, Weight = normal.

Regarding the data that you will be displaying: I am displaying 2 fields in the list box (Salesperson and Account) from my own table, so if you wish to display more or less data, you'll have to customize these properties accordingly. My column count = 5 (2, displayed columns and 3 hidden columns), column widths = 0";0.5625";1.2709";0";0", column heads = No.

Name each list box lst1, lst2, lst3, etc. across so that lst1 is superimposed on txt1, lst2 is superimposed on txt2, etc.

5. Once you have all 7 list boxes and text boxes lined up exactly the way you want them, copy the entire row and make 4 more rows of listboxes and textboxes beneath the orignal row. You should now have 35 total boxes (5 rows x 7 columns). Name all of the remaining list and text boxes in numerical order continuing from lst8 and txt8, etc. through to lst35 and txt35.

6. In the form header, place 7 labels for each day of the week Sunday through Saturday just above each column of list boxes. Mine are transparent, Tahoma 8 bold with a black border that is as wide as the column of text boxes beneath it.

7. For Sunday and Saturday (the first and seventh columns), I actually made the text box with a yellow back color and a normal back style so that the weekdays and weekends are visually separate.

8. Data/Query: Create a query named qryCalendar with the following SQL:

SELECT Orders.OrderDate, Employees.LastName, Customers.CompanyName, Format([OrderDate],"myyyy") AS myyyy, Day([OrderDate]) AS calendar_day
FROM Employees INNER JOIN (Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID) ON Employees.EmployeeID = Orders.EmployeeID;

Note that I'm only going to be displaying the Employee's last name and the Company name in the calendar's list boxes that the order applied to. The other fields will be hidden in the list boxes. If you wanted to display more or less fields, you'd have to revise this query and revise the column count and column widths properties of all of the listbox controls accordingly. The key is to always include the calendar_day and myyyy fields of the query.

OK...the hard part is done. Now just add the code below:



9. Create a module (basCalendarFunctions) and add the following:

Option Compare Database
Option Explicit

Public Function EndOfMonth(EvalDate As Date) As Date
On Error GoTo Err_EndOfMonth

'------------------------------------------------------------------------------
'PURPOSE: Returns the last day of the month for the date value passed
'ACCEPTS: EvalDate = Date to evaluate
'RETURNS: Last day of the month as a date
'------------------------------------------------------------------------------

EndOfMonth = DateAdd("m", 1, DateSerial(Year(EvalDate), Month(EvalDate), 1)) - 1

Exit_EndOfMonth:
Exit Function

Err_EndOfMonth:
MsgBox Err & " - " & Err.Description, 48, "EndOfMonth"
Resume Exit_EndOfMonth

End Function

Public Function CalendarBox(EvalDate As Date) As Integer
On Error GoTo Err_CalendarBox

'------------------------------------------------------------------------------
'PURPOSE: Used for determining the box number (not the day #) that a date will
' display in a 35 box (7-column by 5-row) calendar. This is used to
' dynamically build calendar forms and reports.
'ACCEPTS: EvalDate = Date to evaluate
'RETURNS: Integer of the box number.
'CREATED: 5/5/2005
'NOTES: This assumes the first day of the month is Sunday, both in the calendar
' display and in VB/VBA for the WeekDay() Function.

' In a month like May, 2004, the first day of the week falls on Saturday
' (box 7) and lasts 31 days. Since this is used for a 35-box calendar
' rather than a 42-box calendar, Sunday the 30th wraps back to the top
' of the calendar into box 1 and Monday the 31st wraps back to box 2.
' In order to accomplish this, I subtracted 35 if the Calendar Box was
' going to be greater than 35.
'------------------------------------------------------------------------------

Dim intBox As Integer

'-------------------------------------------------------------------------------------
'Take the starting day of the month, add the day of the month and subtract 1 to
'get the calendar box that the date falls in
'-------------------------------------------------------------------------------------
intBox = (Weekday(DateSerial(Year(EvalDate), Month(EvalDate), 1)) _
+ Day(EvalDate)) - 1

'-------------------------------------------------------------------------------------
'If CalendarBox is going to be > 35, then subtract 35 from the result so that
'the CalendarBox is either 1 or 2...wrapping around to the top of the Calendar
'to display the last one or 2 days without needing a 6th row in the calendar form.
'-------------------------------------------------------------------------------------
If intBox > 35 Then
CalendarBox = intBox - 35
Else
CalendarBox = intBox
End If

Exit_CalendarBox:
Exit Function

Err_CalendarBox:
MsgBox Err & " - " & Err.Description, 48, "CalendarBox"
Resume Exit_CalendarBox

End Function



10. Add the following code behind the frmCalendar form (hopefully the comments explain enough how it works):

Option Compare Database
Option Explicit

Private Sub BuildCalendar()
On Error GoTo Err_BuildCalendar

'-------------------------------------------------------------------------
'PURPOSE: Loops through all days of the month for the month and year
' selected, and assigns the day value in the appropriate calendar
' box and then filters the list box to display the data applicable
' on that date.
'CREATED: 5/5/2005
'-------------------------------------------------------------------------

'-------------------------------------------------------------------------
'Declare, verify and set variables
'-------------------------------------------------------------------------

Dim dtEvalDate As Date
Dim dtMonthEnd As Date
Dim strListName As String
Dim strSQL As String
Dim intCBox As Integer
Dim i As Integer
Dim strMsg As String

If IsNull(Me.cboMonth) Then
strMsg = "You must select a month."
MsgBox strMsg, vbOKOnly + vbInformation, "Invalid Parameter"
Exit Sub
ElseIf Me.txtYear < 1900 And Me.txtYear > 9999 Then
strMsg = "You must enter a valid year."
MsgBox strMsg, vbOKOnly + vbInformation, "Invalid Parameter"
Exit Sub
End If

dtEvalDate = DateSerial(Me.txtYear, Me.cboMonth, 1) 'First day of the month
dtMonthEnd = EndOfMonth(dtEvalDate) 'Last day of the month

'-------------------------------------------------------------------------
'Clear out list box row source and text box
'-------------------------------------------------------------------------

For i = 1 To 35
Me("lst" & i).RowSource = "SELECT * FROM qryCalendar WHERE True = False"
Me("txt" & i) = Null
Next i

'-------------------------------------------------------------------------
'Loop through all days in the month, determine the applicable calendar
'box, set the day number of the calendar, and dynamically create the
'row source for the list box making up that calendar box.
'-------------------------------------------------------------------------

Do While dtEvalDate <= dtMonthEnd
intCBox = CalendarBox(dtEvalDate) 'Get the calendar box
Me("txt" & intCBox) = Day(dtEvalDate) 'Set the Day number in the calendar box
strSQL = "SELECT * FROM qryCalendar " & _
"WHERE myyyy = " & Me.cboMonth & Me.txtYear & _
" AND calendar_day = " & Day(dtEvalDate) 'Dynamically filter row source of the day's listbox
Me("lst" & intCBox).RowSource = strSQL 'Set the row source
dtEvalDate = dtEvalDate + 1 'increment the day
Loop

Exit_BuildCalendar:
Exit Sub

Err_BuildCalendar:
MsgBox Err & " - " & Err.Description, 48, "BuildCalendar"
Resume Exit_BuildCalendar

End Sub


Private Sub cboMonth_AfterUpdate()
On Error GoTo Err_cboMonth_AfterUpdate

If Not IsNull(Me.cboMonth) Then
BuildCalendar
End If

Exit_cboMonth_AfterUpdate:
Exit Sub

Err_cboMonth_AfterUpdate:
MsgBox Err & " - " & Err.Description, 48, "cboMonth_AfterUpdate"
Resume Exit_cboMonth_AfterUpdate

End Sub

Private Sub txtYear_AfterUpdate()

If Not IsNull(Me.txtYear) Then
BuildCalendar
End If

End Sub



11. To test the form, select any month in 1998 (since that is when the Northwinds data occurred). Each month will display the Salesperson name and Customer on each date that an order was made. In theory, you could add a Double-Click event on the list box and call up the actual Order Form that the user clicked on.

Hopefully I didn't forget anything here. Again, it would've been easier if I could've just e-mailed the solution, but that's a limitation in Tek-Tips I guess.

Regards,

Rick


 
Bocker - The form is similar in concept to the one you linked. The calendar I created is not for entering data, just displaying it, but in concept you can create either.
 
rickj65,

Thanks for posting this solution. Although there have been many links and discussions related to creating calendars, this one seems better suited to my needs.

I know that you posted this back in May, but hopefully you’re still around to take a question.

I’m new to Access programming so I apologize if I’ve missed something obvious. I tried to recreate your solution (using the Northwinds database), but I’m hitting a problem I’m unable to identify. I followed your steps, but the form doesn’t retrieve the data or populate the days. Do you have any suggestions for things I may have done wrong?

Thank you.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top