1.概述
在許多組態(tài)控制軟件中,都提供了報(bào)表的功能,可滿足不了各種客戶的報(bào)表需求,不可避免的碰到各種各樣的報(bào)表。現(xiàn)在大多數(shù)組態(tài)軟件支持嵌入VB程序,可以再VB平臺(tái)下作出報(bào)表嵌入到組態(tài)程序中。在VB平臺(tái)下制作報(bào)表大致有兩種選擇:使用VB自帶的Data Report控件和借助第三方軟件。使用Data Report控件有兩點(diǎn)局限:第一DataReport本身提供的控件很少卻功能很弱,與數(shù)據(jù)環(huán)境邦定得太死。第二DataReport沒(méi)用提供分欄等復(fù)雜的打印功能;借助第三方軟件功能復(fù)雜多樣需要學(xué)習(xí),需要時(shí)間去理解掌握。利用VB本身提供的控件功能也可以輕松設(shè)計(jì)自己的復(fù)雜報(bào)表,簡(jiǎn)單明了,適用于簡(jiǎn)單和復(fù)雜報(bào)表,與大家共同探討。
2.設(shè)計(jì)報(bào)表紙
設(shè)計(jì)報(bào)表紙的容器(Form)也就是一張白紙,它具有Form.PrintForm功能,利用它作者可以任意發(fā)揮,只要在窗體能顯示的內(nèi)容都可以打印出來(lái),制作打印所見(jiàn)即所得的報(bào)表。眾所周知,在窗體上可以放置VB提供的所有控件,如:Lable,TextBox,Line,Imge,MSHFGrid等各種控件,由用程序操作各種控件的結(jié)果,用數(shù)據(jù)庫(kù)內(nèi)的數(shù)據(jù)填充MSHFGrid,就可以作出圖文并茂的報(bào)表。設(shè)定報(bào)表紙張(form4):
在工程中添加一窗體Form4。設(shè)定窗體的大小通與打印紙張大小相同、前景顏色、后景顏色、邊框形式、控制按鈕、滾動(dòng)條、標(biāo)題等項(xiàng)目,使窗體顯示為一張“白紙”。程序如下:
Private Sub Form4_Load()
With Form4
.Appearance = 0 Flat
.AutoRedraw = 1 True
.BackColor = &H80000005 背景顏色:白色
.BorderStyle = 0 None
.Height = 15000 設(shè)置頁(yè)面的大小,即紙的大小,
.Width = 11760 15000,11760相當(dāng)于A3
.Top = 0
.Left = 0
.ClipControls = 0 False
.FillStyle = 0 Solid
.Caption = "paper"
End With
End Sub
3.表頭的設(shè)計(jì)
表頭包括報(bào)表的頁(yè)眉、頁(yè)腳、頁(yè)標(biāo)題、日期、不規(guī)則表頭等。用Lable控件設(shè)計(jì)報(bào)表的題目。用Line控件在紙上畫出不規(guī)則表頭。用Lable,TextBox,Imge填充表頭的內(nèi)容,將標(biāo)頭內(nèi)的所有同類的控件選中設(shè)定統(tǒng)一屬性。頁(yè)眉、頁(yè)腳、頁(yè)標(biāo)題、日期、都可以用控件TextBox設(shè)計(jì),程序運(yùn)行時(shí)控制控件的顯示內(nèi)容,可以做出復(fù)雜表頭。
4.表體的設(shè)計(jì)
在窗體上添加控件MSHFlexGrid(Microsoft Hieerarchical FlexGrid),用鼠標(biāo)拖動(dòng)邊框,使其占據(jù)表體所需的面積,設(shè)定其屬性:編框、前景顏色、背景顏色、固定行數(shù),固定列數(shù),滾動(dòng)條,行寬(若各行高度不一樣,可以在程序中設(shè)定各行的高度)。在程序中設(shè)定各列的寬度。MSHFlexGrid控件以網(wǎng)格形式顯示Recordset數(shù)據(jù),可以將文本、圖片或者文本和圖片放在MSHFlexGrid的任意單元中,Row和Col屬性制定了MSHFlexGrid裝的當(dāng)前單元??梢栽诖a種植訂單前單元,也可以在運(yùn)行時(shí)使用鼠標(biāo)或者方向鍵來(lái)選定當(dāng)前的單元。Text屬性引用當(dāng)前單元的內(nèi)容。很遺憾MSHFlexGrid控件沒(méi)用打印功能,只能借助于Form控件的打印功能,實(shí)現(xiàn)報(bào)表打印。
Begin MSHierarchicalFlexGridLib.MSHFlexGrid MSHFlexGrid1
Height = 10305 設(shè)置高度容納一頁(yè)所有的行。
Left = 300
TabIndex = 0
Top = 780
Width = 4755 設(shè)置寬度容納一頁(yè)所有的列。
_ExtentX = 8387
_ExtentY = 18177
_Version = 393216
Rows = 26 設(shè)置一頁(yè)容納的行數(shù)
FixedCols = 0
BackColorFixed = 255
BackColorBkg = -2147483639
GridColor = 8454016
GridColorFixed = 8454143
GridColorUnpopulated= 8421631
GridLines = 1
GridLinesUnpopulated= 3
MergeCells = 4
BorderStyle = 1 設(shè)置邊框:有邊框
Appearance = 0
GridLineWidthFixed= 1
BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851}
Name = "宋體"
Size = 12 設(shè)置字體的大小,行寬自動(dòng)設(shè)定
Charset = 134
Weight = 400
Underline = 0 False
Italic = 0 False
Strikethrough = 0 False
EndProperty
_NumberOfBands = 1
_Band(0).Cols = 2
_Band(0).GridLineWidthBand= 1
End 上段程序是在設(shè)置MSHFlexGrid控件屬性自動(dòng)產(chǎn)生的,以示參考
Sub MsgdWidth(ci As Integer, ccwidth() As Integer, Msgd As MSHFlexGrid)
設(shè)置格列的寬度 ci 列數(shù)
ccwidth() 容納列寬度的數(shù)組,單位使用缺省單位
Dim i As Integer
For i = 0 To ci - 1
msgrd.ColWidth(i) = ccwidth(i)
Next i
End Sub
5.為MSHFlexGrid準(zhǔn)備數(shù)據(jù)
MSHFlexGrid可以與各種數(shù)據(jù)空間邦定,能夠自動(dòng)讀取數(shù)據(jù)。在報(bào)表打印中,我們不使用數(shù)據(jù)邦定,用程序代碼來(lái)控制填充MSHFlexGrid控件的每一單元格。使用ADO對(duì)象的Recordset來(lái)準(zhǔn)備數(shù)據(jù)源,也可以用其他類似的方法獲得數(shù)據(jù)源的指針。
Sub opendata(t As String, restdata As adodb.Recordset)
Dim constring, sqlstring As String
Dim recon As adodb.Connection
constring="Provider=SQLOLEDB.4;server=Datacenter;database=zbmis;uid=;pwd="
數(shù)據(jù)源連接字
sqlstring = "select stid,sbbatchid,stlong from tn_stinfo where ckroundnum=" & ""_
& Trim(t) & "" & "order by stid"
數(shù)據(jù)篩選指令,t為數(shù)據(jù)篩選條件
restdata.Open sqlstring, constring, adOpenKeyset, adLockReadOnly
打開(kāi)數(shù)據(jù)記錄,獲得記錄集
End Sub
6.填充MSHFlexGrid的單元格
用打開(kāi)的數(shù)據(jù)源,填充MSHFlexGrid每一行,每一列,若最后一頁(yè)所有的行填充不滿,用“”來(lái)填充。若用彩色打印機(jī)可以控制每一單元格的顏色,制作多彩的報(bào)表。可以在表中單元任意各種添加頁(yè)計(jì)、總計(jì)、序號(hào)等數(shù)據(jù)。
Sub inputmsfh(ri As Integer, ci As Integer, restdata As adodb.Recordset, msgrd As MSHFlexGrid) ri,ci 是MSHFlexGrid的行數(shù)和列數(shù)
Dim rk, ck As Integer
msgrd.Rows = ri + 1 加一行列表頭
msgrd.Cols = ci
For rk = 1 To ri
With msgrd
.Row = rk
For ck = 0 To ci - 1
.Col = ck
If restdata.EOF Or IsNull(restdata(ck)) Then
.Text = ""
Else
.Text = Trim(restdata(ck))
End If
Next ck
If restdata.EOF = False Then restdata.MoveNext 控制記錄行將每行填滿,
若記錄到了文件尾或記錄的列內(nèi)容為null則用“”來(lái)填充
End With
Next rk
End Sub
列表頭的填充
Sub msgrdname(ci As Integer, ccstring() As String, msgrd As MSHFlexGrid)
ci 列數(shù)
ccstring() 容納列表頭的數(shù)組
Dim i As Integer
With msgrd
msgrd.Cols = ci
msgrd.Rows = 1
.Row = 0
For i = 0 To ci - 1
.Col = i
.Text = ccstring(i)
Next i
End With
End Sub
7.關(guān)于分頁(yè)和分欄
首先確定分欄數(shù),若不分欄,窗體Form4頁(yè)面上只添加一個(gè)控件MSHFlexGrid1;若分兩欄,在窗體Form4頁(yè)面上添加兩個(gè)并列控件MSHFlexGrid1 ,MSHFlexGrid2;依次類推。下面的程序中支持分三欄以下的格式。各欄之間的距離,可以直接在窗體上確定。其次,計(jì)算報(bào)表的頁(yè)數(shù)控制打印的次序。
Private Sub Command1_Click()
Dim restdata As New adodb.Recordset
Dim t As String 數(shù)據(jù)篩選條件
Dim ccstring() As String 列標(biāo)題名稱數(shù)組
Dim ccwidth() As Integer 列寬
Dim cc, rc As Integer 一頁(yè)的行數(shù)rc,頁(yè)數(shù)cc
Dim prc, plc As Integer 頁(yè)數(shù)prc,攔數(shù)plc
Dim rctotal As Integer 總行數(shù)
Dim prc1, I As Integer
t = Form1.TextBox1.Text 從Form1.TextBox1.Text輸入查詢的條件
Call opendata(t, restdata) 打開(kāi)數(shù)據(jù)源,獲得記錄集
rctotal = restdata.RecordCount 取出總行數(shù)
Print rctotal
If rctotal > 0 Then
cc = restdata.Fields.Count 取出總列數(shù)
ReDim ccstring(3) As String
ReDim ccWidth(3) As String
plc = 2 設(shè)定分兩欄
rc = 30 每頁(yè)30行
ccwidth(0)=600 列寬數(shù)組初始化,根據(jù)列的字符寬度設(shè)定列寬度
ccwidth(1)=1600
ccwidth(2)=1800
ccstring(0) = "管號(hào)" 列表頭數(shù)組初始化
ccstring(1) = "爐批號(hào)"
ccstring(2) = "米長(zhǎng)"
prc = Int(rctotal / (rc * plc)) 計(jì)算總頁(yè)數(shù)
prc1 = rctotal Mod (rc * plc)
If prc1 > 0 Then prc = prc + 1
restdata.MoveFirst
For i = 1 To prc
Form4.Text1 = rctotal
Select Case plc
Case 1 不分欄
Call MsgdWidth(Msgd1 As MSHFlexGrid1)
Call msgrdname(cc, ccstring(), Form4.MSHFlexGrid1)
Call inputmsfh(rc, cc, restdata, Form4.MSHFlexGrid1)
Form4.MSHFlexGrid2.Visible = False
Form4.MSHFlexGrid3.Visible = False
Case 2 分兩欄
Call MsgdWidth(Msgd1 As MSHFlexGrid1) 第一欄列寬
Call MsgdWidth(Msgd1 As MSHFlexGrid2) 第二欄列寬
Call msgrdname(cc, ccstring(), Form4.MSHFlexGrid1) 第一欄列頭
Call msgrdname(cc, ccstring(), Form4.MSHFlexGrid2) 第二欄列頭
Call inputmsfh(rc, cc, restdata, Form4.MSHFlexGrid1) 第一欄內(nèi)容
Call inputmsfh(rc, cc, restdata, Form4.MSHFlexGrid2) 第二欄內(nèi)容
Form4.MSHFlexGrid3.Visible = False
Case 3 分三欄
Call MsgdWidth(Msgd1 As MSHFlexGrid1)
Call MsgdWidth(Msgd1 As MSHFlexGrid2)
Call MsgdWidth(Msgd1 As MSHFlexGrid3)
Call msgrdname(cc, ccstring(), Form4.MSHFlexGrid1)
Call msgrdname(cc, ccstring(), Form4.MSHFlexGrid2)
Call msgrdname(cc, ccstring(), Form4.MSHFlexGrid3)
Call inputmsfh(rc, cc, restdata, Form4.MSHFlexGrid1)
Call inputmsfh(rc, cc, restdata, Form4.MSHFlexGrid2)
Call inputmsfh(rc, cc, restdata, Form4.MSHFlexGrid3)
End Select
Form4.Show
MsgBox ("打印第" & i & "頁(yè)"
Form4.PrintForm 輸出到系統(tǒng)缺省打印機(jī)
Next i
Else
MsgBox "查無(wú)此記錄"
End If
restdata.Close 關(guān)閉記錄
set restdata = Nothing 釋放緩沖區(qū)
End Sub
8. 結(jié)束語(yǔ)
所有的程序 Mcrosoft Visual Basic 6.0下調(diào)試通過(guò),還有許多排錯(cuò)指令,由于篇幅所限都已去掉,在實(shí)際運(yùn)用中,使用者可以加入,以增強(qiáng)程序的強(qiáng)壯性。若有Bug請(qǐng)來(lái)信一起探討。
聯(lián)系方式:電話: 0546-8850085
Email: Deckhand@sina100.com
地址:山東省淄博市張店區(qū)中埠鎮(zhèn)勝利鋼管有限公司
郵編:255082