---- 一. 概述
---- 幾乎所有數據庫應用軟件,都需要打印單證和報表。常見的方法是利用VB的Crystal Reports(水晶報表)方式,通過TextBox等數據綁定控件,調用Print方法直接輸出。雖然Crystal Report這一個功能強大、樣式豐富且無編程方式的報表編制程序能適應大部分單證、報表打印的需要,但是Crystal Reports引擎是一個動態鏈接庫,需許多文件支持和調用更多系統資源,大大增加系統負擔。
---- 另一種解決辦法是通過Printer對象的Print方法,直接打印字符串。這雖然減少了系統資源的開銷,但它不能直接用于打印復雜的單證和報表。本文通過兩個實例,闡述一個通用折行打印程序的編程和在單證及報表的應用。
---- 二. 編程實現及實例
---- 為便于闡述的方便,我們先建立一個Access數據庫Standards.mdb,其內SN表由以下幾個字段組成:
---- 標準號(文本,17)
---- 標準名稱(文本,255)
---- 英文名稱(文本,255)
---- 實施日期(日期,8)
---- 修定日期(日期,8)
---- 發布日期(日期,8)
---- 代替標準(文本,50)
---- 通用折行打印程序編制操作如下:
---- 1.在VB5.0編程環境中,新建一個工程Project1;
---- 2. 在Project1中添加Moduel,在Moduel模塊中定義一個記錄最大折行數的公用變量Rowlab和Function函數(以下程序都經過實際運行測試,可以原樣復制使用);
Public rowlab As Integer '定義一個公用變量 Function prnt11(X As Integer, Y As Integer,Font As Single, Txt As String, Val As Integer) Dim str As String, str1 As String, str2 As String ,i As Integer Printer.CurrentX = X Printer.CurrentY = Y Printer.FontBold = False Printer.FontSize = font str = txt str2 = str i = 0 rowlab = 0 If Len(Trim(str)) = 0 Then rowlab = 1 '待打印字符串為空的標志 Else Do While Len(str) > 0 Printer.CurrentX = X Printer.CurrentY = Y + rowlab * 240 rowlab = rowlab + 1 If Len(str) >= val Then str1 = Mid(str, 1, val) Printer.Print str1 i = i + 1 str = Mid(str2, i * val + 1) Else Printer.Print str Exit Do End If Loop End If End Function
---- 3. 在Project1中新建一個窗體Form1,窗體上添加一個Data控件Data1,一個MSFlexGrid控件MSFGrid1,7個 TextBox和兩個命令按鈕CmdPrnt1、CmdPrnt2。設置Data控件的屬性:
.. DatabaseName="Standards.mdb" ..RecordSourse="SN" MSFGrid1屬性: .DataSource="Data1" Text1屬性: .DataSource="Data1" .DataField="標準號" Text2~Text7類同。
---- CmdPrnt1、CmdPrnt2分別為打印單條記錄和多條記錄的按鈕。
---- 實例1:文字串定位折行打印在口岸聯檢部門中應用非常廣泛。下述例子是用CmdPrnt1的Click事件代碼實現了對文字串定位折行打。
Private Sub CmdPrnt1_Click() Dim str As String, str1 As String ,txt As String Dim strx As Integer, stry As Integer,i As Integer strx = 200 stry = 0 txt = Space(20) + "中國出入境檢驗檢疫標準目錄檢索STEMS 2000" Printer.FontName = "黑體" dd = prnt11(strx, stry, 10, txt, 50) stry = stry + rowlab * 240 Printer.Line (0, stry)-(9000, stry) Printer.FontName = "宋體" txt = "標準號:" + Space(2) + Trim(Text1) + Space(3) + "發布日期:" + Trim(Text4) + Space(3) + "實施日期:" + Trim(Text6) + Space(3) + "修定日期:" + Trim(Text5) '+ Chr(13) stry = stry + 240 dd = prnt11(strx, stry, 10, txt, 70) stry = stry + rowlab * 240 txt = "代替標準:" dd = prnt11(strx, stry, 10, txt, 10) dd = prnt11(strx + 1000, stry, 10, Trim(Text7), 60) stry = stry + rowlab * 240 txt = "標準名稱:" dd = prnt11(strx, stry, 10, txt, 10) dd = prnt11(strx + 1000, stry, 10, Trim(Text4), 38) stry = stry + rowlab * 240 txt = "英文名稱:" dd = prnt11(strx, stry, 10, txt, 10) dd = prnt11(strx + 1000, stry, 10, Text5, 72) Printer.EndDoc End Sub
---- 注: Prnt11函數原形:prnt11(X As Integer, Y As Integer, Font As Single, Txt As String, Val As Integer),其各參數含義如下:
---- X、Y為待打印字符串左上角起始座標;
---- Font為字體大小;
---- Txt為待打印字符串;
---- Val為字符串打印折行長度。
---- 實例2:直接打印表格式窗體顯示的多記錄多字段,往往因某些字段的字節太多而造成紙張寬度不足。以下 CmdPrnt2的Click事件中的代碼,實現了對上述MSFGrid1表格記錄的打印:
Private Sub CmdPrnt2_Click() Dim fnt As Single Dim pp As Integer Dim stry As Integer, strx As Integer Dim stry1 As Integer, strx1 As Integer, linw As Integer Dim page1 As Integer, p As Integer, gridrow As Integer, ii As Integer p = 0 ii = 1 'ii記錄MSFGRID1表格同一記錄內字段最大打印行 pp = 0 '開始頁碼 ss$ = "中國出入境檢驗檢疫標準目錄檢索STEMS 2000" ' 表頭 Static a(4) As Integer kan = 0 a(2) = 1680 a(3) = 2800 a(4) = 5300 page1 = 46 '定義每頁行數 strx = 200 strx1 = 200 stry = 1400 stry1 = 1400 linw = 240 '定義行寬 fnt = 10 '定義字體大小 For i = 2 To 4 kan = kan + a(i) Next gridrow = Datdatact1.Recordset.RecordCount If gridrow = 0 Then MsgBox "無滿足條件記錄打!" Exit Sub End If Printer.FontName = "黑體" dd = prnt11(3300, 700, fnt, ss$, 26) '打印標題 dd = prnt11(500, stry - 250, fnt, "標準號", 26) dd = prnt11(2690, stry - 250, fnt, "標準名稱", 26) dd = prnt11(6690, stry - 250, fnt, "英文名稱", 26) Printer.Line (strx - 20, stry - 30)-(10460, stry - 30) Printer.FontName = "宋體" For j = 1 To gridrow '打印gridrow條記錄 MSFGrid1.Row = j strx = strx1 For i = 2 To 4 '假設只打印2-3 列 MSFGrid1.Col = i dd = prnt11(strx, stry, fnt, MSFGrid1.Text, IIf(i = 3, 13, 55)) If ii < rowlab Then 'ii記錄同一記錄內字段最大打印行 ii = rowlab End If strx = strx + a(i) Next p = p + ii rowlab = ii ii = 1 '重新初始化 If p > page1 Then p = 0 strx = strx1 For n = 2 To 4 strx = strx + a(n) Next pp = pp + 1 stry = stry + rowlab * linw foot$ = "第" + CStr(pp) + "頁" dd = prnt11(strx / 2, stry + 3 * linw, 10, foot$, 26) stry = stry1 Printer.NewPage Printer.FontName = "黑體" dd = prnt11(3300, 700, fnt, ss$, 26) dd = prnt11(500, stry - 250, fnt, "標準號", 26) dd = prnt11(2690, stry - 250, fnt, "標準名稱", 26) dd = prnt11(6690, stry - 250, fnt, "英文名稱", 26) Printer.Line (-20, stry - 30)-(10460, stry - 30) '打印起始線 Printer.FontName = "宋體" strx = strx1 Else stry = stry + rowlab * linw End If Next If p < page1 Then For p = 0 To page1 + 1 strx = strx1 Next End If strx = strx1 For n = 2 To 4 strx = strx + a(n) Next pp = pp + 1 foot$ = "第" + CStr(pp) + "頁" dd = prnt11(strx / 2, stry + 3 * linw, 10, foot$, 26) Printer.EndDoc End Sub
---- 以上程序在簡體中文Windows98、VB5.0環境中調試通過。 資料來源:孔祥軍 蘇悅娟
|