注册 登录
编程论坛 VFP论坛

怎样让FRX报表文件每页都打印标题

王咸美 发布于 2024-11-06 19:51, 369 次点击
下列程序生成的报表文件,从第二页开始不能打印标题,请高手指点,万分感谢!!!
只有本站会员才能查看附件,请 登录

只有本站会员才能查看附件,请 登录


【程序代码】
CLOSE DATABASES
SET SAFETY OFF
cPath=ADDBS(JUSTPATH(SYS(16)))
SET DEFAULT TO (cPath)
USE F:\Data\陈集小学考试库202306.dbf
dbftofrx([xsxxk2023],[陈集小学2023年秋学期六年级学生名单],0)
REPORT FORM  xsxxk2023.frx  preview


PROCEDURE dbftofrx
*调用方法:DBFTOFRX([<报表文件名>],[<报表标题>],[<打印方向>],[<左页脚>], [<右页脚>])
*使用举例1:
*USE   E:\kb201809\jsrkb201809.dbf
*dbfTofrx('教师任课表', '陈集小学2018年秋学期各班教师任课表',1)
*REPORT   FORM   e:\kb201809\教师任课表 Preview  && 预览
*或 REPORT   FORM   e:\kb201809\教师任课表      && 打印

*使用举例2:
*USE    陈集小学教师
*或 SELECT  *  from  陈集小学教师  WHERE  政治面貌="党员"  into  CURSOR   temp
*或 SELECT  姓名,性别,出生年月,学历,工作时间  from   陈集小学教师  into  cursor  temp
*dbfToFrx( [jsxx2024] , [陈集小学教师信息一览表] , 0 , [制表人:XXX] , [制表单位:陈集小学])
*report   form   jsxx2024   preview

*【VFP9.0代码】
PARAMETERS   报表文件名, 报表标题, L_打印方向, L_左页脚, L_右页脚  
&& 报表文件名不带扩展名,可缺省(缺省文件名为TMP_REPORT),报表标题可缺省
PRIVATE   ALL   LIKE    L_CA*
WAIT   '正在生成报表......'   WINDOW   NOWAIT   NOCLEAR
IF   TYPE('M.报表文件名')='L'   OR   EMPTY(M.报表文件名)
    报表文件名='TMP_REPORT'
ENDIF

* 定义页脚
LeftFooter="制表日期:"+STR(year(DATE()),4)+"年"+STR(month(DATE()),2)+"月"+STR(day(DATE()),2)+"日"
*RightFooter= "共 "+ALLTRIM(STR(_PAGETOTAL))+" 页 第 "+ALLTRIM(STR(_PAGENO))+" 页"
*RightFooter="第 "+ALLTRIM(STR(_PAGENO))+" 页"
RightFooter="  "

IF   EMPTY(L_左页脚)
    L_左页脚=LeftFooter
ELSE
    LeftFooter=L_左页脚
ENDIF

IF   EMPTY(L_右页脚)
    L_右页脚=" "
ELSE
    RightFooter=L_右页脚
ENDIF

IF   EMPTY(L_打印方向)
    L_打印方向=0
ENDIF

L_字符宽度9=625         && FONTSIZE=9
L_字符宽度9粗=729.167   && FONTSIZE=9,粗体
L_字符宽度16=1250       && FONTSIZE=16(半角字符宽度为1250,半个全角字符宽度为1145.833,故由此算得标题居中位置并不准确)
L_域控件宽度修正9=370   && 由"L_字符宽度9"算得域控件宽度需加上此数值,才能完整输出
L_带区指示条高度=2083
L_标题区高度=IIF(TYPE('M.报表标题')='L'  OR  EMPTY(报表标题),0,5000)
L_页标头区高度=2400
L_细节区高度=2400
L_页脚区高度=2500
L_左边距=5000
L_右边距=0

L_页标头区VPOS=L_标题区高度+IIF(L_标题区高度=0,0,L_带区指示条高度)
L_细节区VPOS=L_标题区高度+L_页标头区高度+IIF(L_标题区高度=0,1,2)*L_带区指示条高度
L_TMP=SYS(2015)
L_CA=SELECT(  )
COPY   STRUCTURE   TO   (L_TMP)   EXTE
CREATE   CURSOR   TMP   (TMPFIELD C(10))
CREATE   REPORT   (报表文件名)   FROM   TMP
USE   报表文件名+'.FRX'   EXCL

