自定义报表预览控制工具条

自定义报表预览控制工具条



说明:原有的VFP的打印预览用多了感觉真的不是很方便,在某些特定的要求下,她就显得很笨拙,尤其那个打印工具条上的打印机按纽,一点就打印了,有时候我们需要在那个时候进行有选择性的打印而不是全盘的打出来,也不是很麻烦的还要再关闭打印预览返回去再提示性的打印,所以此次更新在原有的自定义报表预览窗口以及计算报表总页数的基础上,增加自定义的工具条,而使程序显得更个性化。

提示:因为该文处于文章排版的需要,所以采用了汉字双字节的空格,而这些空格在程序中执行会提示错误,所以请将以下代码选择复制后,请再处理去掉其中包含的双字节空格,可用一些文字处理软件将双字节空格“ ”全部替换为单字节空格!

*-- 程序名称:RptPreview.prg
*-- 程序功能:以自定义的窗口显示报表的同时,显示自定义的工具条控制报表的预览打印...
*-- 使用方法:RptPreview ( [,cTitleName])
*    或者:do RptPreview with [, cTitleName ]
*-- 程序说明:cReportName 为 报表文件名(无须带扩展名),如果省略的话,则可显示工具条
*       cTitlename 为 报表的标题(可省略,然后以报表文件名做标题)
*       报表的扩展名以 frx 为准
*-- 原创作者:红虎
*-- 联系方式:E-mail: hu_feng@163.net  
*       HomePage: http://www.honghoo.net
*       Oicq: 1569040
*-- 编写日期:2001年1月


Func RPTPreview
para cReportName,cTitleName
#define ready_loc    "预览报表 ..."
#define noRptFile_loc  "报表文件&cReportName.不存在!"
#define noData_loc    "当前工作区没有可共预览的数据,终止!"
#define RptExist_loc   "是否替换原有的报表预览?"
#define error_loc    "错误"
#define NoRpt_loc    "没有报表可预览"
#define RptShut_loc   "预览报表已经关闭!"
#define RptClose_loc   "关闭打印预览窗口?"
#define Preview_name   "报表名称"    && 用来显示报表内容的窗口
#define Time_Refresh   500       && 时钟刷新频率(微秒)
set message to ready_loc

#define isPicBtn   .T.    && 是否使用图片按纽,如果为假时将采用文字按纽
#define btn_width   iif(isPicBtn,23,56)   &&  按纽的宽度
#define btn_height  iif(isPicBtn,22,25)   &&  按纽的高度

*-- 设定按纽的图片及标题
#define home_name   iif(isPicBtn,"","首页")
#define home_pic   iif(isPicBtn,"btnhome.bmp","")
#define prev_name   iif(isPicBtn,"","上页")
#define prev_pic   iif(isPicBtn,"btnprev.bmp","")
#define next_name   iif(isPicBtn,"","下页")
#define next_pic   iif(isPicBtn,"btnnext.bmp","")
#define end_name    iif(isPicBtn,"","末页")
#define end_pic    iif(isPicBtn,"btnend.bmp","")

#define setup_name  iif(isPicBtn,"","设置...")
#define setup_pic  iif(isPicBtn,"btnsetup.bmp","")
#define print_name  iif(isPicBtn,"","打印...")
#define print_pic  iif(isPicBtn,"btnprint.bmp","")
#define info_name  iif(isPicBtn,"","信息")
#define info_pic   iif(isPicBtn,"btnprop.bmp","")
#define close_name  iif(isPicBtn,"","关闭")
#define close_pic  iif(isPicBtn,"btnclose.bmp","")


*-- 显示预览工具条
if type("oPrvToolsBar")="O" and !isnull(oPrvToolsBar)
  *-- 如果已存在打印工具条,提示信息及打开工具条上的检查时钟
  oPrvToolsBar.msg.rpt_info.caption = ready_loc
  oPrvToolsBar.ChkTimer.enabled = .T.  
else
  *-- 如果不存在打印工具条,则创建该工具条
  public oPrvToolsBar    && 定义工具条对象的全局变量
  oPrvToolsBar=CreateObject("preview")  && 创建工具条
  oPrvToolsBar.msg.addobject("rpt_info","rpt_info")  && 添加一个信息提示文本框
  oPrvToolsBar.dock(0)  && 使工具条在屏幕的最上边
  oPrvToolsBar.show    && 显示工具条
