DEFINE CLASS PowerVFP as Session olepublic datasession=2
PROCEDURE CreateCurosr(cXml as string,cCursorName as string) XMLTOCURSOR(cXml,cCursorName)
ENDPROC
PROCEDURE ExecFoxCode(cCode as string) EXECSCRIPT(cCode) ENDPROC
FUNCTION GetCursor(cCursorName as String) as String LOCAL cXml as String CURSORTOXML(cCursorName,"cXml",3,48,0,"") RETURN cXml ENDFUNC
PROCEDURE Error(nError as Integer,cMethod as String, nLine as Integer) LOCAL cText as String cText=; "出错时间:"+transform(datetime())+CL+; "错误代码:"+str(nError,4)+CL+; "错误提示:"+message()+CL+; "错误方法:"+cMethod+CL+; "错误行号:"+transform(nLine)+CL+CL strtofile(cText,"c:PowerFox.txt",.t.) comreturnerror("PowerFox COM Service",cText) ENDPROC
ENDDEFINE我的思路写这个组件是“有感而发”的,前一阵子用Delphi写ERP系统,虽然很努力的将大量的工作交给后台的 SQL Server,多数情况下,Delphi端得到的是很简单的数据集。然而,在一些涉及到复杂应用时,很多从经SQL Server处理的数据只是半成品,必须到客户端加工,这种加工往往是异常复杂的,分组、排序、关联、统计……在Delphi中实现这些功能是非常繁琐的,除了使用一些第三方控件能解决一些问题之外,无一例外的是大量的“循环+条件”,真的是很麻烦,工作量很大。基于上述思考,加上经SQL Server处理过的数据量已不大,我尝试着编写一个COM来解决这个问题。除了Error方法之外,整个组件只有三个方法: CreateCurosr(cXml as string,cCursorName as string) 是将外部传入的XML字串转换成Visual FoxPro 的Cursor;GetCursor(cCursorName as String) as String是将Visual FoxPro 的Cursor 转换成为XML字符串,向外传递;关键的是ExecFoxCode(cCode as string),它可一次执行多句符合Visual FoxPro 语法的语句,这样就可以在外部任意享用Visuial FoxPro提供的绝大多数功能!应用实例编译这个项目以后,我们做两个简单的实验,感受一下这超级的功能!例一:LOCAL ox as "PowerFox.PowerVFP" LOCAL cStr,cFoxCode as String *建立COM对象实例 ox=CREATEOBJECT("PowerFox.PowerVFP") *在客户端得到XML的结果集 USE northwind!Customers IN 0 SHARED CURSORTOXML("Customers","cStr",3,48,0,"") USE IN Customers *将XML语句传递到COM中,并建立Cursor ox.CreateCurosr(cStr,"C1") *产生符合 Visual FoxPro 语法的语句 cFoxCode="SELECT CustomerID,CompanyName FROM C1 WHERE Country like "%s%" INTO CURSOR T1" cFoxCode=cFoxCode+CHR(10)+"SELECT CustomerID,CompanyName,ContactName,ContactTitle FROM C1 INTO CURSOR T2" *传递语句到 COM 中执行 ox.ExecFoxCode(cFoxCode) *让 COM 组件将结果集以XML的形式传回客户端 XMLTOCURSOR(ox.GetCursor("T1"),"Result1") XMLTOCURSOR(ox.GetCursor("T2"),"Result2")例二:LOCAL ox as "PowerFox.PowerVFP" LOCAL cStr1,cStr2,cStr3,cFoxCode as String *建立COM对象实例 ox=CREATEOBJECT("PowerFox.PowerVFP") *在客户端得到XML的结果集 USE northwind!Employees IN 0 SHARED USE northwind!Orders IN 0 SHARED USE northwind!Order_Details IN 0 SHARED CURSORTOXML("Employees","cStr1",3,48,0,"") CURSORTOXML("Orders","cStr2",3,48,0,"") CURSORTOXML("Order_Details","cStr3",3,48,0,"") USE IN Employees USE IN Orders USE IN Order_Details *将XML语句传递到COM中,并建立Cursor ox.CreateCurosr(cStr1,"Employees") ox.CreateCurosr(cStr2,"Orders") ox.CreateCurosr(cStr3,"Order_Details") *产生符合 Visual FoxPro 语法的语句 cFoxCode="SELECT a.employeeid,ALLTRIM(LastName)+" "+ALLTRIM(FirstName) as Name,Title,sum(unitprice*Quantity)*(1-discount) as nJe " cFoxCode=cFoxCode+"from orders a INNER JOIN order_details b ON a.orderid=b.orderid INNER JOIN employees c ON a.employeeid=c.employeeid GROUP BY a.employeeid into cursor T1 noFilter" cFoxCode=cFoxCode+CHR(10)+"SELECT employeeid,Name,Title,MAX(nJe) as nJe FROM T1 INTO CURSOR T2" *传递语句到 COM 中执行 ox.ExecFoxCode(cFoxCode) *让 COM 组件将结果集以XML的形式传回客户端 XMLTOCURSOR(ox.GetCursor("T1"),"Result1") XMLTOCURSOR(ox.GetCursor("T2"),"Result2")后记好了,关于 “XML 在 COM 组件数据集传递中的意义” 已经大致讨论完毕了。不知您有何感受,我是怀着兴奋、骄傲的情绪做这个实验的、写这篇文章的。可能你对整个实验不以为然——神经病一样的将数据集导来导去,自找麻烦!但你设想一下:如果两个Test程序不用Visual FoxPro来实现,情况会怎样?那是一种多么美好的事情啊!将Visual FoxPro 作为一个 Server 运行,这是微软近年来努力的方向,在Visual FoxPro 7里,融入了大量的将关增强技术,这里介绍的就是一个很关键的东西。