|
导读淮北市社会保障局计算中心 沙顺义---- 做为一种简捷、系统的 Windows应用程序开发工具,Visual Basic 5 具有强大的数据处理能力,提供了多种数据访问方法,可以方便地存取Micro... 淮北市社会保障局计算中心 沙顺义---- 做为一种简捷、系统的 Windows应用程序开发工具,Visual Basic 5 具有强大的数据处理能力,提供了多种数据访问方法,可以方便地存取Microsoft SQL Server、Oracle、XBase等多种数据库,被广泛应用于建立各种信息管理系统。但是,VB缺乏足够的、符合中文习惯的数据表格输出功能。虽然使用Crystal Report控件及 Crystal Reports程序可以输出报表,但操作很麻烦,中文处理能力也不理想,特别是不能够用来制作不确定内容的表格。笔者在用VB开发淮北市医疗保险信息管理系统时,需要对任意的查询结果进行表格输出,为此,编制了一个通用的数据表格输出控件,能够根据查询的结果自动生成二维中文表格,并打印输出,在此介绍给大家,共同探讨。 一.VB 5中的结果集 ---- VB 5提供的数据访问方法有数据询问对象(DAO)、Data控件、远程数据对象(RDO)、RemoteData控件 (RDC)、ODBC API、VB SQL等,其中ODBC API比较复杂,开发、调试和支持非常困难;VB SQL是针对Microsoft SQL Server的,这两种方法使用的比较少,这里不做讨论。比较常用的方法是DAO、Data控件、RDO、RDC,其中DAO和Data控件使用的结果集 (又叫纪录集) 包含在Recordset对象中,RDO和RDC使用的结果集包含在rdoResultset对象中。通用表格输出的实现方法就是根据任意的Recordset对象或rdoResultset对象自动生成表格并输出。 二.表格的自动生成 ---- 1. Recordset对象 ---- 下面以Data控件为例,介绍 Recordset对象的表格自动生成方法。 ---- 假设有Data控件名称为MyData,首先说明相关的内容及用法: ---- (1) Data控件的结果集包含在它的 Recordset对象中,引用方法为: MyData.Recordset。 ---- (2) Recordset 对象的 RecordCount属性为结果集的行数,它决定了表格的长度,该属性引用方法为: MyData.Recordset.RecordCount。 ---- (3) Recordset 对象包含一个Fields集合,通过Fields集合的 Count属性可以得到结果集中字段的个数,用做表格的列数,该属性引用方法为: MyData.Recordset.Fields.Count。 ---- (4) Fields集合包括结果集合全部 Field对象,这些 Field对象引用方法为: MyData.Recordset.Fields(i),其中 i是该 Field对象在中的位置序号,从 0开始计数。 ---- (5) Field 对象的Name属性是该字段的名称,用做表格对应列的名称,引用方法为:MyData.Recordset.Fields(i).Name。 ---- (6) Field 对象的Size属性是该字段数据的最大尺寸,引用方法为:MyData.Recordset.Fields(i).Size。 ---- (7) Field 对象的Type属性是该字段数据的类型,引用方法为:MyData.Recordset.Fields(i).Type。 ---- 用Field 对象的Size和Type属性可以计算出表格对应列的宽度。 ---- (8) Field 对象的 Value属性是该字段的值,这是表格对应列的内容,引用方法为:MyData.Recordset.Fields(i).Value。 ---- 以上引用在VB中都可有多种引用方法,这里使用的是比较明了的一种,便于说明问题。 ---- 表格的自动生成可分为两个步骤: ---- 第一步,根据结果集中各字段的Size和Type属性,生成表格各对应列的宽度,用Format函数使用的格式字符串表示。 ---- 下面的 Function getFmt()用来生成表格各列的格式字符串,调用时把Field 对象的Type和Size属性值分别赋给形式参数intType和logSize。 Private Function getFmt(intType As Integer, logSize As Long) As String Dim i As Integer getFmt = "" 注释:返回的结果串初始置空 Select Case intType Case dbBoolean getFmt = getFmt & "\ \ \ \0;\ \ \ \1" 注释:Boolean 型值转换为0、1, Case dbByte getFmt = "@@@@" Case dbInteger getFmt = "@@@@@@" Case dbLong getFmt = "@@@@@@@@@@" Case dbCurrency getFmt = "@@@@@@@@@@" Case dbSingle getFmt = "@@@@@@@@@@" Case dbDouble getFmt = "@@@@@@@@@@" Case dbDate getFmt = "@@@@@@@@@@" Case dbBinary getFmt = "@@@@" Case dbText If logSize >= 40 Then 注释:限制一列最多打印40个半角字符 getFmt = "@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@" Else For i = 0 To CInt(logSize / 2) * 2 - 1 getFmt = getFmt & "@" Next 注释:调整数值长度为偶数, 以适应汉字制表符 End If Case dbLongBinary getFmt = "@@@@" Case dbMemo getFmt = "@@@@@@@@@@@@@@@@" Case dbGUID getFmt = "@@@@" Case dbBigInt getFmt = "@@@@@@@@@@" Case dbVarBinary getFmt = "@@@@" Case dbChar For i = 0 To CInt(logSize / 2) * 2 - 1 getFmt = getFmt & "@" Next Case dbNumeric For i = 0 To CInt(logSize / 2) * 2 - 1 getFmt = getFmt & "@" Next Case dbDecimal For i = 0 To CInt(logSize / 2) * 2 - 1 getFmt = getFmt & "@" Next Case dbFloat getFmt = "@@@@@@@@@@" Case dbTime getFmt = "@@@@@@@@" Case dbTimeStamp getFmt = "@@@@@@@@@@" End Select End Function ---- 第二步,取结果集的内容并根据各列的格式字符串生成表格,生成的表格存放在字符串数组 strDy()中,下面用Sub Dy()例示这一步骤。 Dim strDy() As String 注释:存放格式化后的表格内容 Dim Fmt() As String 注释:存放表格各列的格式字符串 注释:以上二个数组变量的元素个数根 据结果集的行数和列数在程序中设定 Dim str,str0,str1,str2 As String 注释:临时使用的串变量 Dim i,j As Integer 注释:临时使用的整型变量 Dim intDc As Integer 注释:存放表格行数, 实际上即是strDy()的元素个数 Private Sub Dy() With MyData.Recordset .MoveLast ReDim strDy(.RecordCount + 8) 注释:需存放标题、表框等,所以加8 ReDim Fmt(.Fields.Count) For i = 0 To .RecordCount + 7 strDy(i) = "" 注释:初始置空 Next For i = 0 To .Fields.Count - 1 Fmt(i) = getFmt(.Fields(i).Type, .Fields(i).Size) 注释:生成表格各列的格式字符串 j = Len(.Fields(i).Name) If j > Len(Fmt(i)) Then Fmt(i) = String$(Int((j / 2) + 0.5) * 2, "@") 注释:标题 (字段名) 字多则增大列宽 End If Next str = "┃" str0 = "┏" str1 = "┠" str2 = "┗" 注释:设定表格为粗框细线, 可根据需要改变 For i = 0 To .Fields.Count - 1 For j = 1 To Len(Fmt(i)) / 2 str0 = str0 & "━" str1 = str1 & "─" str2 = str2 & "━" Next If (i = .Fields.Count - 1) Then str = str & Format(.Fields(i).Name, Fmt(i)) & "┃" Else str = str & Format(.Fields(i).Name, Fmt(i)) & "│" End If If (i = .Fields.Count - 1) Then str0 = str0 & "┓" str1 = str1 & "┨" str2 = str2 & "┛" Else str0 = str0 & "┯" str1 = str1 & "┼" str2 = str2 & "┷" End If Next strDy(0) = "表格标题" 注释:通过在标题前增加空格可使标题居中 strDy(1) = "" strDy(2) = Format(Now, " 打印日期: yyyy年 m月 d日") strDy(3) = str0 strDy(4) = str strDy(5) = str1 intDc = 6 .MoveFirst Do While Not .EOF str = "┃" For i = 0 To .Fields.Count - 1 If IsNull(.Fields(i).Value) Then 注释:处理 Null 值 If i = .Fields.Count - 1 Then str = str & Format(" ", Fmt(i)) & "┃" Else str = str & Format(" ", Fmt(i)) & "│" End If Else If i = .Fields.Count - 1 Then str = str & Format(Left$(.Fields(i). Value, Len(Fmt(i))), Fmt(i)) & "┃" Else str = str & Format(Left$(.Fields(i). Value, Len(Fmt(i))), Fmt(i)) & "│" End If End If Next strDy(intDc) = strDy(intDc) & str intDc = intDc + 1 .MoveNext Loop strDy(intDc) = str2 End With End Sub ---- 在实际编程中还要排除二进制数据字段,全角与半角字符的匹配调整,处理数据中出现的换行符、回车符、制表符,等等,限于篇幅,这里不于介绍。 ---- 2.rdoResultset对象 ---- rdoResultset对象的表格自动生成方法与Recordset对象的方法相似,在处理过程中把Recordset对象的RecordCount属性用rdoResultset对象的RowCount属性替换,Fields集合用rdoColumns替换,Field对象用rdoColumn替换,其余相同。例如: ---- 引用Data控件MyData结果集中第三个字段的名称用:MyData.Recordset.Fields(3).Name。 ---- 引用RDC控件MyRDC相应字段的名称用: MyRDC.Resultset.rdoColumns(3).Name。 三.表格的输出 ---- 表格的输出包括二个部分,一是屏幕预览,二是打印机输出。屏幕预览是把存放在数组中的表格通过在PictureBox控件上调用 Print方法显示出来而实现的。打印输出是把同样的内容通过 Printer对象的 Print方法实现的。下面例示打印机输出的实现方法: Printer.Font.Name = "黑体" 注释:设置标题字体 Printer.Font.Size = 18 注释:设置标题字体大小 Printer.Print strDy(0) 注释:打印标题 Printer.Print strDy(1) 注释:打印空行 Printer.Font.Name = "楷体_GB2312" 注释:设置日期字体 Printer.Font.Size = 16 注释:设置日期字体大小 Printer.Print strDy(2) 注释:打印日期 Printer.Font.Name = "宋体" 注释:设置表格字体 Printer.Font.Size = 11 注释:设置表格字体大小 Printer.Print strDy(3) 注释:以下打印表格内容 Printer.Print strDy(4) For i = 6 To intDc If i < intDc Then Printer.Print strDy(5) Printer.Print strDy(i) Else Printer.Print strDy(i) 注释:表尾 End If Next Printer.EndDoc 注释:打印完成 ---- 屏幕预览程序与打印机的输出相同,只要把 Printer对象换成PictureBox控件对象并使用相应的对象属性及方法,同时,在编程中还要处理分页、纸张、打印设置、字体、出错等等,限于篇幅,这里不一一介绍。在控件中实现了字体及其大小的设置、纸张的设置、自动分页、自动顺序号,任选列的汇总、选择打印、多份打印等功能,感兴趣的朋友可与本人联系。 ---- 该控件在中文Windows 95、VB 5下运行通过。 |
温馨提示:喜欢本站的话,请收藏一下本站!