mydoc2.Activate
range2.Copy
mydoc1.Activate
Selection.Paste
EndIf
Nextm
Documents(mydoc2).Closesavechanges:
=wdDoNotSaveChanges
EndSub
编程实现VFP6.0操纵Word灵活打印特殊格式的报表
VFP6.0作为优秀的桌面型数据库系统,提供了强大的报表、标签输出功能。
但是在实际应用中,其提供的报表输出格式常常不符合要求,有时会碰到一些复杂格式的表格,有时要多报表同文档输出,用VFP6.0的报表设计功能难于实现。
在实际应用中笔者尝试编程实现用VFP6.0操纵Word灵活打印各式报表,取得了良好的效果,在此介绍这种方法。
众所周知,MicroSoft的Word是一个功能强大的字处理软件,它可以用自身带有的宏编辑器编写宏来实现绝大多数菜单功能,也可以用VBA编写程序完成很多任务。
编程实现VFP6.0操纵Word灵活打印特殊格式的报表,是用VFP6.0编写嵌有类似于VBA宏的程序,执行Word的命令打印报表、报告。
所以理论上,用这种方式可以实现任意格式报表的输出。
问题的关键在于:
一,正确地在VFP6.0中调用Word。
对于在VFP6.0中调用Word(也可理解为客户/服务器的请求和应答关系),使用语句
loWord=etcominstance ("word.application")
调用后,Word就可视为VFP的一个对象,为了使用其变量、方法、事件和过程,必须在程序开头时包含Word的一个头文件,语句为:
#INCLUDEwdolb.h(Offices97中的Word)或#INCLUDEmsolb09.h(Offices2000中的Word)。
二,正确地使用word能执行的编排版式的语言。
使用这种方式打印报表的主要目的是满足特殊的报表格式,而编排这些格式是依靠Word能运行的宏代码,这些宏代码在又要在VFP中被执行,而宏在Word中与在VFP中形式大体相近,但书写格式不尽相同。
例如要插入一个两行两列的表格,Word中宏格式为:
ActiveDocument.Tables.AddRange:
=Selection.Range,NumRows:
=2,NumColumns:
=2,
而在VFP中应该为:
.Activedocument.Tables.Add(.Selection.Range,2,2);再如输出一行文本“电脑编程”Word中宏格式为:
Selection.TypeTextText:
="电脑编程",而在VFP中应该为:
Selection.TypeText("电脑编程")等。
在后面的例程中可以看出这些差别。
当不知道该如何实现某个特殊格式时,最便捷的做法是在Word中刻录该格式的Word宏,拷贝到VFP中做适当修改即可。
三,正确处理VFP6.0宿主语句与Word宏语句的镶嵌关系。
这种报表打印方式的优越之处,不光在于单份特殊格式的报表输出,而且在于多份在VFP意义上的报表的同文档打印,甚至用一些信息挖掘手段从几十、上百个数据表中提取信息,打印出一个大体完整的既有表格又有自由文字的报告,这些是很诱人的。
所以,一般这样的报表打印程序除了满足格式上的要求外,通常还要实现一定的数据筛选,信息挖掘的功能,或者多表记录关联在同一报表输出,多报表的同文档输出等等,所以除了Word宏,程序中还有大量VFP自身的处理语句,有时两者是相互嵌套的,要注意两类语句排列顺序,有时顺序的错误回导致程序的错误。
例如,对Word对象的控制语句要放在“WITH…….ENDWITH”中,这样,在使用VFP的循环语句、分支语句时一定要注意不要嵌套错误。
编程中如果出现奇怪的错误,最好是检查一下语句的排列顺序。
下面举一个简单的例子,介绍如何在VFP6.0中调用Word、用其代码控制、以报表形式打印输出满足条件的记录。
这种打印结果脱离了VFP6.0,可以保存为独立电子文档,也可做进一步的编辑。
该示例是假定在学生信息管理系统中,要打印满足学号为特定值的学生信息。
首先,新建一个目录WriteReport作为当前VFP6.0默认路径,在其中建一个数据库表文件Student,形式为Student(name(C,8),gender(C,2),borntime(D,8),photo(G,4),studentno(C,12),stime(D,8),dpartment(C,20),major(C,18),drom(C,20),dtelenumber(C,15),address(C,20),htelenumber(C,15),hobby(M,4)),其中设置字段studentno为该表主关键字,并录入几条记录;然后建立一个名为WriteReport的过程(程序清单附后);最后建立一个如图1所示的
图1. 执行表单
表单调用WriteReport过程,其中“打印”按钮的代码为:
cStuNumb=ThisForm.List1.Value
IFEMPTY(cStuNumb)
MESSAGEBOX("请先用鼠标在列表框中单击一个学生的姓名!
",0+64+0,"提示信息")
ELSE
DoWriteReportWITHcStuNumb
ENDIF
执行该过程即可在word中打印出如图2所示的报表。
图2. 学生信息报表样式
WriteReport程序清单:
*PROCEDUREWriteReport WriteStudentDocumentfromdatabasetableByWord!
PARAMETcStudentNumber
#INCLUDEwdolb.h
#DEFINETrue.T.
#DEFINEFalse.F.
IF!
USED('student') &&Openthetable
USEstudentIN0ORDERstudentno
ENDIF
SELEstudent
IFPARA()=0 &&Whenthereisnoparameterbeenpasted,writethefirststudentinthetable
cStudentNumber=student.studentno
ENDIF
SEEKcStudentNumber
IFFOUND()
LOCALloWord,loTable,lnRow,lnColumn
loWord=Getcominstance("word.application") &&CallWordapplication
loWord.Visible=.t.
cString= "学生信息报表"
WITHloWord
.Documents.Add("Normal",False)
.Selection.MoveDown(wdLine,100)
WITH.Selection &&Informationonthetopofthe report
.Font.Name="宋体" &&FormatoftheString
.Font.Size=20
.ParagraphFormat.Alignment=wdAlignParagraphCenter
.TypeText(cString)
.TypeParagraph &&Addablankline
ENDWITH
.Selection.Sections
(1).Footers
(1).PageNumbers.Add(wdAlignPageNumberCenter,True)
.Selection.Font.Size=14
.Activedocument.Tables.Add(.Selection.Range,1,7)
loTable=.Activedocument.Tables
(1)
WITH loTable
.Cell(1,1).Width=80
.Cell(1,2).Width=45
.Cell(1,3).Width=80
.Cell(1,4).Width=45
.Cell(1,5).Width=30
.Cell(1,6).Width=45
.Cell(1,7).Width=90
.Cell(1,1).Range.Insertafter("照片")
.Cell(1,2).Range.Insertafter("姓名")
.Cell(1,4).Range.Insertafter("性别")
.Cell(1,6).Range.Insertafter("学号")
.Cell(1,3).Range.Insertafter(name)
.Cell(1,5).Range.Insertafter(gender)
.Cell(1,7).Range.Insertafter(studentno)
ENDWITH
.Selection.MoveDown(wdLine,100)
.Activedocument.Tables.Add(.Selection.Range,2,5)
loTable=.Activedocument.Tables
(1)
WITH loTable
FORj=2TO3
.Cell(j,1).Width=80
.Cell(j,2).Width=70
.Cell(j,3).Width=100
.Cell(j,4).Width=70
.Cell(j,5).Width=95
ENDFOR
.Cell(2,2).Range.Insertafter("出生年月")
.Cell(2,3).Range.Insertafter(borntime)
.Cell(2,4).Range.Insertafter("入学时间")
.Cell(2,5).Range.Insertafter(stime)
.Cell(3,2).Range.Insertafter("所在院系")
.Cell(3,3).Range.Insertafter(department)
.Cell(3,4).Range.Insertafter("所学专业")
.Cell(3,5).Range.Insertafter(major)
ENDWITH
.Selection.SelectColumn &&Selectthethreecolumns
.Selection.Cells.Merge &&unitecolumns
.Selection.MoveDown(wdLine,100)
.Activedocument.Tables.Add(.Selection.Range,2,4)
loTable=.Activedocument.Tables
(1)
WITH loTable
FORj=4TO5
.Cell(j,1).Width=80
.Cell(j,2).Width=170
.Cell(j,3).Width=70
.Cell(j,4).Width=95
ENDFOR
.Cell(4,1).Range.Insertafter("学校住址")
.Cell(4,2).Range.Insertafter(drom)
.Cell(4,3).Range.Insertafter("寝室电话")
.Cell(4,4).Range.Insertafter(dtelenumber)
.Cell(5,1).Range.Insertafter("家庭住址")
.Cell(5,2).Range.Insertafter(address)
.Cell(5,3).Range.Insertafter("联系电话")
.Cell(5,4).Range.Insertafter(htelenumber)
ENDWITH
.Selection.MoveDown(wdLine,100)
.Activedocument.Tables.Add(.Selection.Range,1,2)
loTable=.Activedocument.Tables
(1)
WITHlotable
.Cell(6,1).Width=80
.Cell(6,1).Height=60
.Cell(6,2).Width=335
.Cell(6,1).Range.Insertafter("个人特长")
.Cell(6,2).Range.Insertafter(hobby)
ENDWITH
.Selection.Sections
(1).Footers
(1).PageNumbers.Add(wdAlignPageNumberCenter,True) &&InsertPagenumber
ENDWITH
ENDIF
RETURN
该程序在VFP6.0中调试通过。
(注意:
要求同机装有Offices的Word软件,程序才能正常运行)。
补充说明:
本文主要探讨用VFP操纵Word打印报的方法,同时在程序实现上也有些技巧,希望在贵刊的数据库栏或者其它专栏中刊出,不胜感激!
所有源程序存到名为“WriteReport”的文件夹中随文邮到,包含完整的项目、库、表单及程序,可打开直接运行检测。
VFP技巧之:
利用WORD增强VFP的打印功能。
VFP9将报表设计器的功能增强了很多,但如果使用生成的报表进行最后的打印输出,总有一些不足,比如:
不能进行打印内容的修改,改变打印机设置后,有些使要打印的内容与设计时的要求发生改变。
……
对于这些不足,实际我们可以利用它与WORD之间的OLE功能,通过WORD实现VFP的打印输出,能够非常方便我们的工作。
下面是我整理出在VFP中控制WORD的一些语句,大家在VFP的命令窗口中试一下,就知道怎么用了。
Word=CREATEOBJECT('word.application') &&创