endif

  
*-- 判断是否正确传递报表标题参数
if type("cTitleName")#"C"
  *-- 如果报表标题的数据类型不是字符型的,那么将报表标题用报表的名称来代替
  cTitleName  = cReportName
endif

*-- 判断是否正确传递报表文件名参数
if type("cReportName")#"C" or isNull(cReportName)
  *-- 如果传递来的报表的名称不是字符型或是空的,那么应该终止,并提示没有报表可显示
  *-- 此时如果存在报表预览窗口,那么要重新来获取该报表的信息

  with oPrvToolsBar
  if wexist(Preview_name)
    .isInited = .T.
    .pageno  = 0
    .rptName = pcRptName
    .rptTitle = pcRptName
  else
    .msg.rpt_info.caption = NoRpt_loc
  endif
  endwith
  retu .f.
else
  *-- 报表文件名的扩展名以 FRX 为准
  if !file("&cReportName..frx")  
    *-- 如果传递来的报表文件不存在,那么应该终止,并提示文件不存在
    messagebox(noRptFile_loc,16,error_loc)
    retu .f.
  endif
endif  

*-- 判断是否当前有数据打开
*  对于报表来讲需要当前有数据表被打开,否则也会自动弹出打开数据对话框
*  所以,如果当前没有数据表打开,或打开的表的记录数为0时,应该终止。
if !used() or recc()=0
  if messagebox(noData_loc,1+48,error_loc) = 2
    retu .f.
  endif
endif  

*-- 得到正确的报表文件名和报表标题
oPrvToolsBar.rptName = cReportName
oPrvToolsBar.rptTitle = cTitleName

*-- 定义预览窗口
*  这个窗口相当于一个容器,用来容纳报表预览窗口,预览窗口的特征可以从这个窗口来继承

DEFINE WINDOW WinRptPre ;
  FROM 0,0 TO SROWS()-10,SCOLS()-10 ;
  FLOAT system CLOSE GROW ZOOM noMINIMIZE ;
  TITLE Preview_name +": "+cTitleName

*-- 计算报表总页数
report form &cReportName nocons environment
_pepage  = _pageno   && 将报表总页数记录在系统变量_pepage中,
            && 注意该变量不可以小于等于0,否则系统出错
            && 当报表计算出来没有可供显示的内容时,
            && 系统变量_pageno最小也是返回1,不会小于0
            
pnTotalPages=_pageno   && 此总页数变量由用户自定义,可以用到报表中显示"共几页"的形式
            && 当使用该变量时,应实现用 public 来定义

*-- 将预览所要显示的窗口最大化
ZOOM WINDOW WinRptPre MAX

*-- 显示报表,之前把原先有的先释放!
if wexist(Preview_name)    && 存在已有报表预览窗口
  if messagebox(RptExist_loc,4+32,"询问") = 7  && 询问是否替换原有的窗口
    activate window Preview_name  && 如果不替换,则激活原有的报表预览窗口
    zoom window Preview_name max  && 并将该窗口最大化
    retu .F.            && 终止程序的继续执行
  endif
endif

*-- 不管是否已经存在原有报表,首先释放原有的报表预览的窗口
*  如果该窗口不存在的话,则不做任何动作
release window Preview_name
*-- 显示预览报表在刚才定义的窗口范围内,并不等待,继续执行,
*  如没有nowait参数,报表象一个模式窗口会停留不前,
*  那么接下去的程序运行会因为没有该报表的存在而产生错误
*  所以在这里这个NOWAIT很有必要,不可去掉!!!
REPORT FORM &cReportName PREVIEW WINDOW WinRptPre NOWAIT

*-- 将系统打印预览工具条移到屏幕右下角,并释放她
move window "打印预览" to 100,100
release window "打印预览"


*-- 释放原有的用来放置预览窗口的"容器"窗口
release window WinRptPre

*-- 初始化工具条完成
*  并标记工具条上的一个是否已初始属性为真.
oPrvToolsBar.isInited   = .T.

*-- 定义报表文件名为全局变量
public pcRptName
pcRptName = cReportName

set message to "预览报表完成"


*-- 定义控件:用来显示报表页数状态
Define Class rpt_info AS label
    AutoSize = .T.
    Caption = "初始化报表 ..."
    Height = 16
    Left = 5
    Top = 6
    Width = 86
    ForeColor = RGB(0,0,255)
    Name = "rpt_info"
    Visible = .T.