IF   L_标题区高度#0
*添加标题区
    INSERT   BLANK
    REPLACE   PLATFORM   WITH   'WINDOWS',;
OBJTYPE   WITH   9,;
HEIGHT   WITH   L_标题区高度
ENDIF

*设置左边距
LOCATE   FOR   OBJTYPE=1
REPLACE   HPOS   WITH   L_左边距

*设置打印方向
*默认为0-竖向,如果设为1-横向,则修改打印方向
IF    L_打印方向=1
    REPLACE   EXPR   WITH   SUBSTR( EXPR,1, ATC("ORIENTATION", EXPR)-1)+"ORIENTATION=1"+;
        CHR(10)+SUBSTR( EXPR, ATC("ORIENTATION", EXPR)+ATC(CHR(10),;
        SUBSTR(expr, ATC("orientation", expr),15)))
ENDIF
*设置纸张
REPLACE   EXPR   WITH   SUBSTR( expr,1, ATC("PAPERSIZE",EXPR)-1)+"PAPERSIZE=9"+;
    CHR(10)+SUBSTR( expr, ATC("PAPERSIZE", EXPR)+ATC(CHR(10),;
    SUBSTR( expr,  ATC("PAPERSIZE",EXPR), 15)))

* 获取页面宽度
LOCATE   FOR   EXPR='_PAGENO'
L_页面宽度=HPOS+WIDTH

*增高页标头区
LOCATE   FOR   OBJTYPE=9   AND   OBJCODE=1
L_页标头区原高度=HEIGHT  
L_页标头区增高=L_页标头区高度-HEIGHT  
REPLACE   HEIGHT   WITH   L_页标头区高度

*增高细节区
LOCATE   FOR   OBJTYPE=9   AND   OBJCODE=4
L_细节区原高度=HEIGHT
L_细节区增高=L_细节区高度-HEIGHT
REPLACE   HEIGHT   WITH   L_细节区高度

*增高页脚区
LOCATE   FOR   OBJTYPE=9   AND   OBJCODE=7
REPLACE   HEIGHT   WITH   L_页脚区高度

*标题区以下内容重定位
LOCATE   FOR   OBJTYPE=5
L_列标题高度=HEIGHT

*修改页注脚区内容垂直位置
REPLACE   VPOS   WITH   L_细节区VPOS+L_细节区高度+L_带区指示条高度;
    FOR   VPOS > L_页标头区原高度+L_带区指示条高度+L_细节区原高度;
 AND   INLIST( OBJTYPE ,5,8)

*修改细节区内容垂直位置
REPLACE   VPOS   WITH   L_细节区VPOS+L_细节区增高/2;
    FOR   BETWEEN( VPOS,L_页标头区原高度, L_页标头区原高度+;
L_带区指示条高度+L_细节区原高度)

*修改页标头区内容垂直位置
REPLACE   VPOS   WITH   L_页标头区VPOS+L_页标头区增高/2;
    FOR   VPOS < L_页标头区原高度   AND   !INLIST(OBJTYPE,1,9)

*修改页注脚内容
CALCULATE   MAX(HPOS)   TO   L_MAX   FOR   OBJTYPE=5   AND   TOP
LOCATE   FOR   HPOS=L_MAX
SCATTER   MEMV   MEMO

*添加列标题标签控件、细节区域控件以及表格线
*先保存报表中基于TMPFIELD字段的标签控件和域控件记录,作为生成各列的标题标签控件和细节域控件的依据
LOCATE   FOR   UPPER(EXPR)=["TMPFIELD"]
SCATTER   TO   L_列标题记录   MEMO
DELETE
LOCATE   FOR   UPPER(EXPR)=[TMPFIELD]
SCATTER   TO   L_列细节记录   MEMO
DELETE
PACK
SELECT 0
USE   (L_TMP)

ALTER  TABLE (L_TMP) ADD  是否打印  L
REPLACE  ALL  是否打印  WITH  .T.
BROWSE   FIELDS  Field_name,是否打印 TITLE   "选择打印字段:T-打印,F-不打印 "

