VB通用数据表格输出程序的设计

2018-06-17 17:11:05来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

----做为一种简捷、系统的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(i=.Fields.Count-1)Then
   str=str&Format(.Fields(i).Name,Fmt(i))&"┃"
  Else
   str=str&Format(.Fields(i).Name,Fmt(i))&"│"
  EndIf
  If(i=.Fields.Count-1)Then
   str0=str0&"┓"
   str1=str1&"┨"
   str2=str2&"┛"
  Else
   str0=str0&"┯"
   str1=str1&"┼"
   str2=str2&"┷"
  EndIf
 Next
 strDy(0)="表格标题"
 '通过在标题前增加空格可使标题居中
 strDy(1)=""
 strDy(2)=Format(Now,"打印日期:
yyyy年m月d日")
 strDy(3)=str0
 strDy(4)=str
 strDy(5)=str1
 intDc=6
 .MoveFirst
 DoWhileNot.EOF
 str="┃"
 Fori=0To.Fields.Count-1
   IfIsNull(.Fields(i).Value)Then  
'处理Null值
    Ifi=.Fields.Count-1Then
     str=str&Format("",Fmt(i))&"┃"
    Else
     str=str&Format("",Fmt(i))&"│"
    EndIf
   Else
    Ifi=.Fields.Count-1Then
     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))&"│"
    EndIf
   EndIf
  Next
  strDy(intDc)=strDy(intDc)&str
  intDc=intDc 1
  .MoveNext
 Loop
 strDy(intDc)=str2
 EndWith
EndSub

----在实际编程中还要排除二进制数据字段,全角与半角字符的匹配调整,处理数据中出现的换行符、回车符、制表符,等等,限于篇幅,这里不于介绍。
----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.PrintstrDy(0)     
 '打印标题
 Printer.PrintstrDy(1)     
 '打印空行
 Printer.Font.Name="楷体_GB2312"
'设置日期字体
 Printer.Font.Size=16      
'设置日期字体大小
 Printer.PrintstrDy(2)      
'打印日期
 Printer.Font.Name="宋体"  
  '设置表格字体
 Printer.Font.Size=11    
  '设置表格字体大小
 Printer.PrintstrDy(3)    
  '以下打印表格内容
 Printer.PrintstrDy(4)
 Fori=6TointDc
  Ifi< intDcThen
   Printer.PrintstrDy(5)
   Printer.PrintstrDy(i)
  Else
   Printer.PrintstrDy(i)'表尾
  EndIf
 Next
 Printer.EndDoc       
   '打印完成

----屏幕预览程序与打印机的输出相同,只要把Printer对象换成PictureBox控件对象并使用相应的对象属性及方法,同时,在编程中还要处理分页、纸张、打印设置、字体、出错等等,限于篇幅,这里不一一介绍。在控件中实现了字体及其大小的设置、纸张的设置、自动分页、自动顺序号,任选列的汇总、选择打印、多份打印等功能,感兴趣的朋友可与本人联系。
----该控件在中文Windows95、VB5下运行通过。->

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:共享数据的锁定--多客户环境下VB数据库编程之(3)

下一篇:另辟蹊径处理字符串中的字符:字节数组法