在VFP中调用Excel
(2011-11-17 10:54:51)
标签:
vfpexcel调用excel |
分类: VFP笔记 |
在VFP中调用Excel
VFP的打印功能较弱,如果在VFP6中调用Excel,把需要打印的数据导入其中,就可以利用Excel强大的打印功能打印出较为美观的表格。而且,必要时还可以在Excel中对表格的格式或数据进行再编辑。
下面举例说明VFP6中调用Excel的方法。
有一个表:SP_JK.dbf,存放全年商品进库的有关数据(该表有一名为MON的、用以存放购进月份的字段)。现需要打印指定月份的全部(约200多条)记录的SPMC(商品名称)、JLDW(计量单位)、GRSL(购入数量)、PJDJ(平均单价)、GRJE(购入金额)等数据,并在最后一行打印出全部商品的合计金额。原表中没有PJDJ(平均单价)字段,须根据购入数量与购入金额临时计算。要求字段(列与列)之间用竖线隔开,记录(行与行)之间不要横线(尽量减少针头的磨损),但每页最后一行要划横线。具体方法:
一)先在Excel中设计表格。
(1)先设计表头,表头有三行,第一行为表的名称:“购入商品一览表”,第二行为日期等,第三行为字段名(如前所述,共5列)。由于是多页打印,需要在Excel的菜单--文件--页面设置--工作表中设置顶端标题行为 $1:$3,并在页眉/页脚中设置页码的打印格式。
(2)第四行开始为表体,最好在表体的首行输入示例数据,以便于设置单元格的格式(如数据类型、对齐方式等),然后使用工具栏中格式刷,把约300行的表体均刷成此格式。
(3)设置纸型后,预览一下打印效果,并通过调整页边距,确定每页的行数。(本例中,我们取25行)
(4)最后,将设置满意的Excel表格另存为模板,取名为spjkb.xlt
(以上许多工作,也可以在VFP中调用Excel时,用运行程序代码的方式完成,但程序代码的长度将是十分惊人的)
二)在VFP中设计名为PrintForm的窗体
(1)在窗体的数据环境中加入SP_JK.dbf。
(2)窗体上方放一个Lable控件,设置它的Caption属性为:打印购入商品表一览表;
(3)窗体中部放一个Combobox控件,设置它的Name属性为:cmbMonth, RowSourceType属性为3(SQL Statement)、 RowSource属性为 “SELE DISTINCT MON FROM SP_JK INTO CURSOR MYSP_JK ORDER BY MON DESC”;
(4)窗体下方放两个Commandbutton控件,它们的Name属性分别为Button1、Button2,Caption属性分别为“打印”、“导出Excel”。在Button1的Click事件中输入代码:thisform.MyPrint("PRINTOUT"),在Button2的Click事件中输入代码:thisform.MyPrint("PRINTPREVIEW")。
(5)在窗体中添加一个名为MyPrint的方法,该方法的程序代码如下:
PARA LP_FLAG
SELECT SP_JK
COPY TO TmpSP_JK FOR VAL(MON)=VAL(ThisForm. CmbMonth.value)
SELECT 0
USE TmpSP_JK
alter table TmpSP_JK add column PJDJ N(6,2) &&添加字段
replace
calculate sum(GRJE) to
INSERT INTO TmpSP_JK (SPMC,GRJE) VALUES (“合计”,Ngrje)
****以下创建一个EXCEL对象,
****并以spjkb.xlt为模板创建一个工作表
MYAPP=createobject("EXCEL.APPLICATION")
MYAPP.WORKBOOKS.add ("spjkb.xlt")
&&(如:MYAPP.WORKBOOKS.add
(cMYPATH+"MYVFP\MYEXCEL\spjkb.XLT")
MYSHEET=MYAPP.ACTIVESHEET
PAGE_ROW=25
SHEET_TOP=3
MAX_COL=5
ARRY_COL=5
**有时需要在表格中添加一个空白的列,
**所以表格列数与字段个数不一定相同
**两者分别定义有助于日后维护
count to MAX_N
DIME
GO TOP
Copy to ARRAY
MYSHEET.CELLS(2,1).VALUE=alltrim(omybegin.this_sys_name)
MYSHEET.CELLS(2,3).VALUE=ThisForm.CmbMonth.value
MYSHEET.Range("A4:E300").ClearContents
FOR N=1
TO MAX_N
FOR J=1 TO ARRY_COL
MYSHEET.CELLS(SHEET_TOP+N,J).VALUE=MYARRY(N,J)
NEXT J
IF MOD(N,PAGE_ROW)=0
mysheet.range(MYSHEET.CELLS(SHEET_TOP+N,1),;
MYSHEET.CELLS(SHEET_TOP+N,MAX_COL)).;
Borders(4).LineStyle = 1
ENDIF
IF alltrim(MYARRY(N,1))='合计'
mysheet.range(MYSHEET.CELLS(N+3,1),;
MYSHEET.CELLS(N+3,MAX_COL)).;
Borders(4).LineStyle = 1
mysheet.range(MYSHEET.CELLS(N+4,1),;
MYSHEET.CELLS(N+4,MAX_COL)).;
Borders(4).LineStyle = 1
ENDIF
NEXT N
mysheet.range(MYSHEET.CELLS(SHEET_TOP+1,1),;
MYSHEET.CELLS(MAX_N+4,MAX_COL)).;
Borders(1).LineStyle = 1
mysheet.range(MYSHEET.CELLS(SHEET_TOP+1,MAX_COL-1),;
MYSHEET.CELLS(MAX_N+4,MAX_COL)).;
Borders(2).LineStyle = 1
IF LP_FLAG=“PRINTOUT”
***按下“打印”按钮时
***不显示Excel界面,直接打印
mysheet.PrintOut
ELSE
***按下“导出Excel”按钮时
***显示Excel界面,可在Excel中再编辑
MYAPP.VISIBLE=.T.
ENDIF
release
注:
(如要将生成的EXECL表文档存盘,可用MYAPP.ActiveWorkbook.saveas()。下面摘自工资系统中个人得税申报模块:
myname="正常工资薪金收入"+cMO+".XLS"
MYAPP.ActiveWorkbook.saveas("d:\个人所得税申报\"+myname)
MESSAGEBOX('已输出到 D:\个人所得税申报 ',0+48,'提示')
补充说明几点:
(1)上例中的平均单价,也可以不通过增加表的字段来解决。例如,可以在设计Excel表格时,在相应列的所有单元格中输入公式,让Excel去计算。
(2)把大量数据导入Excel时,可能要花费较多的时间,最好能加上一个进度条。
(本文主要内容在Win98、VFP6、Excel2000中测试通过)

加载中…