| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2471 人关注过本帖
标题:根据当前工件区的表和列宽动态生成报表文件出错
只看楼主 加入收藏
王咸美
Rank: 1
等 级:新手上路
帖 子:579
专家分:0
注 册:2018-1-4
结帖率:97.04%
收藏
已结贴  问题点数:20 回复次数:9 
根据当前工件区的表和列宽动态生成报表文件出错
现有表文件jsrkb20181001.dbf和动态生成报表文件MYREPORT2018.PRG,运行下列语句出错,提示“报表结构文件不能为空!”,如何修改或操作请高手赐教,万分感谢!
use jsrkb20181001
MYREPORT2018('班级学科任课教师','2018年秋学期各班任课教师一览表')
程序及表文件.zip (6.03 KB)
搜索更多相关主题的帖子: 当前 动态生成 报表 文件 出错 
2018-10-12 13:33
gs2536785678
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:45
帖 子:601
专家分:1770
注 册:2017-7-16
收藏
得分:5 
看过了,现在都是用报表设计器来创作一个报表。
象朋友这样程序代码做一个报表已经很少见了。
你也真不容易啊。。。
2018-10-12 14:11
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:335
帖 子:9798
专家分:26886
注 册:2012-2-5
收藏
得分:5 
MYREPORT2018.PRG 文件在何处?

坚守VFP最后的阵地
2018-10-12 18:26
王咸美
Rank: 1
等 级:新手上路
帖 子:579
专家分:0
注 册:2018-1-4
收藏
得分:0 
在附件“程序及表文件”中
2018-10-12 19:45
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:335
帖 子:9798
专家分:26886
注 册:2012-2-5
收藏
得分:0 
只有BAK文件

坚守VFP最后的阵地
2018-10-12 20:31
wcx_cc
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:52
帖 子:352
专家分:1152
注 册:2015-10-2
收藏
得分:5 
先 use 报表名.frx,再 brow .看看能不能打开结构文件。要保证文件存在,也要注意内部数据不能超范围,或类型不符。
2018-10-13 21:48
王咸美
Rank: 1
等 级:新手上路
帖 子:579
专家分:0
注 册:2018-1-4
收藏
得分:0 
现有表文件jsrkb20181001.dbf和动态生成报表文件MYREPORT2018.PRG,运行下列语句出错,提示“报表结构文件不能为空!”,如何修改或操作请高手赐教,万分感谢!
use jsrkb20181001
 MYREPORT2018('班级学科任课教师','2018年秋学期各班任课教师一览表')
程序和表文件.zip (6 KB)


MYREPORT2018.PRG程序如下:
*调用方法:MYREPORT2006([<报表文件名>],[<报表标题>],[<左页眉>],[<中页眉>],[<右页眉>],[<左页脚>],[<中页脚>],[<右页脚>],;
*<报表结构文件名>,<报表打印列数>[,表头字体][,表头字号][,表体字体][,表体字号][,行高][,是否伸展][,打印方向])
*使用举例:
*报表文件放在"C:\TEMP"目录下
*cFilePath="C:\TEMP\"
*IF !DIRECTORY((cFilePath))
*   MD (cFilePath)
*ENDIF
*定义标题,页眉,页脚
*reportname='MYREPORT'  &&报表文件名
*titlename='我的动态报表'  &&报表标题
*leftHeader="编制单位:"
*centerHeader="日期:"+DTOC(DATE())+"至"+DTOC(date())
*rightHeader='"共 "+ALLTRIM(STR(_PAGETOTAL))+" 页 第 "+ALLTRIM(STR(_PAGENO))+" 页"'
*leftFooter="制表人:"
*centerFooter="复核人:"
*rightFooter="打印日期:"+TTOC(DATETIME())
*tmpfilename=SYS(2015)  &&报表结构文件名(随机值)
*lnColumns=thisform.grid1.ColumnCount  &&打印列数
*nLockColumns=thisform.grid1.LockColumns &&锁定列数
*title_f  &&几种可选字体,'黑体','宋体','楷体_GB2312','隶书'
*title_fontsize=16
*detail_f
*detail_fontsize=9
*nRowHeight=1800   &&行高,默认值--2200
*lStretch=.F.   &&溢出时是否伸展,默认值.F.,不伸展
*nOrientation=0   &&打印方向(0-竖向,1-横向),默认为0-竖向
*IS_PRINT_MOREPAGE=.F.  &&是否打印多页

*SELECT * FROM MYTABLE INTO CURSOR TMP_RPT
*SELECT TMP_RPT
*tempfilename=SYS(2015)
*COPY STRUCTURE TO (cFilePath)+(tempfilename) EXTENDED
*SELECT *,space(128) as 列标题,CAST(0 as numeric(10)) as 列宽,.F. as 锁定列,.F. as 打印;
 FROM (cFilePath)+(tempfilename);
 INTO CURSOR (tmpfilename) READWRITE
