我正在研究 Boo,并认为尝试转换几个可自动执行 Excel 的古老 VB 脚本(在本例中为 2007 年)将是一个有用的练习。很多事情似乎很容易翻译,但是我在选择范围时遇到了很大的麻烦 - 每当我尝试获取或设置它们时,我都会得到一个 TargetInitationException Member not found 。

这是我在 booish 中运行的一个(精简的)示例:

def CreateInstance(progid):
    type = System.Type.GetTypeFromProgID(progid)    
    return type()   

xl as duck = CreateInstance("Excel.Application")
xl.Visible = true
xl.Workbooks.Add

sht as duck = xl.ActiveSheet
#Next line throws exception
rng as duck = sht.Range("A1")

某些事情工作正常,例如设置工作表的“名称”属性等,但如何使用范围?VB 是否隐藏了一些我需要调用的特殊方法,如果是的话,我将如何找到这些方法?

干杯,

莱尼。

有帮助吗?

解决方案

Range 实际上是一个属性,它是一个有点特殊的属性,因为它作为索引器工作,这意味着它具有类似数组或字典的语义。在大多数语言中,这意味着您可以访问 sht.Range["A1"]. 。这是语法糖,实际上它的访问方式就像任何其他方法一样,即:

sht.get_Range("A1",System.Reflection.Missing.Method)

我尝试使用 Boo、Ruby 和 IronRuby 来重复您的代码,同时使用语法糖样式和显式方法调用。在 IronRuby 中,我可以让它完美地工作,但是 仅在 32 位解释器中. 。在常规 Ruby(我的配置上是一个 32 位应用程序)中,它也运行得很好。在 64 位解释器中,Range 属性从未被正确解析。

因此,这让我怀疑 Boo Interactive Shell 正在 64 位模式下运行,并且互操作因此而失败。不幸的是,在使用 CORFLAGS.exe 将本地 Boo 二进制文件设置为以 32 位模式运行后,同样的问题再次出现,因此我认为这不是真正的问题。

不过,有效的方法是显式导入 Excel Dotnet 互操作库以及互操作服务命名空间,如下所示:

import Microsoft.Office.Interop.Excel
import System.Runtime.InteropServices

xl_type=typeof(Application).GetCustomAttributes(typeof(CoClassAttribute),true)[0].CoClass
xl=xl_type()
xl.Visible=true
xl.Workbooks.Add

然后:

xl.Range["A1","A2"].Value=12
xl.Range["A1",System.Type.Missing].Value="Alpha"
(xl.ActiveSheet as Worksheet).Range["A1","A2"].Value2='Whatever'

所有这些都有效,但它们本质上要求您放弃您习惯于后期绑定的“脚本性”(这就是您的鸭子打字所做的)。

与大多数语言(C# 4.0 除外)的 VB/VBScript 的一个区别是,通常可选参数不是透明处理的,因此在处理支持可选参数的方法时,需要更仔细地查看 API参数(用 System.Type.Missing 或 System.Reflection 等效项替换它们)。您可以通过 Excel 互操作文档找到这一点,尽管您可能可以使用反射来识别标记为可选的参数(如果您发现这比查找更容易)。

因为 Ruby 对于后期绑定这些对象有一个合理的解决方案,所以我怀疑 Boo 中的 COM 互操作场景中缺少功能(或错误)。

编辑添加: Sam Ng 撰写了有关 C# 4.0 中索引属性支持的文章;他的帖子中描述的问题可能也适用于 Boo。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top