VFP与EXCEL的几种交互编程方法

VFP与EXCEL的几种交互编程方法

一、EXECL驱动VFP
EXECL内置的VBA语言(Visual Basic For Application)为EXECL功能的扩展提供了便利的手段,用户可使用该语言直接驱动VFP完成数据检索等功能。
程序首先生成一个VFP对象,然后用VFP的DoCmd方法执行VFP摸索命令串,其摸索结果再借助于VFP的DateToClip方法拷贝至剪切板,最后VBA将其粘贴至工作表的正确位置。
Sub FoxTest()

Dim oFox As Object
Dim SLesson As String
Dim SCommand As String

Set oFox = CreateObject("VisualFoxPro.Application") '启动VFP,生成VFP对象
Sheets("查询").Select
SLesson = Range("课程名") '在名为“课程名”的单元格中得到欲查询的课程名称
Sheets.Add '产生新的工作表单
ActiveSheet.Name = Slesson '指定工作表单的名称与课程名称相同

SCommand = "SELECT 学号,语文,数学 FROM d:/vfp/学生成绩表 WHERE "+ SLesson + "<60 INTO CURSOR TEMP" '形成VFP查询命令串
oFox.DoCmd Scommand '执行VFP命令串
oFox.DataToClip "temp", , 3 '将搜索结果以文本方式拷贝至剪切板
Range("a1:a1").Select '指向拷贝目标区域左上角单元
ActiveSheet.Paste '粘贴搜索结果

End Sub

为便于使用,作者在EXECL中自制了一名为“搜索”的工具栏及一名为“开始搜索”的按钮,并将上述宏程序段与自制按钮相关联,按下此按钮即可运行程序并在EXCEL中得到要求的数据。
制作工具栏及按钮的方法如下:
1. 选“工具”/“自定义”菜单,出现自定义对话框;
2. 选择“工具栏”页框,然后按下“新建”按钮;
3. 在工具栏对话框中输入“搜索”作为新建工具栏的名称;
4. 选择“命令”页框,在“类别”列表中选“宏”,在“命令”列表中选“自定义按钮”并将其拖放至新建的“搜索”工具栏;
5. 按下“更新所选内容”按钮,首先在“命名”栏中填入按钮名称“开始搜索”,然后选择“指定宏”,在随后出现的“指定宏”列表中选择上述宏程序FoxTest()即可实现为该宏指定一个工具栏按钮。

二、VFP使用OLE功能驱动EXECL
OLE(Object Linking and Embedding)对象链接与嵌入,是WINDOWS应用程序间相互传递和共享数据的一种有效方法。VFP借助于OLE不仅可共享其它应用程序的数据,而且还能以对象方式直接控制其它应用程序的运行,从而进一步扩展VFP的功能。VFP支持直接在程序中创建、使用和控制OLE对象,实现OLE自动化。作为OLE客户VFP与作为OLE服务器的EXCEL具有良好的编程接口,下述程序段用OLE方式实现所要求的功能。
程序首先生成一个EXCEL的OLE对象OleApp以便对其进行操作,然后利用OLE功能从EXCEL表单中获取欲查询的课程名,并控制EXCEL生成新的工作表,VFP的查询结果仍然使用剪切板的方式传递至EXCEL工作表。

OleApp=CREATEOBJECT("Excel.Application") && 打开EXCEL,产生OLE对象
OleApp.Application.Caption="VFP交互编程" && 指定标题栏名称
OleApp.Application.Visible=.T. && 置EXCEL可见
OleApp.Application.WorkBooks.Open("d:/vfp/VFP交互.xls") && 打开EXCEL工作簿

DO WHILE .T.
WITH OleApp.Application
nAnswer = MESSAGEBOX("开始搜索?", 32+4, "搜索指定数据") &&产生信息框
IF (.NOT.(nAnswer=6)) && 如按下“Yes"按钮,则开始搜索,反之退出
EXIT
ENDIF

.Sheets("查询").Select && 选择“查询”工作表单
SLesson = OleApp.Application.Range("课程名").value && 得到欲查询的课程名称
.Sheets.Add && 新建一工作表单
.ActiveSheet.Name = Slesson && 指定工作表单的名称
SCommand = "SELECT 学号,语文,数学 FROM d:/vfp/学生成绩表 WHERE " +ALLTrim(SLesson) + "<60 INTO CURSOR TEMP" && 形成VFP查询命令串
&Scommand && 执行VFP命令串
_VFP.DataToClip("TEMP",,3) && 将搜索结果以文本方式拷贝至剪切板
.Range("a1:a1").Select && 指向拷贝目标区域左上角单元
.ActiveSheet.Paste && 粘贴搜索结果
ENDWITH
ENDDO