*USE IN (tempfilename)
*ERASE (cFilePath)+(tempfilename)+'.*'
*SELECT (tmpfilename)
*N=1
*SCAN
*   lcFiledName=IIF(n<=lnColumns,THISFORM.GRID1.COLUMNS(N).HEADER1.CAPTION,FIELD_NAME)
*   lnWidth=IIF(n<=lnColumns,THISFORM.GRID1.COLUMNS(N).WIDTH*100,7500)
*   isLock=IIF(n<=nLockColumns,.T.,.F.)
*   REPLACE 列标题 WITH lcFiledName,列宽 WITH lnWidth,锁定列 WITH isLock
*   N=N+1
*ENDSCAN
*COUNT TO nHideColumns FOR 列宽<=1000  &&隐藏的列数

*PUBLIC nPrint_Columns
*nPrint_Columns=nHideColumns  &&已打印的列数
*DO WHILE .T.
 *SELECT TMP_RPT
 *MYREPORT2006(reportname,titlename,leftHeader,centerHeader,rightHeader,leftFooter,centerFooter,rightFooter,tmpfilename,lnColumns,;
  title_fontname,title_fontsize,detail_fontname,detail_fontsize,nRowHeight,lStretch,nOrientation)
 *REPORT FORM (cFilePath)+(reportname) noeject noconsole to print preview
 *ERASE (cFilePath)+(reportname)+'.*'
 *IF nPrint_Columns<lnColumns and IS_PRINT_MOREPAGE=.T.
 *   nPrint_Columns=nPrint_Columns-nLockColumns
 *   LOOP
 *ELSE
 *   EXIT
 *ENDIF
*ENDDO
*USE IN (tmpfilename)  &&关闭报表结构文件

*报表文件名不带扩展名,可缺省(缺省文件名为TMP_REP)
PARAMETERS 报表文件名,报表标题,leftHeader,centerHeader,rightHeader,leftFooter,centerFooter,rightFooter,L_TMP,lnColumns,;
 L_标题字体,L_标题字号,L_表体字体,L_表体字号,L_行高,L_伸展,L_打印方向
PRIVATE ALL LIKE L_*
*WAIT "正在生成报表......" WINDOW AT SYSMETRIC(2)/24-6,SYSMETRIC(1)/12-13 NOWAIT NOCLEAR
IF EMPTY(报表文件名)
   报表文件名='TMP_REP'
ENDIF
IF EMPTY(L_TMP)
   MESSAGEBOX("报表结构文件不能为空!",16,"提示!")
   RETURN
ENDIF
IF !USED((L_TMP))
   MESSAGEBOX("报表结构文件不存在!",16,"提示!")
   RETURN
ENDIF
IF EMPTY(lnColumns)
   MESSAGEBOX("打印列不能为空或0!",16,"提示!")
   RETURN
ENDIF
IF EMPTY(L_标题字体)
   L_标题字体="黑体"
ENDIF
IF EMPTY(L_标题字号)
   L_标题字号=16
ENDIF
IF EMPTY(L_表体字体)
   L_表体字体="宋体"
ENDIF
IF EMPTY(L_表体字号)
   L_表体字号=9
ENDIF
IF EMPTY(L_行高)
   L_行高=2200
ENDIF
IF EMPTY(L_打印方向)
   L_打印方向=0
ENDIF
L_表体_字符宽度=  (1145.833+(L_表体字号-8)*104.167)/2  &&1145.833--字号8的宽度,104.167--字号每增加1的增加值
L_表体_字符宽度粗= (1354.167+(L_表体字号-8)*104.167)/2   &&1354.167--字号8,粗体的宽度
L_表体_字符高度=  1354.167+(L_表体字号-8)*104.167
L_标题_字符宽度粗=  (1354.167+(L_标题字号-8)*104.167)/2
L_标题_字符高度=  1354.167+(L_标题字号-8)*104.167
L_带区指示条高度=2083
L_标题区高度=0
L_页标头区高度=12000
L_细节区高度=L_行高 + (L_表体字号-8)*208.333
L_页脚区高度=5000
L_总结区高度=L_表体_字符高度
L_左边距=5000
L_右边距=0
L_页标头区VPOS=L_标题区高度+IIF(L_标题区高度=0,0,L_带区指示条高度)
L_细节区VPOS=L_标题区高度+L_页标头区高度+IIF(L_标题区高度=0,1,2)*L_带区指示条高度
L_总结区VPOS=L_标题区高度+L_页标头区高度+L_细节区高度+L_页脚区高度+IIF(L_标题区高度=0,3,4)*L_带区指示条高度
L_CA=SELECT()

L_PATH="\"  &&报表文件所在目录
CREATE CURSOR TEMP (TMPFIELD C(10))  &&字段长度在6位以上,小于6时,在VFP9中会出错
CREATE REPORT (L_PATH)+(报表文件名) FROM TEMP
USE IN TEMP
USE (L_PATH)+报表文件名+'.FRX' EXCL IN 0
SELECT (报表文件名)

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  subs(EXPR, 1, atc("ORIENTATION",EXPR)-1) + "ORIENTATION=1" + chr(10);
  + subs(EXPR,  atc("ORIENTATION",EXPR) + atc(chr(10), subs(expr, atc("ORIENTATION",expr), 15)))
ENDIF