EndDefine

*-- 定义控件:打印控制工具条
DEFINE CLASS preview AS toolbar

  Caption = "报表预览打印控制"
  Name = "preview"
  
  *-- 对工具条新增以下属性
  pageno    = 0
  isinited = .F.  && 是否初始完毕
  rptName = ""  && 当前报表文件名
  rptTitle = norpt_loc  && 当前报表名称
  isRptTop = .T.  && 报表是否最前
  isRptBot = .T.  && 报表是否最尾

  ADD OBJECT separator1 AS separator  && 加上工具条分隔栏
  ADD OBJECT separator2 AS separator
  
  ADD OBJECT msg AS container WITH ;
    Width = 110, ;
    Height = btn_height, ;
    SpecialEffect = 1, ;
    Name = "msg"

  ADD OBJECT separator5 AS separator

  ADD OBJECT cmdhome AS commandbutton WITH ;
    Height = btn_height, ;
    Width = btn_width, ;
    Caption = home_name, ;
    Name = "cmdHome", ;
    ToolTipText = "第一页", ;
    Picture = home_pic

  ADD OBJECT cmdprev AS commandbutton WITH ;
    Height = btn_height, ;
    Width = btn_width, ;
    Caption = prev_name, ;
    Name = "cmdPrev", ;
    ToolTipText = "上一页" , ;
    Picture = prev_pic

  ADD OBJECT separator7 AS separator

  ADD OBJECT cmdnext AS commandbutton WITH ;
    Height = btn_height, ;
    Width = btn_width, ;
    Caption = next_name, ;
    Name = "cmdNext", ;
    ToolTipText = "下一页", ;
    Picture = next_pic

  ADD OBJECT cmdend AS commandbutton WITH ;
    Height = btn_height, ;
    Width = btn_width, ;
    Caption = end_name, ;
    Name = "cmdEnd", ;
    ToolTipText = "最后一页" , ;
    Picture = end_pic

  ADD OBJECT separator9 AS separator
  
  ADD OBJECT cmdSetup AS commandbutton WITH ;
    Height = btn_height, ;
    Width = btn_width, ;
    Caption = setup_name, ;
    Name = "cmdSetup", ;
    ToolTipText = "系统打印机设置", ;
    Picture = setup_pic

  ADD OBJECT cmdprint AS commandbutton WITH ;
    Height = btn_height, ;
    Width = btn_width, ;
    Caption = print_name, ;
    Name = "cmdPrint", ;
    ToolTipText = "进入报表打印设置", ;
    Picture = print_pic

  ADD OBJECT separator10 AS separator

  ADD OBJECT cmdInfo AS commandbutton WITH ;
    Height = btn_height, ;
    Width = btn_width, ;
    Caption = info_name, ;
    Name = "cmdInfo", ;
    ToolTipText = "显示报表文件的打印信息", ;
    Picture = info_pic
    
  ADD OBJECT cmdclose AS commandbutton WITH ;
    Height = btn_height, ;
    Width = btn_width, ;
    Caption = close_name, ;
    Name = "cmdClose", ;
    ToolTipText = "关闭当前的报表", ;
    Picture = close_pic

  *-- 工具条的特殊之处是多了一个时钟,用来检查当前页数,及其他的一些信息
  ADD OBJECT ChkTimer AS timer WITH ;
    Interval = time_refresh , ;
    Name = "ChkTimer"

  *-- 控件添加完毕,下面开始控件过程
  
  *-- 工具条初始化
  PROCEDURE Init
    this.ChkTimer.height=0
    this.ChkTimer.width=0
    this.refresh
  ENDPROC

  *-- 到首页
  PROCEDURE cmdHome.Click
    ACTI window Preview_name
    KEYBOARD '{HOME}'
  ENDPROC

  *-- 上翻一页
  PROCEDURE cmdPrev.Click
    ACTI window Preview_name
    KEYBOARD '{PGUP}'
  ENDPROC

  *-- 下翻一页
  PROCEDURE cmdNext.Click
    ACTI window Preview_name
    KEYBOARD '{PGDN}'
  ENDPROC

  *-- 到页尾
  PROCEDURE cmdEnd.Click
    ACTI window Preview_name
    KEYBOARD '{END}'
  ENDPROC

  *-- 系统打印设置
  PROCEDURE cmdSetup.Click
    sys(1037)
  ENDPROC

  *-- 打印选项
  PROCEDURE cmdprint.Click
    *-- 调用打印设置对话框,需要另一个程序的支持: RptPrint
    RptPrint (this.parent.RptName)
  ENDPROC

  *-- 获取报表信息
  PROCEDURE cmdInfo.Click
    *-- 显示报表文件的打印信息,需要另一个程序的支持: DspRptInfo
    DspRptInfo(this.parent.rptname)
  ENDPROC

  *-- 关闭报表预览及打印工具条
  PROCEDURE cmdclose.Click
    if messagebox(RptClose_loc,4+32,this.parent.rptTitle) = 6
      *-- 释放预览窗口
      release window Preview_name  
      *-- 释放打印控制工具条
      this.parent.release
    endif
  ENDPROC

  *-- 工具条刷新
  PROCEDURE Refresh
  With this
  *-- 刷新是对工具条上翻页功能的可用不可用的控制
    do case
      *-- 当页数处于第一,且总页数也是只有一页时,四者都不可用
      case  _pageno=1 and _pepage=1
        .isRptTop =.T.
        .isRptBot =.T.
      *-- 当页数处于第一,且总页数大于一页时,前两者不可用
      case  _pageno=1 and _pepage>1
        .isRptTop =.T.
        .isRptBot =.F.
      *-- 当页数在第一和最大之间时,四者都可用
      case  _pageno>1 and _pageno<_pepage
        .isRptTop =.F.
        .isRptBot =.F.
      *-- 当页数在最后一页时,后两者不可用
      case  _pageno>1 and _pageno=_pepage
        .isRptTop =.F.
        .isRptBot =.T.
    endcase
    *-- 可是当没有初始化时,四者都不可用
    if !this.isInited
      .isRptTop = .T.
      .isRptBot = .T.
    endif
    *-- 甚至四个按纽的可用性,前两个和后两个分别协调一致
    .cmdHome.enabled = !.isRptTop
    .cmdPrev.enabled = !.isRptTop
    .cmdNext.enabled = !.isRptBot
    .cmdEnd. enabled = !.isRptBot
  Endwith

  ENDPROC

  *-- 时钟刷新
  PROCEDURE ChkTimer.Timer
    with this.parent
    *-- 当报表预览初始化,及改变了页号时
    if _pageno # .pageno and .isInited
      .pageno = _pageno  && 当改变了报表的页号后,重新改写属性.pageno的值
      .msg.rpt_info.caption = "第 "+allt(str(_pageno))+" 页,共 "+allt(str(_pepage))+" 页"
      .msg.width = .msg.rpt_info.width + 10  && 调整信息框的宽度使其宽度适中
      .refresh()  && 刷新工具条,使重新改变按纽的可用性
    endif
    
    *-- 当被预览的报表不存在时
    if !wexist(Preview_name) and .isInited
      set message to rptshut_loc
      *-- 初始化失败
      .isInited = .F.
      *-- 使全部按纽不可用.
      .setall("enabled",.F.,"commandbutton")
      *-- 保留打印设置和关闭按纽的可用
      .cmdSetup.enabled=.t.
      .cmdClose.enabled=.t.
      *-- 显示报表信息为没有报表
      .msg.rpt_info.caption = noRpt_loc
      .rptTitle  = noRpt_loc
      *-- 记录当前页数为0,以使下次判断时,当前页数和记录的页数始终不相等
      .pageno = 0
      *-- 关闭时钟的检查
      .ChkTimer.enabled = .F.  
    else
      *-- 打印和报表信息两个按纽的可用性受报表是否初始化影响
      .cmdPrint.enabled  = .isInited
      .cmdInfo. enabled  = .isInited
    endif
      .msg.rpt_info.ToolTipText = .msg.rpt_info.caption

    endwith
  ENDPROC

ENDDEFINE

*-- 结束定义
**************************************************

>>> 请下载该示例 dbf2excel.zip 31.3K如有问题,请来信

注:该下载包中含有的文件有:
执行程序:dbf2excel_sample.prg
自由表表:sample_item.dbf
包含文件:vb_marco.h

报表预览:RptPreview.prg
报表打印:RptPrint.prg
报表信息:DspRptInfo.prg

报表预览工具条上的8个图片文件
报表文件,表单文件,项目文件各一个
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值