OleApp.Quit && 关闭EXCEL,保存更新后的工作簿文件
三、VFP使用DDE功能驱动EXECL
DDE(Dynamic Data Exchange)动态数据交换,是WINDOWS应用程序间相互传递和共享数据的另一种有效方法,DDE用共享存储器在应用程序间交换数据。DDE会话发生在DDE客户与DDE服务器应用程序之间,客户应用程序向服务器应用程序请求数据和服务,而服务器响应客户应用程序对数据与服务的请求。DDE的数据交换可分三种方式:
* 冷链接:客户应用程序请求数据时,服务器应用程序才发送数据给客户应用程序;
* 暖链接:服务器应用程序在每次数据项的值变化时都向客户应用程序发送通告,但它并不直接发送值给客户应用程序,而由客户应用程序决定是否取得该数据;
* 热链接:服务器应用程序在每次值变化时都发送数据项的新值给客户应用程序。
VFP与EXCEL均支持DDE客户与服务器。下述程序段由作为DDE客户的VFP应用程序与作为DDE服务器的EXCEL用DDE方式实现所要求的功能。
程序首先启动EXCEL,然后在VFP应用程序与“查询”工作表单的“课程名”单元格之间形成“热链接”,当“课程名”单元格内容改变时,将自动执行
“GetData”过程。在该过程中首先直接获取DDE数据,如果该数据为“空”,则关闭EXCEL,程序结束;反之,利用DDEPOKE功能向EXCEL发送键盘命令串,以形成新的工作表,最后VFP将查询结果通过剪切板送EXCEL形成要求的工作表。

PUBLIC ExcelChan
PUBLIC SheetChan

RUN /N3 C:/Program Files/Microsoft Office/Office/EXCEL.EXE && 以“活动”与“最大化方式启动EXCEL
ExcelChan = DDEInitiate("Excel",'SYSTEM') && 初始化DDE通道ExcelChan
= DDEExecute(ExcelChan,'[Open("d:/vfp/VFP交互.xls")]') && 打开“VFP交互.xls”

SheetChan = DDEInitiate('Excel', '查询') && 初始化DDE通道SheetChan
= DDEAdvise(SheetChan, '课程名', 'GetData', 2) && 在VFP应用程序与“查询”工作表单的“课程名”单元格之间形成“热链接”!如果该单元数值改变,则执行“GetData”过程。

PROCEDURE GetData
PARAMETERS Channel, Action, Item, Data, Format, Advise
IF Action = 'ADVISE' .AND. Item = '课程名' && 服务器提供的链接名为“课程名”
SLesson = Data && 直接获取DDE服务器提供的数据
SLesson = LEFT(SLesson,LEN(SLesson)-2) && 去掉原始数据尾部的格式字符
IF (LEN(SLesson)=0) && 如果指定单元格内容为“空”,则退出
= DDETerminate(SheetChan) && 终止DDE通道SheetChan
= DDEExecute(ExcelChan,'[Quit]') && 退出EXCEL
= DDETerminate(ExcelChan) && 终止DDE通道ExcelChan
ELSE
= DDEExecute(ExcelChan,'[Formula.Goto("课程名")]') && 指定名为“课程名”
的单元格为活动单元格
= DDEExecute(ExcelChan,'[Copy]') && 将指定单元格内容拷贝至剪切板
SKey="'%IW%OHR^V{enter}'" && 键盘命令字符串,表示“插入(I)|工作表(W);格式(O)|工作表(H)|重命名(R);粘贴”
= DDEExecute(ExcelChan,&SKey) && 通过DDE通道将命令串送EXCEL
WAIT WINDOW TIMEOUT 2 && 等待2秒钟以实现上述命令串
SCommand = "SELECT 学号,语文,数学 FROM d:/vfp/学生成绩表 WHERE " +ALLTRIM(SLesson) + "<60 INTO CURSOR TEMP" && 形成VFP查询命令串
&Scommand && 执行VFP命令串
_VFP.DataToClip("TEMP",,3) && 将搜索结果以文本方式拷贝至剪切板

