Tutorials > VSPrinter Tutorial - Calendar > Step 2: Create the calendar |
To create the calendar, we will start with a base date, which will be stored in a global variable called TheDate.
Here is the code that declares the global variable and initializes it:
Example Title |
Copy Code
|
---|---|
Option Explicit
' base date used to build the calendar
Dim TheDate As Date
|
Example Title |
Copy Code
|
---|---|
Private Sub Form_Load() ' initialize date TheDate = Now ' show calendar ShowCalendar End Sub |
This code initializes the global variable to the current date and calls ShowCalendar, the main routine in this application, to generate the initial calendar. The ShowCalendar routine uses VSPrinter's table formatting properties to create the calendar. Here it is:
Example Title |
Copy Code
|
---|---|
Private Sub ShowCalendar() Dim r%, c% ' build calendar for the given date ' return TheDate's row and column in r, c ReDim cal(7, 1) As Variant BuildCalendar TheDate, cal, r, c ' start document vp.StartDoc ' start table, don't render till we're done vp.StartTable ' set header and bind to calendar array ' (use dummy column widths for now) vp.AddTableArray "||||||", _ "Sun|Mon|Tue|Wed|Thu|Fri|Sat", cal ' format table using the TableCell property: ' note that TableCell indices are 1-based ' set column widths and row heights to .8 in vp.TableCell(tcColWidth) = "0.8in" vp.TableCell(tcRowHeight) = "0.8in" ' align cells to center vp.TableCell(tcAlign) = taCenterMiddle ' set body font vp.TableCell(tcFontName) = "Times New Roman" vp.TableCell(tcFontSize) = 24 vp.TableCell(tcFontItalic) = True ' set Sunday back color vp.TableCell(tcBackColor, , 1) = vbRed ' format header row (week days) vp.TableCell(tcRowHeight, 0) = ".5in" vp.TableCell(tcFontBold, 0) = True vp.TableCell(tcFontItalic, 0) = False vp.TableCell(tcBackColor, 0) = vbBlue ' highlight today (note 1-based indices) vp.TableCell(tcFontBold, r + 1, c + 1) = True vp.TableCell(tcBackColor, r + 1, c + 1) = vbYellow ' append a row with the current month and year r = vp.TableCell(tcRows) + 1 vp.TableCell(tcRows) = r vp.TableCell(tcText, r, 1) = _ "Calendar for " & _ Format(TheDate, "mmmm yyyy") vp.TableCell(tcColSpan, r, 1) = 7 vp.TableCell(tcRowHeight, r) = ".5in" vp.TableCell(tcAlign, r) = taCenterMiddle vp.TableCell(tcBackColor, r) = vbBlue vp.TableCell(tcFont, r, 1) = _ vp.TableCell(tcFont, 0, 1) ' done, render the table vp.EndTable ' done, finish the document vp.EndDoc End Sub |
The ShowCalendar routine is not very complicated, but it deserves some explanation. Here's a breakdown of what each part does:
Example Title |
Copy Code
|
---|---|
' build calendar for the given date ' return TheDate's row and column in r, c ReDim cal(7, 1) As Variant BuildCalendar TheDate, cal, r, c |
This code dimensions a variant array that will contain the calendar data. It uses a separate auxiliary routine, BuildCalendar, which does most of the work. BuildCalendar fills out the variant array and returns in the r, c parameters the array indices that correspond to the given date.
Example Title |
Copy Code
|
---|---|
' start document
vp.StartDoc
|
This statement tells the VSPrinter control we want to create a new document. Because the Preview property is True by default, this will be a preview document and will not be sent to the printer immediately.
Example Title |
Copy Code
|
---|---|
' start table, don't render till we're done vp.StartTable |
This statement tells the VSPrinter control we want to create a new table. The control will build the table in memory, and will not render it until we issue the matching EndTable statement.
Example Title |
Copy Code
|
---|---|
' set header and bind to calendar array ' (use dummy column widths for now) vp.AddTableArray "||||||", _ "Sun|Mon|Tue|Wed|Thu|Fri|Sat", cal |
This statement builds a table with seven columns, and binds it to the data in the cal variant array. The contents of the array determine the number of table rows and the cell contents. Now we are ready to embellish the table using the TableCell property.
Example Title |
Copy Code
|
---|---|
' set column widths and row heights to .8 in vp.TableCell(tcColWidth) = "0.8in" vp.TableCell(tcRowHeight) = "0.8in" |
Here we set the width and height of all columns and rows to 0.8 inches. By omitting indices in the call to TableCell, the setting applies to all elements. As with any other measurements, VSPrinter interprets the units. (The default unit is twips.)
Example Title |
Copy Code
|
---|---|
' align cells to center
vp.TableCell(tcAlign) = taCenterMiddle
|
Again, we omit the indices to align all table cells to the center. The valid settings for tcAlign are the same that apply to the TextAlign property.
Example Title |
Copy Code
|
---|---|
' set body font vp.TableCell(tcFontName) = "Times New Roman" vp.TableCell(tcFontSize) = 24 vp.TableCell(tcFontItalic) = True |
Setting the font for all table cells is similar to setting the alignment.
Example Title |
Copy Code
|
---|---|
' set Sunday back color
vp.TableCell(tcBackColor, , 1) = vbRed
|
This statement sets the background color for the first column (Sunday) to red. Note that the row argument was omitted, causing the setting to apply to the entire column, and the column argument was set to one, since table indices are one-based.
Example Title |
Copy Code
|
---|---|
' format header row (week days) vp.TableCell(tcRowHeight, 0) = ".5in" vp.TableCell(tcFontBold, 0) = True vp.TableCell(tcFontItalic, 0) = False vp.TableCell(tcBackColor, 0) = vbBlue |
This code formats the header row, which has index zero. It sets the font, row height, and background color.
Example Title |
Copy Code
|
---|---|
' highlight today (note 1-based indices)
vp.TableCell(tcFontBold, r + 1, c + 1) = True
vp.TableCell(tcBackColor, r + 1, c + 1) = vbYellow
|
This line makes the base date, whose coordinates were returned by the call to BuildCalendar, bold on a yellow background.
Example Title |
Copy Code
|
---|---|
' append a row with the current month and year r = vp.TableCell(tcRows) + 1 vp.TableCell(tcRows) = r vp.TableCell(tcColSpan, r, 1) = 7 vp.TableCell(tcText, r, 1) = _ "Calendar for " & _ Format(TheDate, "mmmm yyyy") |
This code appends a row to the table by writing to the tcRows attribute. Then it sets the tcColSpan attribute of the first cell to 7, causing it to span the entire row. Finally, it sets the text of the first cell to a string containing the calendar's month and year. This illustrates how you can mix data that comes from the array with custom data.
Example Title |
Copy Code
|
---|---|
vp.TableCell(tcRowHeight, r) = ".5in"
vp.TableCell(tcAlign, r) = taCenterMiddle
vp.TableCell(tcBackColor, r) = vbBlue
vp.TableCell(tcFont, r, 1) = _
vp.TableCell(tcFont, 0, 1)
|
Finally, the row that was just appended to the table is formatted. Note how the font is set with a single reference to the tcFont attribute, which is faster and more concise than copying the font's name, size, and so on.
Example Title |
Copy Code
|
---|---|
' done, render the table
vp.EndTable
|
This statement closes the table that was started with the StartTable statement and renders it on the document.
Example Title |
Copy Code
|
---|---|
' done, finish the document
vp.EndDoc
|
This statement tells the VSPrinter control we are done creating the document. At this point, the document is available for previewing, saving to disk, or sending to the printer.
The NavBar property is set to vbnpBottom by default, so the control will display a navigation bar so the user can flip preview pages and zoom with the mouse. The Navigation property is set to vpnvMouseWheel by default, so the user can scroll the preview using the mouse and the mouse wheel.
That was a lot of code, but well worth it because it covers most aspects of advanced table formatting in VSPrinter. We are still missing the BuildCalendar routine, which is pretty simple:
Example Title |
Copy Code
|
---|---|
Private Sub BuildCalendar(TheDay As Date, _ ByRef TheCal(), _ ByRef TheDayRow, ByRef TheDayCol) Dim dt As Date ' clear array ReDim TheCal(7, 1) ' initialize date to the first of the month dt = TheDay While Day(dt) > 1 dt = dt - 1 Wend ' fill array with dates for current month Dim r%, c% r = 0 c = WeekDay(dt) - 1 While Month(dt) = Month(TheDay) ' add row if we have to If c >= 7 Then c = 0 r = r + 1 ReDim Preserve TheCal(7, r) End If ' save day value in the calendar TheCal(c, r) = Day(dt) ' return TheDate's row and column If dt = TheDay Then TheDayRow = r TheDayCol = c End If ' increment day dt = dt + 1 c = c + 1 Wend End Sub |