*设置纸张
*REPLACE EXPR WITH  subs(EXPR, 1, atc("PAPERSIZE",EXPR)-1) + "PAPERSIZE=9" + chr(10);
 + subs(EXPR,  atc("PAPERSIZE",EXPR) + atc(chr(10), subs(expr, atc("PAPERSIZE",expr), 15)))

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

*增高页标头区
LOCATE FOR OBJTYPE=9 AND OBJCODE=1
REPLACE HEIGHT WITH L_页标头区高度
*增高细节区
LOCATE FOR OBJTYPE=9 AND OBJCODE=4
REPLACE HEIGHT WITH L_细节区高度
*增高页脚区
LOCATE FOR OBJTYPE=9 AND OBJCODE=7
REPLACE HEIGHT WITH L_页脚区高度

*添加总结区
INSERT BLANK
REPLACE PLATFORM WITH 'WINDOWS',OBJTYPE WITH 9,OBJCODE WITH 8,HEIGHT WITH L_总结区高度

*添加列标题标签控件、细节区域控件以及表格线
*拷贝一个标签记录至数组
LOCATE FOR OBJTYPE=5 AND TOP
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 (L_TMP)
L_报表宽度=0
L_HPOS=0
L_GAP=400  &&列与纵线之间的间隙
*设置纵线属性
OBJTYPE=6
EXPR=''
WIDTH=208.333  &&左边框为粗线
HEIGHT=L_细节区高度
PENSIZE=2
PENPAT=8
MODE=0

*1.通用型字段不打印
*2.只打印列宽大于1000的列
*3.只打印表格控件中显示的列
*4.每页打印锁定列
*5.对于已打印的列不再打印
SCAN FOR FIELD_TYPE<>'G' AND 列宽>1000 AND RECNO()<=lnColumns AND (锁定列=.T. OR 打印=.F.)
     L_列标题=TRIM(列标题)
     L_列标题宽=LEN(L_列标题)*L_表体_字符宽度粗
     L_列细节=TRIM(FIELD_NAME)
     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
     L_列标题_HPOS=L_HPOS+IIF(L_列宽-L_列标题宽>0,(L_列宽-L_列标题宽)/2,0)  &&列标题居中
     *添加列标题
     APPEND BLANK
     GATHER FROM L_列标题记录 MEMO
     REPLACE EXPR WITH ["]+L_列标题+["],VPOS WITH L_页标头区VPOS+L_页标头区高度-L_细节区高度*3/4,HPOS WITH L_列标题_HPOS,;
      WIDTH WITH L_列标题宽,HEIGHT WITH L_表体_字符高度,FONTFACE WITH L_表体字体,FONTSIZE WITH L_表体字号
     *添加列细节
     APPEND BLANK
     GATHER FROM L_列细节记录 MEMO
     REPLACE EXPR WITH L_列细节,VPOS WITH L_细节区VPOS+(L_细节区高度-L_表体_字符高度)/2,HPOS WITH L_HPOS,;
      WIDTH WITH L_列细节宽,HEIGHT WITH L_表体_字符高度,FONTFACE WITH L_表体字体,FONTSIZE WITH L_表体字号,;
      FILLCHAR WITH CHRTRAN(L_类型,'YFTBIM','NNDNNC'),PICTURE WITH IIF(L_类型="N",'"@Z"',""),;
      SUPEXPR WITH IIF(INLIST(L_类型,"D","T"),"!EMPTY(&L_列细节)",""),STRETCH WITH IIF(L_类型="T",.F.,L_伸展)
     IF FILLCHAR='N'
        REPLACE OFFSET WITH 1
     ENDIF
     L_HPOS=L_HPOS+L_列宽+L_GAP
     SELECT (L_TMP)
     WIDTH=104.167  &&表中间为细线
     PENSIZE=1
     REPLACE 打印 WITH .T.
     nPrint_Columns=nPrint_Columns+1
ENDSCAN
*USE IN (L_TMP)  &&关闭报表结构文件
SELECT (报表文件名)
WIDTH=208.333  &&右边框为粗线
PENSIZE=2
添加纵线()
L_报表宽度=L_HPOS+WIDTH

*添加横线
HPOS=0
PENSIZE=2  &&页标头区为粗线
HEIGHT=208.333
WIDTH=L_报表宽度
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_页标头区VPOS+L_页标头区高度-L_细节区高度
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_页标头区VPOS+L_页标头区高度
PENSIZE=1  &&细节区为细线
HEIGHT=104.167
TOP=.F.
BOTTOM=.T.
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_细节区VPOS+L_细节区高度
*为了获得粗边框的效果,在总结区添加一条横线
PENSIZE=1
HEIGHT=104.167
TOP=.T.
BOTTOM=.F.
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_总结区VPOS,SUPEXPR WITH "recno()=reccount()"

*设置标题,页眉
*拷贝一个标签记录至数组
LOCATE FOR OBJTYPE=5 AND TOP
SCATTER MEMV MEMO

IF !EMPTY(报表标题)
    *增加标题
 L_标题宽度=LEN(报表标题)*L_标题_字符宽度粗
 EXPR=["]+报表标题+["]
 VPOS=(L_页标头区高度-L_细节区高度)/3
 HPOS=MAX(0,(L_报表宽度-L_标题宽度)/2)
 WIDTH=L_标题宽度
 HEIGHT=L_标题_字符高度
 FONTSIZE=L_标题字号
 FONTFACE=L_标题字体
 FONTSTYLE=5  &&0-规则 1-粗体 5-下划线,粗体
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