SheetChan1 = DDEInitiate("Excel",'&SLesson') && 初始化DDE通道SheetChan1
指向新生成的工作表
= DDEExecute(SheetChan1,'[Paste]') && 粘贴搜索结果
= DDETerminate(SheetChan1) && 终止DDE通道SheetChan1
ENDIF
使用VFP读取EXCEL中的数据示例 *!* *****数据导入程序,由“学生基本基本情况表模板.xls”导入数据 *!* ***使用VFP控制EXCEL表,计取中指定列的内容*********** *!* "学生基本基本情况表模板.xls"的数据布局 *!* cells(1,1):“标题” *!* cells(2,1):校区 *!* cells(2,3):学历 *!* cells(2,5):专业 *!* cells(2,6):班级 *!* *!* set safe off set talk on LOCAL inf(4) as String *dele file C:\MyDocu~1\Resume.xlw objExcel = CreateObject("Excel.Application") &&创建一个EXCEL应用程序实例 wjm=getfile("xls") objExcel.Workbooks.Open(wjm) &&调用workbooks(Microsoft Excel 应用程序; 中当前打开的所有 Workbook 对象的集合。); 对象的open方法程序来打开指定的文件,并为; 打开的文件创建一个新的工作簿 *objexcel.visible=.f. ***下面的代码判断出生日期字段的格式是否满足要求*** *IF !varTYPE(objexcel.cells(10,6))="d" * MESSAGEBOX("出生日期字段不满足格式要求,不能导入,请将出生日期字段修改为:"+CHR(13); +"mm.dd.yy的格式,如:05.19.83 表示1983年5月19 然后再运行此导入程序") * RETURN *ENDIF inf(1)=substr(objexcel.cells(2,1).value,7)&&校区 Inf(2)=objexcel.cells(2,4).value&&学历 inf(3)=objexcel.cells(2,6).value&&专业 inf(4)=objexcel.cells(2,7).value&&班 LOCAL nrow as Number ,i as Number i=0 *MESSAGEBOX("计算行数") *MESSAGEBOX(objexcel.cells(5,1).value) *MESSAGEBOX(VARTYPE(objexcel.cells(22,1).value)) DO WHILE .t. i=i+1 ?objexcel.cells(i,1).value IF !VARTYPE(objexcel.cells(i,1).value)="C" nrow=i-1 EXIT ENDIF ENDDO *nrow=20 LOCAL arecord(16) *MESSAGEBOX("循环添加记录") USE zlb disinf("zlb.dbf中现有记录"+ALLTRIM(STR(RECCOUNT()))+"条") disinf("正在添加记录") FOR i=4 TO nrow arecord(1)=objexcel.cells(i,1).value&&学号  arecord(2)=objexcel.cells(i,2).value&&姓名 arecord(3)=objexcel.cells(i,3).value&&性别 arecord(4)=objexcel.cells(i,4).value&&籍贯 arecord(5)=objexcel.cells(i,5).value&&民族 *MESSAGEBOX(VARTYPE(objexcel.cells(i,6).value)) IF VARTYPE(objexcel.cells(i,6).value)="C" arecord(6)=RIGHT(objexcel.cells(i,6).value,2)+"/"+"01"+'/'; +LEFT(objexcel.cells(i,6).value,2) ELSE arecord(6)= RIGHT(STR(objexcel.cells(i,6).value,5,2),2); +"/"+"01"+"/"; +LEFT(STR(objexcel.cells(i,6).value,5,2),2) ENDIF &&arecord(6)=IIF(VARTYPE(objexcel.cells(i,6).value)="c",RIGHT(objexcel.cells(i,6).value,2)+"/"+"01"+'/'+LEFT(objexcel.cells(i,6).value,2),; RIGHT(STR(objexcel.cells(i,6).value,5,2),2)+"/"+"01"+'/'+LEFT(STR(objexcel.cells(i,6).value,5,2),2))&&出生年月 arecord(7)=LEFT(ALLTRIM(STR(objexcel.cells(i,8).value,6,0)),6)&&邮政编码 arecord(8)=objexcel.cells(i,7).value&&通讯地址 arecord(9)=objexcel.cells(i,9).value &&收信人 arecord(10)=iif(!ALLTRIM(objexcel.cells(i,10).value)=="",objexcel.cells(i,10).value; ,"无")&&家庭电话 arecord(11)=inf(3)&&专业 arecord(12)=inf(4)&&班级 arecord(13)=objexcel.cells(i,11).value&&寝室号码 arecord(14)=STR(objexcel.cells(i,12).value,7,0)&&寝室电话 arecord(15)=inf(1)&&校区 arecord(16)=inf(2)&&学历 SELECT zlb APPEND FROM ARRAY arecord ENDFOR disinf("zlb.dbf中现有记录"+ALLTRIM(STR(RECCOUNT()))+"条") disinf("记录添加完毕,共添加了"+ALLTRIM(STR(nrow-3))+"条记录,请查检") INKEY(3) WAIT CLEAR ****定义日期转换函数,此函数能将各种格式的日期转换成mm/dd/yy的格式**** ****如果要转换的日期只有年和月,则自动添加日为'01'*** *!* FUNCTION datetran *!* PARAMETERS soudate *!* IF VARTYPE(soudate)="N" *!* DO case *!* CASE LEN(souDATE) ***关闭工作簿,退出EXCEL objexcel.quit RELEASE objexcel *!* objexcel.save *!* *objExcel.ActiveWorkbook.saved=.f. *!* objexcel.Quit &&退出 *!* RELEASE objexcel *!* retu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值