技术中心
 
 

嵌入复杂VB报表的实现方法

   日期:2006-03-14     作者:管理员    

      1. 概述
      在许多组态控制软件中,都提供了报表的功能,可满足不了各种客户的报表需求,不可避免的碰到各种各样的报表。现在大多数组态软件支持嵌入VB程序,可以再VB平台下作出报表嵌入到组态程序中。在VB平台下制作报表大致有两种选择:使用VB自带的Data Report控件和借助第三方软件。使用Data Report控件有两点局限:第一DataReport本身提供的控件很少却功能很弱,与数据环境邦定得太死。第二DataReport没用提供分栏等复杂的打印功能;借助第三方软件功能复杂多样需要学习,需要时间去理解掌握。利用VB本身提供的控件功能也可以轻松设计自己的复杂报表,简单明了,适用于简单和复杂报表,与大家共同探讨。


      2. 设计报表纸
     设计报表纸的容器(Form)也就是一张白纸,它具有Form.PrintForm功能,利用它作者可以任意发挥

,只要在窗体能显示的内容都可以打印出来,制作打印所见即所得的报表。众所周知,在窗体上可以放置VB提供的所有控件,如:Lable,TextBox,Line,Imge,MSHFGrid等各种控件,由用程序操作各种控件的结果,用数据库内的数据填充MSHFGrid,就可以作出图文并茂的报表。设定报表纸张(form4):
在工程中添加一窗体Form4。设定窗体的大小通与打印纸张大小相同、前景颜色、后景颜色、边框形式、控制按钮、滚动条、标题等项目,使窗体显示为一张“白纸”。程序如下:
Private Sub Form4_Load()

 With Form4
   .Appearance = 0           'Flat
   .AutoRedraw = 1           'True
   .BackColor = &H80000005   '背景颜色:白色
   .BorderStyle = 0            'None
   .Height = 15000            '设置页面的大小,即纸的大小,
   .Width = 11760            '15000,11760相当于A3
   .Top = 0
   .Left = 0
   .ClipControls = 0           'False
   .FillStyle = 0              'Solid
   .Caption = "paper"
 End With
End Sub


      3. 表头的设计
      表头包括报表的页眉、页脚、页标题、日期、不规则表头等。用Lable控件设计报表的题目。用Line控件在纸上画出不规则表头。用Lable,TextBox,Imge填充表头的内容,将标头内的所有同类的控件选中设定统一属性。页眉、页脚、页标题、日期、都可以用控件TextBox设计,程序运行时控制控件的显示内容,可以做出复杂表头。


     4. 表体的设计
      在窗体上添加控件MSHFlexGrid(Micro





















soft Hieerarchical FlexGrid),用鼠标拖动边框,使其占据表体所需的面积,设定其属性:编框、前景颜色、背景颜色、固定行数,固定列数,滚动条,行宽(若各行高度不一样,可以在程序中设定各行的高度)。在程序中设定各列的宽度。MSHFlexGrid控件以网格形式显示Recordset数据,可以将文本、图片或者文本和图片放在MSHFlexGrid的任意单元中,Row和Col属性制定了MSHFlexGrid装的当前单元。可以在代码种植订单前单元,也可以在运行时使用鼠标或者方向键来选定当前的单元。Text属性引用当前单元的内容。很遗憾MSHFlexGrid控件没用打印功能,只能借助于Form控件的打印功能,实现报表打印。


Begin MSHierarchicalFlexGridLib.MSHFlexGrid MSHFlexGrid1
      Height          =   10305  

216;设置高度容纳一页所有的行。
      Left            =   300
      TabIndex        =   0
      Top             =   780
      Width           =   4755   ‘设置宽度容纳一页所有的列。
      _ExtentX        =   8387
      _ExtentY        =   18177
      _Version        =   393216
      Rows            =   26     ‘设置一页容纳的行数
      FixedCols       =   0
      BackColorFixed  =   255
      BackColorBkg    =   -2147483639
      GridColor       =   8454016
      GridColorFixed  =   8454143
      GridColorUnpopulated=   8421631
      GridLines&n
















bsp;      =   1
      GridLinesUnpopulated=   3
      MergeCells      =   4
      BorderStyle     =   1      ‘设置边框:有边框
      Appearance      =   0
      GridLineWidthFixed=   1
   
;   BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851}
         Name            =   "宋体"
         Size            =   12   ‘设置字体的大小,行宽自动设定
         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  ‘上段程序是在设置MSHFlexGrid控件属性自动产生的,以示参考

Sub MsgdWidth(ci As Integer, ccwidth() As Integer, Msgd As MSHFlexGrid)
 ‘设置格列的宽度   ci  列数
   ‘ccwidth() ‘容纳列宽度的数组,单位使用缺省单位
  Dim i As




















Integer
        For i = 0 To ci - 1
            msgrd.ColWidth(i) = ccwidth(i)
        Next i
End Sub


      5. 为MSHFlexGrid准备数据
      MSHFlexGrid可以与各种数据空间邦定,能够自动读取数据。在报表打印中,我们不使用数据邦定,用程序代码来控制填充MSHFlexGrid控件的每一单元格。使用ADO对象的Recordset来准备数据源,也可以用其他类似的方法获得数据源的指针。