IF !EMPTY(leftHeader)
    *增加左页眉
 L_标题宽度=LEN(leftHeader)*L_表体_字符宽度
 EXPR=["]+leftHeader+["]
 VPOS=L_页标头区高度-L_细节区高度-L_表体_字符高度
 HPOS=0
 WIDTH=L_标题宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

IF !EMPTY(centerHeader)
    *增加中页眉
 L_标题宽度=LEN(centerHeader)*L_表体_字符宽度
 EXPR=["]+centerHeader+["]
 VPOS=L_页标头区高度-L_细节区高度-L_表体_字符高度
 HPOS=MAX(0,(L_报表宽度-L_标题宽度)/2)
 WIDTH=L_标题宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

IF !EMPTY(rightHeader)
    *增加右页眉
 L_标题宽度=18*L_表体_字符宽度
 EXPR=rightHeader
 VPOS=L_页标头区高度-L_细节区高度-L_表体_字符高度
 HPOS=MAX(0,L_报表宽度-L_标题宽度)
 WIDTH=L_标题宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 OBJTYPE=8  &&5-标签 6-直线 8-域控件
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

*在总结区添加页脚
*当最后一页不满页时打印总结区页脚,否则打印页脚区页脚
IF !EMPTY(leftFooter)
 *在总结区添加左页脚
 L_页脚宽度=LEN(leftFooter)*L_表体_字符宽度
 EXPR=["]+leftFooter+["]
 VPOS=L_总结区VPOS+208.333  &&加上横线的高度
 HPOS=0
 WIDTH=L_页脚宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 OBJTYPE=5
 SUPEXPR="recno()=reccount()"
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

IF !EMPTY(centerFooter)
 *在总结区添加中页脚
 L_页脚宽度=LEN(centerFooter)*L_表体_字符宽度
 EXPR=["]+centerFooter+["]
 VPOS=L_总结区VPOS+208.333
 HPOS=(L_报表宽度-L_页脚宽度)/2
 WIDTH=L_页脚宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 OBJTYPE=5
 SUPEXPR="recno()=reccount()"
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

IF !EMPTY(rightFooter)
 *在总结区添加右页脚
 L_页脚宽度=LEN(rightFooter)*L_表体_字符宽度
 EXPR=["]+rightFooter+["]
 VPOS=L_总结区VPOS+208.333
 HPOS=L_报表宽度-L_页脚宽度
 WIDTH=L_页脚宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 OBJTYPE=5
 SUPEXPR="recno()=reccount()"
 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_表体_字符宽度
   REPLACE EXPR WITH ["]+leftFooter+["],VPOS WITH L_细节区VPOS+L_细节区高度+L_带区指示条高度,HPOS WITH 0,;
    WIDTH WITH L_页脚宽度,HEIGHT WITH L_表体_字符高度,OBJTYPE WITH 5,;
    FONTFACE WITH L_表体字体,FONTSIZE WITH L_表体字号,FONTSTYLE WITH 0,;
    SUPEXPR WITH "recno()<>reccount()"
ELSE
   DELETE
   PACK
ENDIF

*设置中页脚
LOCATE FOR EXPR=[_PAGENO] AND TOP
IF !EMPTY(centerFooter)
   L_页脚宽度=LEN(centerFooter)*L_表体_字符宽度
   REPLACE EXPR WITH ["]+centerFooter+["],VPOS WITH L_细节区VPOS+L_细节区高度+L_带区指示条高度,HPOS WITH (L_报表宽度-L_页脚宽度)/2,;
    WIDTH WITH L_页脚宽度,HEIGHT WITH L_表体_字符高度,OBJTYPE WITH 5,;
    FONTFACE WITH L_表体字体,FONTSIZE WITH L_表体字号,FONTSTYLE WITH 0,;
    SUPEXPR WITH "recno()<>reccount()"
ELSE
   DELETE
   PACK
ENDIF

*设置右页脚
LOCATE FOR EXPR=[DATE()] AND TOP
IF !EMPTY(rightFooter)
   L_页脚宽度=LEN(rightFooter)*L_表体_字符宽度
   REPLACE EXPR WITH ["]+rightFooter+["],VPOS WITH L_细节区VPOS+L_细节区高度+L_带区指示条高度,HPOS WITH L_报表宽度-L_页脚宽度,;
    WIDTH WITH L_页脚宽度,HEIGHT WITH L_表体_字符高度,OBJTYPE WITH 5,;
    FONTFACE WITH L_表体字体,FONTSIZE WITH L_表体字号,FONTSTYLE WITH 0,;
    SUPEXPR WITH "recno()<>reccount()"
ELSE
   DELETE
   PACK
ENDIF

USE IN (报表文件名)
SELECT (L_CA)
WAIT CLEAR
RETURN

