论坛登陆 用户名:  密 码:
设为首页  加入收藏
08年北京名校秋季招生
名牌院校免试入学宽进严出,突破考分限制,名校与你零距离,以下院校按报名先后顺序录取,24小时网上报名覆盖全国
  您现在的位置: 中国教育招生在线 >> IT >> 应试技巧 >> IT正文
用Word更好地输出VFP报表
 作者:佚名     2007-3-14 15:59:32        来源:不详  浏览次数:

  一、概述
  无论是西文还是中文Visual FoxPro 3.0(以下简称VFP),其报表输出都有一个严重缺陷,就是当数据库的某一字段具有溢出延伸属性(就是当字段的内容长于指定的输出宽度时,自动进行换行的属性)时,在换行处容易出现半个汉字,使输出的报表内容出现"乱码"。
  另外,VFP与其他数据库管理系统一样,报表输出模块也存在以下严重不足:
  ①报表输出的宽度和长度不能由用户改变,无法实现页面的任意变化;
  ②由于数据库中数据的长度不一,必然会导致输出报表中各栏位的宽度不适,系统无法根据数据库的实际内容对输出的各栏位的宽度进行随机调整,报表的整体效果差;
  ③报表一旦输出,用户不能对报表格式进行编辑;
  ④不宜实现对某些特定栏位的单独输出或组合输出。
  为此,笔者利用VFP的OLE自动化技术,通过Microsoft Word 6.0 提供的Word.Basic对象,将数据库的记录输出成Word文档。
  
  
  二、在VFP中自动生成Word文档的基本原理和方法
  1.用Word.Basic生成数据Word文档的基本原理我们知道,Windows的OLE技术是在两个具有OLE能力的应用程序之间建立了一种信息共享机制。能够提供OLE服务的应用程序叫服务器,请求OLE服务的应用程序叫客户机。由于VFP不能为其他具有OLE能力的应用程序提供可用的对象,不能作为OLE服务器。为了在VFP中使用OLE自动化技术来解决报表输出存在的问题,必须在Windows环境下选择一个能作为OLE服务器的应用程序。Microsoft Word 6.0不仅能够向VFP提供OLE对象类型Word.Basic,而且能够生成复杂的表格,具有较强的编辑功能,是生成数据库报表的理想工具。
  VFP和Microsoft Word 6.0之间的信息共享机制是通过在VFP中创建由MS Word 6.0提供可用OLE对象Word.Basic实现的。因此,要使用OLE自动化技术,必须首先使用VFP的OLE对象创建函数CREATEOBJECT() 创建MS Word 6.0的OLE对象,即: oleWord=CREATEOBJECT("Word.Basic")
  
  2.用Word.Basic生成数据Word文档的基本方法在用CREATEOBJECT()函数创建OLE对象之后,我们就可以利用面向对象的程序设计方法,调用Word.Basic的具体命令,将数据库的具体内容生成到Word文档。
  用Word.Basic生成数据库的Word文档,常用的方法有两种:第一种方法是用Word.Basic的一系列命令生成数据库的整个Word文档;另一种方法是利用Word.Basic打开预制的基本文档框架,再用Word.Basic的编辑命令来生成数据库的Word文档。这两种方法各有优点,有时要将它们结合起来使用。第一种方法主要用于对数据库报表没有任何要求的全自动生成,由于采用全自动生成技术,尽管也能实现输出页面的任意变化和报表中各栏位宽度的自动调整等功能,但不能直接根据具体的数据库输出具有相应特色的标题。第二种方法在标题及输出的格式上具有更大的灵活性。通常情况下,先用第一种方法输出某些数据库的一般文档,再利用W ord将其修改成特殊报表输出的基本文档框架,供第二种方法使用。
  下面结合应用介绍第二种方法的具体实现和主要算法。
  (1) 定制基本的Word文档框架
  在基本的文档框架中可以包含Word文档的任何内容,比如在标题的两边各插入一些图片等等。但是为了实现对数据库字段的定位输出,该文档框架必须包含一个表,该表的表头可以设计成任何复杂的形式, 如下面的文档框架:
  表1 不良地质:瓦斯信息
  为了能使Word.Basic将数据库中要输出的字段正确地输出到基本框架中,在基本框架中需要增加位置标记。我们可以用在Word基本文档框架中添加书签的方法来指导Word.Basic在基本框架中的正确定位,这些书签分别添加在基本文档框架中仅有的一行表体的各栏位处。由于Word.Basic在进行后续记录的输出时是按第一表体行中输出字段的顺序进行输出的,这样就可以保证后续各行输出的正确性了。为了方便起见可将书签名定义成与字段名同名。
  在实际的数据输出过程中,由于我们允许输出页面任意变化,并允许对输出的各栏位宽度进行优化调整,这样就很难保证各页的行数相同。为了使输出页面的标题能够正确地打印在每一输出页面的首部,将该表的表头设置成"标题允许"(先选定要设置成标题允许的一行或多行,再用"表格"菜单中的"标题"命令进行设置)。为了使输出页面的高度一致,可用"表格"菜单中"单元格高度和宽度"对话框选择"允许跨页断行"选项,当然也可用Word.Basic的TableR owHeight命令对"允许跨页断行"进行设置。
  另外,在定义基本文档框架时,不必考虑总的表格宽度应放大至何种尺寸以及各栏位之间的比例关系,仅仅需要将各栏位的宽度定义成用户所想要的最小宽度即可,其具体目的在下面的数据库输出的主要算法中会作解释。
  (2) 生成Word文档的主要算法
  在用Word.Basic将数据库的记录输出成Word文档时,需要编程调整输出报表的页面和各栏位的宽度,下面介绍编程中使用的调整策略和主要算法。
  由于数据库中数据的随机性,特别是字符型和备注型数据长度的不定性,表中各栏位宽度的比例关系很难预先确定,需要在整个报表生成之后进行调整。调整的基本策略是先将各记录中要输出的字段的具体内容输出到表格中,并在输出过程中记下每一栏位在各行中的最大宽度(字符数),用它作为调整各栏位宽度比例关系的依据。如果完全按照此依据进行调整,表体部分一定能编排得比较匀称,但表头部分的编排有可能发生变化(如上面的"采取措施"表头,由于数据库中该字段对应的内容可能很少,在进行栏位宽度调整时,有可能使表头文字变成 多行排列),报表的整体效果仍然较差。所以有必要预先知道各栏位的最小宽度,以防止在调整各栏位宽度时表头多行排列。为此,约定原始文档框架中各栏位的宽度即为最小宽度,且栏位宽度调整仅对字符型和备注型字段进行。
  基于上述调整策略,我们介绍相应的算法。为了便于介绍,我们假设通过页面和页边距的设置得出需要将表格的宽度调宽至nWidth英寸,并定义如下数据类型:
  LOCAL aFieldName[nOutColumn,6]
  其中:
  nOutColumn为要输出字段个数,也是表格的最大列数;
  aFiledName[nOutColumn,1]为书签名;
  aFiledName[nOutColumn,2]为该书签所在栏位对应字段的字段类型;
  aFiledName[nOutColumn,3]为该书签所在栏位对应字段的字段宽度;
  aFiledName[nOutColumn,4]为该书签所在栏位对应字段的小数位数;
  aFiledName[nOutColumn,5]为该书签所在栏位最小TWIP数;(1英寸 =1440 TWIP)
  aFiledName[nOutColumn,6]为该书签所在栏位在各行中的最大字符个数。
  这样在计算出各栏位的最大字符个数和各栏位的最小TWIP数后,就可以计算出需要调整栏位的总字符数和可供使用的宽度总TWIP数。
  假设可供使用的宽度总数为j(TWIP),需要调整栏位的总字符数为(字符),则某要调整栏位的宽度应为: j/k*aFieldName[i,6] 式中i为该调整栏在表中的列号。 但是该宽度有可能小于该栏位的最小宽度,这样该栏位就不应调 整,需要将该栏的类型a FieldName[i,2]修改为"U"(非C且非M即可), 而将该栏位列入非调整的行列,同时也要相应修改j和k,再从第一列逐 一检查,查看是否仍有这样的列,如果有需要再重复上述步骤。直到不 再有上述类型的列为止。最后再用TableColumnWidth命令对剩下需要 调整的栏位进行调整即可。
  三、生成Word文档的程序实现 根据上面的调整策略和算法,我们给出用VFP编制的从VFP数据库 输出Word文档的通用程序。此程序不依赖具体的数据库结构,也不依赖于具体的报表输出格式,可用于任何VFP数据库的Word文档输出。
  
  LOCAL nOldrecno,oleWord,i,j,k,nOutColumn,cString
  LOCAL aFieldList[1]
  USE b1
  IF EOF() &&无输出结果则直接返回
  RETURN
  ENDIF
  =AFIELDS(aFieldList) &&将当前数据库的字段信息存入数组中
  nOldrecno=RECNO()
  *下面首先生成Word.Basic对象,再用Word.Basic的打开文档命令
  打开基本文档框架
  oleWord=CREATEOBJECT("Word.Basic")
  oleWord.FileOpen("c:\mf\data\word.doc")
  *下面是从Word文档的首部向下移动插入点指针,直到移动到表格
  中为止。
  *这样做的原因是,基本文档框架中在表格的上面可以有附加内容。
  DO WHILE oleWord.SelInfo(12)#-1
  oleWord.LineDown
  ENDDO
  *下面是检查书签数与表格的最大列数是否相同
  nOutColumn=oleWord.CountBookMarks()
  IF nOutColumn#oleWord.SelInfo(18)
  oleWord.AppClose("Microsoft Word")
  =MESSAGEBOX("书签与表格的列数不符",16,"提示信息")
  RETURN
  ENDIF
  *下面是定义列信息数组,并且填写该数组的前4列内容
  LOCAL aFieldName[nOutColumn,6]
  *-- aFieldName列的意义:1书签名,2字段类型,3字段宽度,4,小
  数位数,
  *-- 5原始表中各列宽度的最小TWIP数
  *-- 6在具体的填写过程中该书签所在列的所有行中的字符的最
  大个数
  FOR i=1 to nOutColumn
  aFieldName[i,1]=oleWord.BookMarkName(i)
  FOR j = 1 TO FCOUNT()+1
  IF j=FCOUNT()+1
  oleWord.AppClose("Microsoft Word")
  =MESSAGEBOX("标签名:"+aFieldName[i,1];
  +"不是数据库的字段名",16,"
  提示信息")
  RETURN
  ENDIF
  IF UPPER(aFieldName[i,1])==UPPER(ALLT(aFieldLis
  t[j,1]))
  aFieldName[i,2]=aFieldList[j,2] &&类型
  aFieldName[i,3]=aFieldList[j,3] &&宽度
  aFieldName[i,4]=aFieldList[j,4] &&小数位
  EXIT
  ENDIF
  ENDFOR
  ENDFOR
  *将插入点移到表格最底行的最右端
  DO WHILE oleWord.SelInfo(12)=-1
  oleWord.LineDown
  ENDDO &&按下箭头向下移出表格
  DO WHILE oleWord.SelInfo(12)#-1
  oleWord.CharLeft
责任编辑:lss
  相关新闻
Spring MVC framework总体分析
06年9月计算机等级考试二级VF笔试试卷(Word版)
Spring MVC framework总体分析
WebWork拦截器(Interceptor)使用方法
Oracle中国前员工述说公司高层内部纷争史
Wicket初次接触之HelloWorld
Oracle身份管理套件帮助企业进行安全管理
Oracle下调数据库许可价格 以适应多芯CPU
Oracle数据仓库查询优化技术
Oracle 将加强代码基地安全防御力度
数据库系统工程师:NBU备份ORACLE时Code 29错误
ORACLE中用一条SQL实现其它进制到十进制的转换
06年9月计算机等级三级网络技术笔试试卷(Word版)
06年9月计算机等级考试二级VF笔试试卷(Word版)
Oracle中国前员工述说公司高层内部纷争史
Oracle下调数据库许可价格 以适应多芯CPU
Oracle身份管理套件帮助企业进行安全管理
Oracle 将加强代码基地安全防御力度
Oracle通过期中考试
Oracle IBM 化对手为伙伴 结盟共创IACC
  评论
现在有100人对本文发表评论
查看所有评论
 
推  荐
 
100本成功必读热销书
热门招生
  北京文理研修学院   前进大学
  北京明园大学   北京建设大学
  北京邮电大学世纪学院   北方工商管理学院
  联想软件定向委培班   香港数码动画学院
  青年企业管理研修学院   北京华夏管理学院
热门培训
网络化办公专家培训认证 电子科技大学软件学院
软件测试工程师培训认证 北大青鸟十大授权培训
IT硬件工程师培训认证班 北京环球雅思荷兰预科
JAVA开发工程师培训 潜能时代IT服务管理培训
网络信息化工程师培训 清华大学继续教育学院
论坛精选
 
有些细节是男人也该注意的风度!最容易读错的字
某强人手机里保存的30条短信 中国十大高薪职业
最感人的十大韩剧经典台词 嫁给工程师的N个理由
爆强!只有一句话的鬼故事 转贴教你如何做妖精
 女人一定要記住的話 女人最好别嫁给最爱的男人
城市联盟
 大连 上海 天津 广州 西安 深圳  天津  青岛  大连  福州  沈阳  青海  连云港  南京  吉林  厦门  威海  辽宁  呼和浩特
Copyright © 2006   www.edu999.com   All rights reserved. 中国教育招生在线  版权所有
北京市通信管理局[2004]字第552号函    京ICP证040442号