L_报表宽度=0
L_HPOS=0
L_GAP=400   && 列与纵线之间的间隙

*设置纵线属性
OBJTYPE=6
EXPR=''
WIDTH=104.167
HEIGHT=L_细节区高度
PENSIZE=1
PENPAT=8
MODE=0

SCAN   FOR   FIELD_TYPE#'G'  AND  是否打印=.T.     && 通用字段除外
    L_列标题高度=TRIM(FIELD_NAME)
    L_列标题宽=LEN(L_列标题高度)*L_字符宽度9粗
    L_列细节宽=FIELD_LEN*L_字符宽度9+L_域控件宽度修正9
    L_列宽=MAX(L_列标题宽,L_列细节宽)
    L_报表宽度=L_报表宽度+WIDTH+2*L_GAP+L_列宽
    L_类型=FIELD_TYPE

    IF   L_报表宽度>L_页面宽度-L_左边距-L_右边距
        *EXIT
    ENDIF

    SELECT   (报表文件名)
    添加纵线()
    L_HPOS=L_HPOS+WIDTH+L_GAP

    *添加列标题
    APPEND   BLANK
    GATHER   FROM   L_列标题记录   MEMO
    REPLACE   EXPR   WITH   ["]+L_列标题高度+["],;
HPOS   WITH   L_HPOS,;
WIDTH   WITH   L_列标题宽

    *添加列细节
    APPEND   BLANK
    GATHER   FROM   L_列细节记录   MEMO
    REPLACE   EXPR  WITH   L_列标题高度,;
HPOS   WITH   L_HPOS,;
WIDTH  WITH   L_列细节宽,;
FILLCHAR   WITH   CHRTRAN( L_类型, 'YFTBIM','NNDNNC')
    *  REPLACE  PICTURE  WITH   IIF(L_类型="N",'"@Z"',"")
DO   CASE
       CASE  L_类型="N"
         REPLACE  PICTURE   WITH   IIF(L_类型="N",'"@Z"',"")  && 数值型字段空值不显示
       CASE  L_类型="D"
         REPLACE  PICTURE   WITH   IIF(L_类型="D",'"@Z"',"{}")  && 日期型字段空值不显示
       CASE  L_类型="L"
         REPLACE  PICTURE   WITH   IIF(L_类型="L",'"@Z"',"(.  .)")  && 逻辑型字段空值不显示
    ENDCASE

    IF   FILLCHAR='N'
        REPLACE   OFFSET   WITH   1
    ENDIF
    L_HPOS=L_HPOS+L_列宽+L_GAP
    SELECT   (L_TMP)
ENDSCAN
USE
SELECT  (报表文件名)
添加纵线()
L_报表宽度=L_HPOS+WIDTH

*添加横线
HPOS=0
HEIGHT=104.167
WIDTH=L_报表宽度
APPEND   BLANK
GATHER   MEMV   MEMO
REPLACE   VPOS   WITH   L_页标头区VPOS
APPEND   BLANK
GATHER   MEMV   MEMO
REPLACE   VPOS   WITH   L_页标头区VPOS+L_页标头区高度
APPEND   BLANK
GATHER   MEMV   MEMO
REPLACE   VPOS   WITH   L_细节区VPOS+L_细节区高度
IF   L_标题区高度#0
    *拷贝一个标签记录并改造成报表标题记录
    LOCATE   FOR   OBJTYPE=5
    SCATTER   MEMV   MEMO
    L_标题宽度=LEN(M.报表标题)*L_字符宽度16
    EXPR=["]+M.报表标题+["]
    VPOS=1000
    HPOS=MAX(0,(L_报表宽度-L_标题宽度)/2)
    WIDTH=L_标题宽度
    HEIGHT=2500
    FONTSIZE=16
    APPEND   BLANK
    GATHER   MEMV  MEMO
ENDIF

*修改页脚区页脚
*设置左页脚
CALCULATE   MAX(HPOS)   TO   L_MAX   FOR   OBJTYPE=5   AND   TOP
LOCATE   FOR   HPOS=L_MAX
IF   !EMPTY(LeftFooter)
    L_页脚宽度=LEN(LeftFooter)*L_字符宽度9
    REPLACE   EXPR   WITH   ["]+LeftFooter+["],;