PROCEDURE 添加纵线
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_页标头区VPOS+L_页标头区高度-L_细节区高度,HPOS WITH L_HPOS
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_细节区VPOS,HPOS WITH L_HPOS,STRETCH WITH .T.
RETURN
2018-10-14 16:39
王咸美
Rank: 1
等 级:新手上路
帖 子:579
专家分:0
注 册:2018-1-4
收藏
得分:0 
现有表文件jsrkb20181001.dbf和动态生成报表文件MYREPORT2018.PRG,运行下列语句出错,提示“报表结构文件不能为空!”,如何修改或操作请高手赐教,万分感谢!
use jsrkb20181001
 MYREPORT2018('班级学科任课教师','2018年秋学期各班任课教师一览表')
[local]1[/local]

MYREPORT2018.PRG程序如下:
*调用方法:MYREPORT2006([<报表文件名>],[<报表标题>],[<左页眉>],[<中页眉>],[<右页眉>],[<左页脚>],[<中页脚>],[<右页脚>],;
*<报表结构文件名>,<报表打印列数>[,表头字体][,表头字号][,表体字体][,表体字号][,行高][,是否伸展][,打印方向])
*使用举例:
*报表文件放在"C:\TEMP"目录下
*cFilePath="C:\TEMP\"
*IF !DIRECTORY((cFilePath))
*   MD (cFilePath)
*ENDIF
*定义标题,页眉,页脚
*reportname='MYREPORT'  &&报表文件名
*titlename='我的动态报表'  &&报表标题
*leftHeader="编制单位:"
*centerHeader="日期:"+DTOC(DATE())+"至"+DTOC(date())
*rightHeader='"共 "+ALLTRIM(STR(_PAGETOTAL))+" 页 第 "+ALLTRIM(STR(_PAGENO))+" 页"'
*leftFooter="制表人:"
*centerFooter="复核人:"
*rightFooter="打印日期:"+TTOC(DATETIME())
*tmpfilename=SYS(2015)  &&报表结构文件名(随机值)
*lnColumns=thisform.grid1.ColumnCount  &&打印列数
*nLockColumns=thisform.grid1.LockColumns &&锁定列数
*title_f  &&几种可选字体,'黑体','宋体','楷体_GB2312','隶书'
*title_fontsize=16
*detail_f
*detail_fontsize=9
*nRowHeight=1800   &&行高,默认值--2200
*lStretch=.F.   &&溢出时是否伸展,默认值.F.,不伸展
*nOrientation=0   &&打印方向(0-竖向,1-横向),默认为0-竖向
*IS_PRINT_MOREPAGE=.F.  &&是否打印多页

*SELECT * FROM MYTABLE INTO CURSOR TMP_RPT
*SELECT TMP_RPT
*tempfilename=SYS(2015)
*COPY STRUCTURE TO (cFilePath)+(tempfilename) EXTENDED
*SELECT *,space(128) as 列标题,CAST(0 as numeric(10)) as 列宽,.F. as 锁定列,.F. as 打印;
 FROM (cFilePath)+(tempfilename);
 INTO CURSOR (tmpfilename) READWRITE
*USE IN (tempfilename)
*ERASE (cFilePath)+(tempfilename)+'.*'
*SELECT (tmpfilename)
*N=1
*SCAN
*   lcFiledName=IIF(n<=lnColumns,THISFORM.GRID1.COLUMNS(N).HEADER1.CAPTION,FIELD_NAME)
*   lnWidth=IIF(n<=lnColumns,THISFORM.GRID1.COLUMNS(N).WIDTH*100,7500)
*   isLock=IIF(n<=nLockColumns,.T.,.F.)
*   REPLACE 列标题 WITH lcFiledName,列宽 WITH lnWidth,锁定列 WITH isLock
*   N=N+1
*ENDSCAN
*COUNT TO nHideColumns FOR 列宽<=1000  &&隐藏的列数

*PUBLIC nPrint_Columns
*nPrint_Columns=nHideColumns  &&已打印的列数
*DO WHILE .T.
 *SELECT TMP_RPT
 *MYREPORT2006(reportname,titlename,leftHeader,centerHeader,rightHeader,leftFooter,centerFooter,rightFooter,tmpfilename,lnColumns,;
  title_fontname,title_fontsize,detail_fontname,detail_fontsize,nRowHeight,lStretch,nOrientation)
 *REPORT FORM (cFilePath)+(reportname) noeject noconsole to print preview
 *ERASE (cFilePath)+(reportname)+'.*'
 *IF nPrint_Columns<lnColumns and IS_PRINT_MOREPAGE=.T.
 *   nPrint_Columns=nPrint_Columns-nLockColumns
 *   LOOP
 *ELSE
 *   EXIT
 *ENDIF
*ENDDO
*USE IN (tmpfilename)  &&关闭报表结构文件

*报表文件名不带扩展名,可缺省(缺省文件名为TMP_REP)
PARAMETERS 报表文件名,报表标题,leftHeader,centerHeader,rightHeader,leftFooter,centerFooter,rightFooter,L_TMP,lnColumns,;
 L_标题字体,L_标题字号,L_表体字体,L_表体字号,L_行高,L_伸展,L_打印方向
