上次记录下《创建EXCEL新方法》之后,有些疑惑始终萦绕心头。
先看看两句话,都来自VFP的帮助文件。
关于CreateObject():
For example, to create a Microsoft Excel worksheet (which supports Automation), you can use the following syntax:
x = CREATEOBJECT('Excel.Sheet') |
When this code is run, Microsoft Excel is started (if not already running), and a new worksheet is created.
如果Excel没有运行,启动Excel。如果已经启动了呢?没说。
关于GetObject():
With some server applications, each time you issue GETOBJECT, an additional instance of the application is started, using additional memory. If the application is already running, you can prevent additional instances of the application from starting by omitting FileName and including ClassName, as in this example:
oleApp = GETOBJECT(, "Excel.Application") |
对某些应用程序(后台软件),GetObject()都启动额外的一个实例。如果应用程序已经在运行,忽略文件名,就可以避免启动额外实例。
上次就是在这里出了困惑。我按上面的例句发出指令后,就收到OLE错误码,提示操作无效。
但如果
oleApp = GETOBJECT( "", "Excel.Application")
操作是可以顺利完成的。所以当时简单地以为可能是微软笔误,漏了引号。
但后来越想越觉得好像有问题,因为这时又有一个新的Excel实例产生,这时候就不是简单的笔误问题了,而是整句话都有问题。所以一直想再测试一下。
(其实是当时没在意 If the application is already running 这句话。)
今天有空,开始了测试,步骤如下,所有过程同时监控任务管理器。
-
ole1 = createobject( 'excel.application' )
ole2 = createobject( 'excel.application' )任务管理器里出现两个Excel进程。
-
RELEASE ole1,ole2
进程消失。
-
ole1 = getobject( ,'excel.application' )
OLE错误,操作无效。
-
ole1 = getobject( '' ,'excel.application' )
ole2 = getobject( '' ,'excel.application' )操作顺利,无错误提示,两个Excel进程。
-
RELEASE ole1,ole2
ole1 = getobject( '' ,'excel.application' )
ole2 = getobject( ,'excel.application' )操作顺利完成,无错误提示,一个Excel进程。这时候恍然大悟,原来省略文件名,前提是Excel进程已经启动。
-
还有一些其它疑问,于是继续测试。
RELEASE ole1,ole2
ole1 = CREATEOBJECT( 'excel.worksheet')找不到Excel.WorkSheet类定义?!
-
ole2 = CREATEOBJECT( 'excel.sheet')
执行成功,一个Excel进程启动。
这就奇怪了!打开Excel的VBA对象浏览器,有类WorkSheet,反而是没有Sheet!(其实excel.sheet是工作簿WorkBook,而不是表Sheet或WorkSheet。) - 显形ole2看看
ole2.Application.Visible = .t.
一个名为Object的工作簿,有张空表Sheet1。注意这时候只有ole2一个对象,ole1还没有被打开。
-
ole2.Application.Workbooks.Open( 'E:\My Documents\Visual FoxPro 项目\测试\csdn.xls')
打开了另一本工作簿。一个进程两张表。
-
换个顺序试试
ole2.Application.quit()
RELEASE ole2
ole2 = CREATEOBJECT( 'excel.sheet')
ole2.Application.Workbooks.Open( 'E:\My Documents\Visual FoxPro 项目\测试\csdn.xls')
ole2.Application.Visible = .t.结果一样,两本工作簿。以往这里疏忽了,只注意到后一个打开的工作簿,没注意到前面已经有一个了。
- RELEASE ole2
ole1 = Getobject('', 'excel.sheet')
ole1.Application.Visible = .t.
ole1.Application.Workbooks.Open( 'E:\My Documents\Visual FoxPro 项目\测试\csdn.xls')效果一样,一个进程,两个工作簿。
-
ole1.Application.quit()
RELEASE ole1
ole1 = Getobject( 'E:\My Documents\Visual FoxPro 项目\测试\csdn.xls', 'excel.sheet')
ole1.Application.Visible = .t.奇怪,csdn.xls并没有被打开,还是只有Object一个工作簿。
-
继续
ole1.Application.Workbooks.Open( 'E:\My Documents\Visual FoxPro 项目\测试\csdn.xls')
csdn.xls这才被打开。
看来GetObject('','excel.sheet')有没有文件名一样。 -
RELEASE ALL
-
ole1 = getobject('', 'excel.sheet')
ole2 = getobject(,'excel.sheet')OLE错误、操作无效!?
-
ole3 = getobject('', 'excel.sheet')
操作成功。观察任务管理器,没有新的Excel进程启动。
-
ole2 = getobject(,'excel.application')
操作成功。原来GetObject省略文件名只适用于Application,不适用于Sheet。
-
ole4 = getobject('','excel.application')
启动第二个Excel进程。
-
RELEASE ALL
ole1 = createobject( 'excel.sheet')
ole2 = createobject( 'excel.sheet')一个Excel进程。
好了,其它的测试不一一列出,总结一下:
-
1、CreateObject( 'excel.类')
2、CreateObject( 'excel.类', '文件名.xls' )对Application类,无论有无进程已启动,均启动新进程; 无论是否提供文件名,均无文件打开。 对Sheet类, 无进程时启动新进程; 无论是否提供文件名,均另外打开新文件。 3、GetObject( '文件名.xls', 'excel.类' )
4、GetObject( '','excel.类')对Application类,无论有无进程已启动,均启动新进程; 无论是否提供文件名,均无文件打开。 对Sheet类,无进程时启动新进程; 无论是否提供文件名,均另外打开新文件。 5、GetObject( ,'exel.类' ) 对Application类, 无进程已启动时,OLE错误;
有进程已启动,不启动新进程,不产生新表。实际上只是取得当前进程的一个引用。对Sheet类,均提示OLE错误。 可见1、2、3、4其实是一样的。 5只适用于exce.Application,不适用于excel.Sheet
-
Excel.Sheet是WorkBook对象,而不是Sheet或WorkSheet对象。
-
在Application.Visible = .t. 的情况下,Release不能退出Excel。但如果Application.Visible = .f.,可以用Release直接退出Excel,终止进程。
(以上测试基于VFP9 + Excel2003,欢迎指正。)