VPOS   WITH   L_细节区VPOS+L_细节区高度+L_带区指示条高度,;
      HPOS   WITH   0, ;
WIDTH   WITH   L_页脚宽度
ELSE
    DELETE
    PACK
ENDIF

*设置右页脚
LOCATE   FOR   EXPR=[DATE()]   AND   TOP
REPLACE   expr   with   [""]
IF   !EMPTY(RightFooter)
     LOCATE   FOR   EXPR=[_PAGENO]   AND   TOP
     REPLACE   expr   with   [""]
     L_页脚宽度=LEN(RightFooter)*L_字符宽度9
     REPLACE   EXPR   WITH   ["]+RightFooter+["],;
VPOS   WITH   L_细节区VPOS+L_细节区高度+L_带区指示条高度,;
HPOS   WITH   L_报表宽度-L_页脚宽度,;
       WIDTH   WITH   L_页脚宽度,;
OBJTYPE   WITH   5
ELSE
    SCATTER   MEMV   MEMO   
    REPLACE   EXPR   WITH   ["共"],;
HPOS   WITH    L_报表宽度-22*L_字符宽度9,;
WIDTH   WITH   3*L_字符宽度9
    APPEND   BLANK
    GATHER   MEMV   MEMO   
    REPLACE   EXPR   WITH   [_PAGETOTAL],;
HPOS   WITH    L_报表宽度-19*L_字符宽度9,;
WIDTH   WITH    5*L_字符宽度9
    APPEND   BLANK
    GATHER   MEMV   MEMO   
    REPLACE   EXPR   WITH   ["页  第"],;
HPOS   WITH   L_报表宽度-14*L_字符宽度9,;
WIDTH   WITH   6*L_字符宽度9
    APPEND   BLANK
    GATHER   MEMV   MEMO
    REPLACE   EXPR   WITH   ["页"],;
HPOS   WITH   L_报表宽度-3*L_字符宽度9,;
WIDTH   WITH   3*L_字符宽度9
    LOCATE   FOR   EXPR=[_PAGENO]   AND   TOP   
    REPLACE   HPOS   WITH   L_报表宽度-8*L_字符宽度9,;
WIDTH   WITH   3*L_字符宽度9
ENDIF

USE
SELECT   (L_CA)
ERASE   L_TMP+'.*'
WAIT   CLEAR
RETURN

PROCEDURE  添加纵线
APPEND   BLANK
GATHER   MEMV   MEMO
REPLACE   VPOS   WITH   L_页标头区VPOS,;
HPOS   WITH   L_HPOS
APPEND   BLANK
GATHER   MEMV   MEMO
REPLACE   VPOS   WITH   L_细节区VPOS,;
HPOS   WITH   L_HPOS,;
STRETCH   WITH   .T.
ENDPROC


9 回复
#2
王咸美7 天前 09:06
NOREPEAT怎么用在上面代码中?盼高手指点!
#3
sash6 天前 19:32
楼主,vfp的报表文件本身就可以,每页显示标题的,为什么要这样处理?你想得到什么样的效果的报表啊?
#4
王咸美6 天前 22:24
谢谢指点!我创建的是动态报表,对任何dbf表文件都适用。是借鉴别人的代码进行了修改,通用性更强。我想每一页都显示标题,奈何水平有限,不知如何下手,望高手指点:如何将标题带区去掉,将标题写入 “页标头” 带区中。

[此贴子已经被作者于2024-11-8 22:26编辑过]

#5
easyppt5 天前 08:16
你的代码运行有错误提示,我想这可能是阻碍大家帮你的原因。

#6
王咸美5 天前 09:01
代码在VFP9.0上运行正常。
#7
凝聚双眼5 天前 09:27
别人的代码有完整的吗
#8
王咸美5 天前 09:50
这是我从网上下载的程序,请您参考,盼指点,多谢!!!