PRIVATE ALL LIKE L_*
*WAIT "正在生成报表......" WINDOW AT SYSMETRIC(2)/24-6,SYSMETRIC(1)/12-13 NOWAIT NOCLEAR
IF EMPTY(报表文件名)
   报表文件名='TMP_REP'
ENDIF
IF EMPTY(L_TMP)
   MESSAGEBOX("报表结构文件不能为空!",16,"提示!")
   RETURN
ENDIF
IF !USED((L_TMP))
   MESSAGEBOX("报表结构文件不存在!",16,"提示!")
   RETURN
ENDIF
IF EMPTY(lnColumns)
   MESSAGEBOX("打印列不能为空或0!",16,"提示!")
   RETURN
ENDIF
IF EMPTY(L_标题字体)
   L_标题字体="黑体"
ENDIF
IF EMPTY(L_标题字号)
   L_标题字号=16
ENDIF
IF EMPTY(L_表体字体)
   L_表体字体="宋体"
ENDIF
IF EMPTY(L_表体字号)
   L_表体字号=9
ENDIF
IF EMPTY(L_行高)
   L_行高=2200
ENDIF
IF EMPTY(L_打印方向)
   L_打印方向=0
ENDIF
L_表体_字符宽度=  (1145.833+(L_表体字号-8)*104.167)/2  &&1145.833--字号8的宽度,104.167--字号每增加1的增加值
L_表体_字符宽度粗= (1354.167+(L_表体字号-8)*104.167)/2   &&1354.167--字号8,粗体的宽度
L_表体_字符高度=  1354.167+(L_表体字号-8)*104.167
L_标题_字符宽度粗=  (1354.167+(L_标题字号-8)*104.167)/2
L_标题_字符高度=  1354.167+(L_标题字号-8)*104.167
L_带区指示条高度=2083
L_标题区高度=0
L_页标头区高度=12000
L_细节区高度=L_行高 + (L_表体字号-8)*208.333
L_页脚区高度=5000
L_总结区高度=L_表体_字符高度
L_左边距=5000
L_右边距=0
L_页标头区VPOS=L_标题区高度+IIF(L_标题区高度=0,0,L_带区指示条高度)
L_细节区VPOS=L_标题区高度+L_页标头区高度+IIF(L_标题区高度=0,1,2)*L_带区指示条高度
L_总结区VPOS=L_标题区高度+L_页标头区高度+L_细节区高度+L_页脚区高度+IIF(L_标题区高度=0,3,4)*L_带区指示条高度
L_CA=SELECT()

L_PATH="\"  &&报表文件所在目录
CREATE CURSOR TEMP (TMPFIELD C(10))  &&字段长度在6位以上,小于6时,在VFP9中会出错
CREATE REPORT (L_PATH)+(报表文件名) FROM TEMP
USE IN TEMP
USE (L_PATH)+报表文件名+'.FRX' EXCL IN 0
SELECT (报表文件名)

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  subs(EXPR, 1, atc("ORIENTATION",EXPR)-1) + "ORIENTATION=1" + chr(10);
  + subs(EXPR,  atc("ORIENTATION",EXPR) + atc(chr(10), subs(expr, atc("ORIENTATION",expr), 15)))
ENDIF

*设置纸张
*REPLACE EXPR WITH  subs(EXPR, 1, atc("PAPERSIZE",EXPR)-1) + "PAPERSIZE=9" + chr(10);
 + subs(EXPR,  atc("PAPERSIZE",EXPR) + atc(chr(10), subs(expr, atc("PAPERSIZE",expr), 15)))

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

*增高页标头区
LOCATE FOR OBJTYPE=9 AND OBJCODE=1
REPLACE HEIGHT WITH L_页标头区高度
*增高细节区
LOCATE FOR OBJTYPE=9 AND OBJCODE=4
REPLACE HEIGHT WITH L_细节区高度
*增高页脚区
LOCATE FOR OBJTYPE=9 AND OBJCODE=7
REPLACE HEIGHT WITH L_页脚区高度

*添加总结区
INSERT BLANK
REPLACE PLATFORM WITH 'WINDOWS',OBJTYPE WITH 9,OBJCODE WITH 8,HEIGHT WITH L_总结区高度

*添加列标题标签控件、细节区域控件以及表格线
*拷贝一个标签记录至数组
LOCATE FOR OBJTYPE=5 AND TOP
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 (L_TMP)
L_报表宽度=0
L_HPOS=0
L_GAP=400  &&列与纵线之间的间隙
*设置纵线属性
OBJTYPE=6
EXPR=''
WIDTH=208.333  &&左边框为粗线
HEIGHT=L_细节区高度
PENSIZE=2
PENPAT=8
MODE=0

