----做为一种简捷、系统的Windows应用
程序开发工具,VisualBasic5具有强大的
数据处理能力,提供了多种
数据访问方法,可以方便地存取MicrosoftSQLServer、
Oracle、XBase等多种
数据库,被广泛应用于建立各种信息管理系统。但是,VB缺乏足够的、符合中文习惯的
数据表格输出功能。虽然使用CrystalReport控件及CrystalReports程序可以输出报表,但操作很麻烦,中文处理能力也不理想,特别是不能够用来制作不确定内容的表格。笔者在用VB开发淮北市医疗保险信息管理系统时,需要对任意的查询结果进行表格输出,为此,编制了一个通用的
数据表格输出控件,能够根据查询的结果自动生成二维中文表格,并打印输出,在此介绍给大家,共同探讨。
一.VB5中的结果集
----VB5提供的
数据访问方法有
数据询问对象(DAO)、Data控件、远程
数据对象(RDO)、RemoteData控件(RDC)、ODBCAPI、VBSQL等,其中ODBCAPI比较复杂,开发、调试和支持非常困难;VBSQL是针对MicrosoftSQLServer的,这两种方法使用的比较少,这里不做讨论。比较常用的方法是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函数使用的格式字符串表示。
----下面的FunctiongetFmt()用来生成表格各列的格式字符串,调用时把Field对象的Type和Size属性值分别赋给形式参数intType和logSize。
PrivateFunctiongetFmt(intTypeAsInteger,
logSizeAsLong)AsString
DimiAsInteger
getFmt=""
'返回的结果串初始置空
SelectCaseintType
CasedbBoolean
getFmt=getFmt&"\\\\0;\\\\1"
'Boolean型值转换为0、1,
CasedbByte
getFmt="@@@@"
CasedbInteger
getFmt="@@@@@@"
CasedbLong
getFmt="@@@@@@@@@@"
CasedbCurrency
getFmt="@@@@@@@@@@"
CasedbSingle
getFmt="@@@@@@@@@@"
CasedbDouble
getFmt="@@@@@@@@@@"
CasedbDate
getFmt="@@@@@@@@@@"
CasedbBinary
getFmt="@@@@"
CasedbText
IflogSize >=40Then
'限制一列最多打印40个半角字符
getFmt="@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@"
Else
Fori=0ToCInt(logSize/2)*2-1
getFmt=getFmt&"@"
Next '调整数值长度为偶数,
以适应汉字制表符
EndIf
CasedbLongBinary
getFmt="@@@@"
CasedbMemo
getFmt="@@@@@@@@@@@@@@@@"
CasedbGUID
getFmt="@@@@"
CasedbBigInt
getFmt="@@@@@@@@@@"
CasedbVarBinary
getFmt="@@@@"
CasedbChar
Fori=0ToCInt(logSize/2)*2-1
getFmt=getFmt&"@"
Next
CasedbNumeric
Fori=0ToCInt(logSize/2)*2-1
getFmt=getFmt&"@"
Next
CasedbDecimal
Fori=0ToCInt(logSize/2)*2-1
getFmt=getFmt&"@"
Next
CasedbFloat
getFmt="@@@@@@@@@@"
CasedbTime
getFmt="@@@@@@@@"
CasedbTimeStamp
getFmt="@@@@@@@@@@"
EndSelect
EndFunction
----第二步,取结果集的内容并根据各列的格式字符串生成表格,生成的表格存放在字符串数组strDy()中,下面用SubDy()例示这一步骤。
DimstrDy()AsString
'存放格式化后的表格内容
DimFmt()AsString
'存放表格各列的格式字符串
'以上二个数组变量的元素个数根
据结果集的行数和列数在
程序中设定
Dimstr,str0,str1,str2AsString
'临时使用的串变量
Dimi,jAsInteger
'临时使用的整型变量
DimintDcAsInteger '存放表格行数,
实际上即是strDy()的元素个数
PrivateSubDy()
WithMyData.Recordset
.MoveLast
ReDimstrDy(.RecordCount 8)
'需存放标题、表框等,所以加8
ReDimFmt(.Fields.Count)
Fori=0To.RecordCount 7
strDy(i)="" '初始置空
Next
Fori=0To.Fields.Count-1
Fmt(i)=getFmt(.Fields(i).Type,.Fields(i).Size)
'生成表格各列的格式字符串
j=Len(.Fields(i).Name)
Ifj >Len(Fmt(i))Then
Fmt(i)=String$(Int((j/2) 0.5)*2,"@")
'标题(字段名)字多则增大列宽
EndIf
Next
str="┃"
str0="┏"
str1="┠"
str2="┗" '设定表格为粗框细线,
可根据需要改变
Fori=0To.Fields.Count-1
Forj=1ToLen(Fmt(i))/2
str0=str0&"━"
str1=str1&"─"
str2=str2&"━"
Next
If