【一个简易动态报表函数】
*作者:sj_sh
*功能:根据当前工作区的表生成报表文件
*调用方法:DYNAMICREPORT([[<报表文件名>],[<报表标题>]])
*使用举例:
*USE MYTABLE
*DYNAMICREPORT('MYREPORT','我的动态报表')
*REPO FORM MYREPORT ......
*或:
*SELE ...... FROM MYTABLE INTO CURS TMP
*DYNAMICREPORT(,'我的动态报表')
*REPO FORM TMP_REPORT ......
PARAMETERS 报表文件名,报表标题 &&报表文件名不带扩展名,可缺省(缺省文件名为TMP_REPORT),报表标题可缺省
PRIVATE ALL LIKE L_*
WAIT '正在生成报表......' WINDOW NOWAIT NOCLEAR
IF TYPE('M.报表文件名')='L' OR EMPTY(M.报表文件名)
报表文件名='TMP_REPORT'
ENDIF
L_字符宽度9=625 &&FONTSIZE=9
L_字符宽度9粗=729.167 &&FONTSIZE=9,粗体
L_字符宽度16=1250 &&FONTSIZE=16(半角字符宽度为1250,半个全角字符宽度为1145.833,故由此算得标题居中位置并不准确)
L_域控件宽度修正9=370 &&由“L_字符宽度9”算得域控件宽度需加上此数值,才能完整输出
L_带区指示条高度=2083
L_标题区高度=IIF(TYPE('M.报表标题')='L' OR EMPTY(报表标题),0,5000)
L_页标头区高度=2400
L_细节区高度=2400
L_页标头区VPOS=L_标题区高度 IIF(L_标题区高度=0,0,L_带区指示条高度)
L_细节区VPOS=L_标题区高度 L_页标头区高度 IIF(L_标题区高度=0,1,2)*L_带区指示条高度
L_TMP=SYS(2015)
L_CA=SELECT()
COPY STRUCTURE TO (L_TMP) EXTE
CREATE CURSOR TMP (TMPFIELD C(1))
CREATE REPORT (报表文件名) FROM TMP
USE 报表文件名 '.FRX' EXCL
IF L_标题区高度#0
*添加标题区
INSERT BLAN
REPLACE PLATFORM WITH 'WINDOWS',OBJTYPE WITH 9,HEIGHT WITH L_标题区高度
ENDIF
LOCATE FOR EXPR='_PAGENO'
L_页面宽度=HPOS WIDTH
*增高页标头区
LOCATE FOR OBJTYPE=9 AND OBJCODE=1
L_页标头区原高度=HEIGHT
L_页标头区增高=L_页标头区高度-HEIGHT
REPLACE HEIGHT WITH L_页标头区高度
*增高细节区
LOCATE FOR OBJTYPE=9 AND OBJCODE=4
L_细节区原高度=HEIGHT
L_细节区增高=L_细节区高度-HEIGHT
REPLACE HEIGHT WITH L_细节区高度
*标题区以下内容重定位
LOCATE FOR OBJTYPE=5
L_列标题高度=HEIGHT
*修改页注脚区内容垂直位置
REPLACE VPOS WITH L_细节区VPOS L_细节区高度 L_带区指示条高度;
FOR VPOS>L_页标头区原高度 L_带区指示条高度 L_细节区原高度 AND INLIST(OBJTYPE,5,8)
*修改细节区内容垂直位置
REPLACE VPOS WITH L_细节区VPOS L_细节区增高/2;
FOR BETWEEN(VPOS,L_页标头区原高度,L_页标头区原高度 L_带区指示条高度 L_细节区原高度)
*修改页标头区内容垂直位置
REPLACE VPOS WITH L_页标头区VPOS L_页标头区增高/2;
FOR VPOS<L_页标头区原高度 AND !INLIST(OBJTYPE,1,9)
*修改页注脚内容
CALCULATE MAX(HPOS) TO L_MAX FOR OBJTYPE=5 AND TOP
LOCATE FOR HPOS=L_MAX
SCATTER MEMV MEMO
REPLACE EXPR WITH ["第"],HPOS WITH L_页面宽度-10*L_字符宽度9,WIDTH WITH 2*L_字符宽度9
APPEND BLANK
GATHER MEMV MEMO
REPLACE EXPR WITH ["页"],HPOS WITH L_页面宽度-2*L_字符宽度9,WIDTH WITH 2*L_字符宽度9
LOCATE FOR EXPR=[_PAGENO] AND TOP
REPLACE HPOS WITH L_页面宽度-8*L_字符宽度9,WIDTH WITH 5*L_字符宽度9
LOCATE FOR EXPR=[DATE()] AND TOP
REPLACE HPOS WITH HPOS 11*L_字符宽度9
APPEND BLANK
GATHER MEMV MEMO
REPLACE EXPR WITH ["打印日期:"],HPOS WITH 0,WIDTH WITH 10*L_字符宽度9
*添加列标题标签控件、细节区域控件以及表格线
*先保存报表中基于TMPFIELD字段的标签控件和域控件记录,作为生成各列的标题标签控件和细节域控件的依据
LOCATE FOR UPPER(EXPR)=["TMPFIELD"]
SCATTER TO L_列标题记录 MEMO
DELETE
LOCATE FOR UPPER(EXPR)=[TMPFIELD]
SCATTER TO L_列细节记录 MEMO
DELETE
PACK
SELECT 0
USE (L_TMP)
L_报表宽度=0
L_HPOS=0
L_GAP=400 &&列与纵线之间的间隙
*设置纵线属性
OBJTYPE=6
EXPR=''
WIDTH=104.167
HEIGHT=L_细节区高度
PENSIZE=1
PENPAT=8
MODE=0
SCAN FOR FIELD_TYPE#'G' &&通用字段除外
L_列标题=TRIM(FIELD_NAME)
L_列标题宽=LEN(L_列标题)*L_字符宽度9粗
L_列细节宽=FIELD_LEN*L_字符宽度9 L_域控件宽度修正9
L_列宽=MAX(L_列标题宽,L_列细节宽)
L_报表宽度=L_报表宽度 WIDTH 2*L_GAP L_列宽
L_类型=FIELD_TYPE
IF L_报表宽度>L_页面宽度
EXIT
ENDIF
SELECT (报表文件名)
添加纵线()
L_HPOS=L_HPOS WIDTH L_GAP
*添加列标题
APPEND BLANK
GATHER FROM L_列标题记录 MEMO
REPLACE EXPR WITH ["] L_列标题 ["],HPOS WITH L_HPOS,WIDTH WITH L_列标题宽
*添加列细节
APPEND BLANK
GATHER FROM L_列细节记录 MEMO
REPLACE EXPR WITH L_列标题,HPOS WITH L_HPOS,WIDTH WITH L_列细节宽,FILLCHAR WITH CHRTRAN(L_类型,'YFTBIM','NNDNNC')
IF FILLCHAR='N'
REPLACE OFFSET WITH 1
ENDIF
L_HPOS=L_HPOS L_列宽 L_GAP
SELECT (L_TMP)
ENDSCAN
USE
SELECT (报表文件名)
添加纵线()
L_报表宽度=L_HPOS WIDTH
*添加横线
HPOS=0
HEIGHT=104.167
WIDTH=L_报表宽度
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_页标头区VPOS
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_页标头区VPOS L_页标头区高度
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_细节区VPOS L_细节区高度
IF L_标题区高度#0
*拷贝一个标签记录并改造成报表标题记录
LOCATE FOR OBJTYPE=5
SCATTER MEMV MEMO
L_标题宽度=LEN(M.报表标题)*L_字符宽度16
EXPR=["] M.报表标题 ["]
VPOS=1000
HPOS=MAX(0,(L_报表宽度-L_标题宽度)/2)
WIDTH=L_标题宽度
HEIGHT=2500
FONTSIZE=16
APPEND BLANK
GATHER MEMV MEMO
ENDIF
USE
SELECT (L_CA)
ERASE L_TMP '.*'
WAIT CLEA
RETURN
PROCEDURE 添加纵线
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_页标头区VPOS,HPOS WITH L_HPOS
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_细节区VPOS,HPOS WITH L_HPOS,STRETCH WITH .T.
RETURN
#9
sam_jiang5 天前 15:06
用报表设计器吧,一个系统通常报表是没法通用的,内容不同,需求不同。。。
#10
schtg4 天前 06:52
回复 楼主 王咸美
可否直接将标题 写在 Page Herder 区域,不写在 Title 区域,只要能达到相同的效果就可以吧
1