*1.通用型字段不打印
*2.只打印列宽大于1000的列
*3.只打印表格控件中显示的列
*4.每页打印锁定列
*5.对于已打印的列不再打印
SCAN FOR FIELD_TYPE<>'G' AND 列宽>1000 AND RECNO()<=lnColumns AND (锁定列=.T. OR 打印=.F.)
     L_列标题=TRIM(列标题)
     L_列标题宽=LEN(L_列标题)*L_表体_字符宽度粗
     L_列细节=TRIM(FIELD_NAME)
     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
     L_列标题_HPOS=L_HPOS+IIF(L_列宽-L_列标题宽>0,(L_列宽-L_列标题宽)/2,0)  &&列标题居中
     *添加列标题
     APPEND BLANK
     GATHER FROM L_列标题记录 MEMO
     REPLACE EXPR WITH ["]+L_列标题+["],VPOS WITH L_页标头区VPOS+L_页标头区高度-L_细节区高度*3/4,HPOS WITH L_列标题_HPOS,;
      WIDTH WITH L_列标题宽,HEIGHT WITH L_表体_字符高度,FONTFACE WITH L_表体字体,FONTSIZE WITH L_表体字号
     *添加列细节
     APPEND BLANK
     GATHER FROM L_列细节记录 MEMO
     REPLACE EXPR WITH L_列细节,VPOS WITH L_细节区VPOS+(L_细节区高度-L_表体_字符高度)/2,HPOS WITH L_HPOS,;
      WIDTH WITH L_列细节宽,HEIGHT WITH L_表体_字符高度,FONTFACE WITH L_表体字体,FONTSIZE WITH L_表体字号,;
      FILLCHAR WITH CHRTRAN(L_类型,'YFTBIM','NNDNNC'),PICTURE WITH IIF(L_类型="N",'"@Z"',""),;
      SUPEXPR WITH IIF(INLIST(L_类型,"D","T"),"!EMPTY(&L_列细节)",""),STRETCH WITH IIF(L_类型="T",.F.,L_伸展)
     IF FILLCHAR='N'
        REPLACE OFFSET WITH 1
     ENDIF
     L_HPOS=L_HPOS+L_列宽+L_GAP
     SELECT (L_TMP)
     WIDTH=104.167  &&表中间为细线
     PENSIZE=1
     REPLACE 打印 WITH .T.
     nPrint_Columns=nPrint_Columns+1
ENDSCAN
*USE IN (L_TMP)  &&关闭报表结构文件
SELECT (报表文件名)
WIDTH=208.333  &&右边框为粗线
PENSIZE=2
添加纵线()
L_报表宽度=L_HPOS+WIDTH

*添加横线
HPOS=0
PENSIZE=2  &&页标头区为粗线
HEIGHT=208.333
WIDTH=L_报表宽度
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_页标头区VPOS+L_页标头区高度-L_细节区高度
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_页标头区VPOS+L_页标头区高度
PENSIZE=1  &&细节区为细线
HEIGHT=104.167
TOP=.F.
BOTTOM=.T.
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_细节区VPOS+L_细节区高度
*为了获得粗边框的效果,在总结区添加一条横线
PENSIZE=1
HEIGHT=104.167
TOP=.T.
BOTTOM=.F.
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_总结区VPOS,SUPEXPR WITH "recno()=reccount()"

*设置标题,页眉
*拷贝一个标签记录至数组
LOCATE FOR OBJTYPE=5 AND TOP
SCATTER MEMV MEMO

IF !EMPTY(报表标题)
    *增加标题
 L_标题宽度=LEN(报表标题)*L_标题_字符宽度粗
 EXPR=["]+报表标题+["]
 VPOS=(L_页标头区高度-L_细节区高度)/3
 HPOS=MAX(0,(L_报表宽度-L_标题宽度)/2)
 WIDTH=L_标题宽度
 HEIGHT=L_标题_字符高度
 FONTSIZE=L_标题字号
 FONTFACE=L_标题字体
 FONTSTYLE=5  &&0-规则 1-粗体 5-下划线,粗体
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

IF !EMPTY(leftHeader)
    *增加左页眉
 L_标题宽度=LEN(leftHeader)*L_表体_字符宽度
 EXPR=["]+leftHeader+["]
 VPOS=L_页标头区高度-L_细节区高度-L_表体_字符高度
 HPOS=0
 WIDTH=L_标题宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

IF !EMPTY(centerHeader)
    *增加中页眉
 L_标题宽度=LEN(centerHeader)*L_表体_字符宽度
 EXPR=["]+centerHeader+["]
 VPOS=L_页标头区高度-L_细节区高度-L_表体_字符高度
 HPOS=MAX(0,(L_报表宽度-L_标题宽度)/2)
 WIDTH=L_标题宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

IF !EMPTY(rightHeader)
    *增加右页眉
 L_标题宽度=18*L_表体_字符宽度
 EXPR=rightHeader
 VPOS=L_页标头区高度-L_细节区高度-L_表体_字符高度
 HPOS=MAX(0,L_报表宽度-L_标题宽度)
 WIDTH=L_标题宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 OBJTYPE=8  &&5-标签 6-直线 8-域控件
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

*在总结区添加页脚
*当最后一页不满页时打印总结区页脚,否则打印页脚区页脚
IF !EMPTY(leftFooter)
 *在总结区添加左页脚
 L_页脚宽度=LEN(leftFooter)*L_表体_字符宽度
 EXPR=["]+leftFooter+["]
 VPOS=L_总结区VPOS+208.333  &&加上横线的高度
 HPOS=0
 WIDTH=L_页脚宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 OBJTYPE=5
 SUPEXPR="recno()=reccount()"
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

