这个问题是有实际意义的,例如软件要导出一些统计数据,通常默认有固定的文件夹和文件名,如果恰好手工打开了这个文件,我们的软件以前是提示用户手工关闭它,但我们希望的是在提示后根据我们的选择自动关闭它或取消导出,要做到自动关闭,就需要获取已经打开的Excel对象。虽然在指定文件名时可以改名,但我们不希望有太多的人工干涉,一是操作人员的电脑知识欠缺(年龄等原因,他们工作经验丰富无法替代),二是统计报表太多,最好只保留最后一份正确的
我参与了软件公司就此问题的工作会议,后来经过开发人员的努力成功解决了,我大概说一下产生此问题的原因和解决思路吧
在xp+Office2003时代,基本不会遇到此类问题,因为那时的Excel大都是以单实例方式运行的。6楼同学可能就是单实例模式,因此用带文件名的GetObject不会提示程序已在运行中,你我都是多实例模式,所以会有提示,同样,我们的各部门使用的Excel版本不同,有高有低,运行模式是安装时默认的(也许通过修改注册表啥的可以都修改,但我们不想采纳)
另一个取不到已经打开的Excel对象问题,就涉及到用户权限,这在xp时代也基本不存在。细究起来就很复杂了,涉及到COM基础知识,可以百度下(知乎 COM编程攻略,浏览下第十六章),GetObject可能就是从ROT表中查找运行中Excel对象的,最关键的问题在于ROT是上下文敏感的,换句话说就是进程权限不同是不会共享的,这才是导致GetObject取不到的关键因素
因此,可以说vfp的GetObject函数,不带第一个参数的用法已部分废废了,之所以说部分废废,是因为如果权限一致时是不会有问题的。双击一个xls文件是用当前登录账号的权限打开文件的,而你的vfp却可能运行在管理员权限下(检查下vfp9.exe是否勾选了以管理员身份运行)。我们使用的软件因为会读写注册表的部分敏感区域(好像还有动态注册控件),需要设置成以管理员身份运行,因此才会遇到你提到的情况。弄清楚了为何取不到,也就知道需要避开ROT这个坑,另寻出路曲线救国了
具体的代码我没有,就算我能看到也无权贴出来,只能根据当时的记录把思路贴出来,希望你自己能实现它(这里高手如云,特别是像吹版这样的高手,有这思路写代码实现易如反掌)
先查找特定窗口句柄,所有的Excel都有一个名为Excel7的子窗口,窗口父子关系是 XLMAIN -> XLDESK -> EXCEL7,找到此窗口句柄后,再用AccessibleObjectFromWindow得到工作簿对象,有了Book对象,再访问Excel,Sheet这些对象就是再普通不过的事儿了
啰啰嗦嗦一大堆,希望对你有所帮助