Sub opendata(t As String, restdata As adodb.Recordset)
  Di

m constring, sqlstring As String
  Dim recon As adodb.Connection
  constring="Provider=SQLOLEDB.4;server=Datacenter;database=zbmis;uid=;pwd="
  '数据源连接字
  sqlstring = "select stid,sbbatchid,stlong from tn_stinfo where  ckroundnum=" & "'"_
   & Trim(t) & "'" & "order by stid"
  '数据筛选指令,t为数据筛选条件
  restdata.Open sqlstring, constring, adOpenKeyset, adLockReadOnly 
  '打开数据记录,获得记录集
End Sub


        6. 填充MSHFlexGrid的单元格
       用打开的数据源,填充MSHFlexGrid每一行,每一列,若最后一页所有的行填充不满,用“”来填充。若用彩色打印机可以控制每一单元格的颜色,制作多彩的报表。可以在表中单元任意各种添加页计、总计、序号等数据。


Sub inputmsfh(ri As Integer, ci As Integer, restdata As adodb.Recordset, msgrd As MSHFlexGrid)  ‘ri,ci 是MSHFlexGrid的行数和列数
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  ‘控制记录行将每行填满,
‘若记录到了文件尾或记录的列内容为null则用&



































#8220;”来填充
    End With
Next rk
End Sub
   列表头的填充
  Sub msgrdname(ci As Integer, ccstring() As String, msgrd As MSHFlexGrid)
‘ci  列数
‘ccstring() 容纳列表头的数组
    Dim i As Integer
    With msgrd
    msgrd.Cols = ci
    msgrd.Rows = 1
        .Row = 0
        For i = 0 To ci - 1
         &
nbsp;    .Col = i
              .Text = ccstring(i)
        Next i
  End With
 End Sub


      7. 关于分页和分栏
     首先确定分栏数,若不分栏,窗体Form4页面上只添加一个控件MSHFlexGrid1;若分两栏,在窗体Form4页面上添加两个并列控件MSHFlexGrid1 ,MSHFlexGrid2;依次类推。下面的程序中支持分三栏以下的格式。各栏之间的距离,可以直接在窗体上确定。其次,计算报表的页数控制打印的次序。
Private Sub Command1_Click()
Dim restdata As New adodb.Recordset
Dim t As String          ‘数据筛选条件
Dim ccstring() As String   '列标题名称数组
Dim ccwidth() As Integer  '列宽
Dim cc, rc   As Integer     '一页的行数rc,页数cc
Dim prc, plc  As Integer    '页数prc,拦数plc
Dim rctotal  As Integer    '总行数
Dim prc1, I  As Integer

t = Form1.TextBox1.Text   ‘从Form1.TextBox1.Text输入查询的条件
   Call opendata(t, restdata)    ‘打开数据源,获得记录集
   rctotal = restdata.RecordCount  ‘取出总行数
   'Print rctotal
If rctotal > 0 Then
cc = restdata.Fields.Count   ‘取出总列数
ReDim ccstring(3) As String
ReDim ccWidth(3) As String
plc = 2                ‘设定分两栏
rc = 30                ‘每页30行
ccwidth(0)=600      






































   ‘列宽数组初始化,根据列的字符宽度设定列宽度
ccwidth(1)=1600
ccwidth(2)=1800
    ccstring(0) = "管号"       ‘列表头数组初始化
    ccstring(1) = "炉批号"
    ccstring(2) = "米长"
       prc = Int(rctotal / (rc * plc))  '计算总页数
     prc1 = rctotal Mod (rc * plc)
 If prc1 > 0 Then prc = prc + 1
      restdata.MoveFirst
   
   &nbs
p;  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) ̵






















6;第一栏列头
                    Call msgrdname(cc, ccstring(), Form4.MSHFlexGrid2) ‘第二栏列头
                    Call inputmsfh(rc, cc, restdata, Form4.MSHFlexGrid1) ‘第一栏内容
                    Call inputmsfh(rc,
cc, restdata, Form4.MSHFlexGrid2) ‘第二栏内容
                     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 Se














lect
           Form4.Show
        MsgBox ("打印第" & i & "页")
        Form4.PrintForm ‘输出到系统缺省打印机
      Next i
    Else
      MsgBox "查无此记录"
    End If
restdata.Close        ‘关闭记录
set restdata = Nothing  ‘释放缓冲区
End Sub


   &n

bsp;  8. 结束语
      所有的程序 Mcrosoft Visual Basic 6.0下调试通过,还有许多排错指令,由于篇幅所限都已去掉,在实际运用中,使用者可以加入,以增强程序的强壮性。若有Bug请来信一起探讨。

联系方式:电话:  0546-8850085
          Email:  Deckhand@sina100.com
地址:山东省淄博市张店区中埠镇胜利钢管有限公司
邮编:255082

















 
  
  
  
  
 
更多>同类技术
 
全年征稿 / 资讯合作
 
推荐图文
推荐技术
可能喜欢