IF !EMPTY(centerFooter)
 *在总结区添加中页脚
 L_页脚宽度=LEN(centerFooter)*L_表体_字符宽度
 EXPR=["]+centerFooter+["]
 VPOS=L_总结区VPOS+208.333
 HPOS=(L_报表宽度-L_页脚宽度)/2
 WIDTH=L_页脚宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 OBJTYPE=5
 SUPEXPR="recno()=reccount()"
 APPEND BLANK
 GATHER MEMV MEMO
ENDIF

IF !EMPTY(rightFooter)
 *在总结区添加右页脚
 L_页脚宽度=LEN(rightFooter)*L_表体_字符宽度
 EXPR=["]+rightFooter+["]
 VPOS=L_总结区VPOS+208.333
 HPOS=L_报表宽度-L_页脚宽度
 WIDTH=L_页脚宽度
 HEIGHT=L_表体_字符高度
 FONTSIZE=L_表体字号
 FONTFACE=L_表体字体
 FONTSTYLE=0
 OBJTYPE=5
 SUPEXPR="recno()=reccount()"
 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_表体_字符宽度
   REPLACE EXPR WITH ["]+leftFooter+["],VPOS WITH L_细节区VPOS+L_细节区高度+L_带区指示条高度,HPOS WITH 0,;
    WIDTH WITH L_页脚宽度,HEIGHT WITH L_表体_字符高度,OBJTYPE WITH 5,;
    FONTFACE WITH L_表体字体,FONTSIZE WITH L_表体字号,FONTSTYLE WITH 0,;
    SUPEXPR WITH "recno()<>reccount()"
ELSE
   DELETE
   PACK
ENDIF

*设置中页脚
LOCATE FOR EXPR=[_PAGENO] AND TOP
IF !EMPTY(centerFooter)
   L_页脚宽度=LEN(centerFooter)*L_表体_字符宽度
   REPLACE EXPR WITH ["]+centerFooter+["],VPOS WITH L_细节区VPOS+L_细节区高度+L_带区指示条高度,HPOS WITH (L_报表宽度-L_页脚宽度)/2,;
    WIDTH WITH L_页脚宽度,HEIGHT WITH L_表体_字符高度,OBJTYPE WITH 5,;
    FONTFACE WITH L_表体字体,FONTSIZE WITH L_表体字号,FONTSTYLE WITH 0,;
    SUPEXPR WITH "recno()<>reccount()"
ELSE
   DELETE
   PACK
ENDIF

*设置右页脚
LOCATE FOR EXPR=[DATE()] AND TOP
IF !EMPTY(rightFooter)
   L_页脚宽度=LEN(rightFooter)*L_表体_字符宽度
   REPLACE EXPR WITH ["]+rightFooter+["],VPOS WITH L_细节区VPOS+L_细节区高度+L_带区指示条高度,HPOS WITH L_报表宽度-L_页脚宽度,;
    WIDTH WITH L_页脚宽度,HEIGHT WITH L_表体_字符高度,OBJTYPE WITH 5,;
    FONTFACE WITH L_表体字体,FONTSIZE WITH L_表体字号,FONTSTYLE WITH 0,;
    SUPEXPR WITH "recno()<>reccount()"
ELSE
   DELETE
   PACK
ENDIF

USE IN (报表文件名)
SELECT (L_CA)
WAIT CLEAR
RETURN

PROCEDURE 添加纵线
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_页标头区VPOS+L_页标头区高度-L_细节区高度,HPOS WITH L_HPOS
APPEND BLANK
GATHER MEMV MEMO
REPLACE VPOS WITH L_细节区VPOS,HPOS WITH L_HPOS,STRETCH WITH .T.
RETURN
2018-10-14 16:39
wcx_cc
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:52
帖 子:352
专家分:1152
注 册:2015-10-2
收藏
得分:0 
上面程序中,有很多参数没有预付值,要首先付值,更改报表结构文件内的数据,能做到报表样式的打印动态化,但要谨慎,出错率多。 判断结构文件是否正在被使用,要用别名。上面程序段的开头部分改为这样,看看行不行。
**********
close all
L_TMP='TMP_REP.frx'
lnColumns=6 && 从你的表单内任设
use &L_TMP alias rrr

IF EMPTY(报表文件名)
   报表文件名='TMP_REP'
ENDIF
IF EMPTY(L_TMP)
   MESSAGEBOX("报表结构文件不能为空!",16,"提示!")
   RETURN
ENDIF
IF !USED('rrr')
   MESSAGEBOX("报表结构文件不存在!",16,"提示!")
   RETURN
ENDIF
IF EMPTY(lnColumns)
   MESSAGEBOX("打印列不能为空或0!",16,"提示!")
   RETURN
ENDIF
2018-10-14 19:01
schtg
Rank: 12Rank: 12Rank: 12
来 自:https://t.me/pump_upp
等 级:贵宾
威 望:67
帖 子:1544
专家分:3003
注 册:2012-2-29
收藏
得分:5 
回复 楼主 王咸美
参数太多,建议单独放在比如ini之类的参数配置文件中,仅供参考。
2018-10-15 07:16
快速回复:根据当前工件区的表和列宽动态生成报表文件出错
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019929 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved