0 引言
在筆者開發的“學籍管理系統”中,有一數據查詢模塊,其任務是查詢與浏覽設定條件的學生或班級數據,其中的“打印”按鈕功能是將顯示在表格中的內容打印出來。由於查詢結果中表與字段的是不固定的,使得利用VB本身自帶的數據庫報表難以實現動態打印,筆者經過對MSHFlexGrid控件、Printer對象的較深入學習、研究,遵循WINDOWS“所見即所得”的思想,有機結合二者編寫程序,實現了既能顯示查詢數據,又能根據MSHFlexGrid控件中的內容的實際大小進行快捷輸出,總體效果良好。
1 控件與打印技術簡介
1.1 MSHFlexGrid控件
Microsoft Hierarchical FlexGrid (MSHFlexGrid) 控件提供了類似EXCEL電子表格的功能,控件可對表格中數據進行顯示和操作,並且在對包含字符串和圖片的表格進行分類、合並以及格式化時,具有很強的靈活性。
MSHFlexGrid 控件中的 Cols 和 Rows 屬性決定了MSHFlexGrid 控件中的列數和行數,Row 和 Col 屬性指定了當前單元格,使用鼠標或者方向鍵可改變單元格的位置,TextMatrix(i, j)屬性為顯示網格中i行j列位置的文本內容,可進行讀寫賦值,表中單元格的列寬、行高分別由ColWidth 和RowHeight 屬性進行設定。MSHFlexGrid控件可用鼠標拖動實現對選中的行列進行行高、列寬的調整,也可通過編寫過程對表進行行高與列寬的統一設置。
1.2 打印技術
VB提供了三種技術用於打印正文和圖形:
①在窗體中建立所需要的輸出,然後調用 PrintForm 方法打印窗體。
②先設置 Printers 集合中的缺省打印機,再傳送正文和圖形到打印機。
③先傳送正文和圖形給Printer對象,再進行打印輸出。
因為Printer 對象是一個與設備無關的圖片空間,支持用Print、PSet、Line、PaintPicture和Circle方法來創建文本和圖形,並將文本和圖形與打印機的分辨率、功能進行了最佳的匹配,所以針對不同類型的打印機,Printer對象提供最好的打印質量。
采用 Printer 對象打印輸出,主要需設置 CurrentX 和 CurrentY 屬性,這兩個屬性決定 Printer 對象當前頁中的輸出位置,如果打印文檔內容較多時,則用NewPage方法進行換頁處理,最後用EndDoc方法結束文檔的打印。
2 實現思想
假設需打印的內容通過查詢已顯示在MSHFlexGrid控件中(如圖)。
由於MSHFlexGrid行列值(ColWidth、RowHeight )與Printer對象在輸出時默認行列值單位一致的,所以報表輸出只要結合A4紙的尺寸大小,統計出在MSHFlexGrid控件中的內容所需頁數、每頁的行、列位置,然後調用打印過程。
窗體打印過程Print_Grid1:根據MSHFlexGrid控件中行高、列寬及行列數,計算出每頁開始與結束的行、列位置及行、列方向所需的頁數,總的頁數為行列方向頁數相乘的積,然後以求得的每頁開始與結束的行、列位置為參數調用打印過程Print_Grid2。
過程Print_Grid2:為單頁打印,利用Printer對象,通過Print_Grid1的多次調用本過程,可將MSHFlexGrid控件上的數據逐頁全部打印輸出。
3 程序代碼
3.1 全部頁碼打印程序
Private Sub Print_Grid1()
Dim row(50), Col(50) As Integer '存放每頁開始的行、列序號
Dim PageRow, PageCol As Integer '行、列方向所需的頁數
Dim i, j, n, L As Integer
With MSHFlexGrid1
'確定每頁行開始、結束位置,行方向需要的頁數
PageRow = 0: L = .RowHeight(0): row(PageRow) = 1
For i = 1 To .Rows - 1
L = L + .RowHeight(i)
If L > 14000 Then
PageRow = PageRow + 1
row(PageRow) = i
L = .RowHeight(i) + .RowHeight(0)
End If
Next i
PageRow = PageRow + 1: row(PageRow) = .Rows
'確定每頁列開始、結束位置,列方向需要的頁數
PageCol = 0: L = .ColWidth(0): Col(PageCol) = 1
For j = 1 To .Cols - 1
L = L + .ColWidth(j)
If L > 10500 Then
PageCol = PageCol + 1
Col(PageCol) = j
L = .ColWidth(j) + .ColWidth(0)
End If
Next j
PageCol = PageCol + 1: Col(PageCol) = .Cols
'按先行後列打印,總頁數為PageRow×PageCol
n = 0
For i = 1 To PageRow
For j = 1 To PageCol
'調用打印一頁過程,參數為開始行、列,結束行、列
Print_Grid2 row(i - 1), row(i) - 1, Col(j - 1), Col(j) - 1
If PageRow + PageCol > 2 Then '若頁數大於2,右下角打印頁碼
n = n + 1
Printer.CurrentX = 10000: Printer.CurrentY = 15500
Printer.Print "第 " & n & " 頁"
End If
Printer.NewPage
Next j
Next i
End With
Printer.EndDoc
End Sub
' 注:因為打印是以缇為單位的,1厘米=567缇,A4紙大小29.7厘米21厘米,所以轉換為缇為單位的大小是16839.9缇×11907缇,打印中橫、縱向不能超過這二個數,上面程序設定橫不超邊14000缇,縱不超過10500缇,用變量L表示
3.2 打印單頁過程
Private Sub Print_Grid2(ByVal StartRow As Integer, ByVal EndRow As Integer, _
ByVal StartCol As Integer, ByVal EndCol As Integer)
Dim Px, Py, x1, y1, i, j As Integer
Dim L As Long, W As Long
x1 = 1000 : y1 = 1000 '設定表格線的左上基准點坐標位置,單位為缇
Px = 100 : Py = 50 '設置打印的數據離左表格線、上表格線的距離
With MSHFlexGrid1
'打印第一行
Printer.CurrentX = x1 + Px
Printer.CurrentY = y1 + Py
Printer.Print .TextMatrix(0, 0)
W = .ColWidth(0)
For j = StartCol To EndCol
Printer.CurrentX = x1 + W + Px
Printer.CurrentY = y1 + Py
Printer.Print .TextMatrix(0, j)
W = W + .ColWidth(j)
Next j
L = .RowHeight(0)
Printer.Line (x1, y1)-(x1 + W, y1)
Printer.Line (x1, y1 + L)-(x1 + W, y1 + L)
'各行數據,表格線
For i = StartRow To EndRow
Printer.CurrentX = x1 + Px '第一列
Printer.CurrentY = y1 + L + Py
Printer.Print .TextMatrix(i, 0)
W = .ColWidth(0)
For j = StartCol To EndCol
Printer.CurrentX = x1 + W + Px
Printer.CurrentY = y1 + L + Py
Printer.Print .TextMatrix(i, j)
W = W + .ColWidth(j)
Next j
L = L + .RowHeight(i)
Printer.Line (x1, L + y1)-(x1 + W, L + y1)
Next i
'豎線打印
Printer.Line (x1, y1)-(x1, L + y1)
W = 0
W = W + .ColWidth(0)
Printer.Line (x1 + W, y1)-(x1 + W, L + y1)
For j = StartCol To EndCol
W = W + .ColWidth(j)
Printer.Line (x1 + W, y1)-(x1 + W, L + y1)
Next j
End With
End Sub
4 結束語
利用MSHFlexGrid控件與Printer對象的配合,采用兩個過程,實現動態報表的顯示與打印,解決了其他方法在VB上難以實現的動態報表輸出問題,具有很強的實用性。