Range 实际上是一个属性,它是一个有点特殊的属性,因为它用作索引器,这意味着它具有类似数组或字典的语义。在大多数语言中,这意味着您可以访问sht.Range["A1"]
. 那是语法糖,实际上它就像任何其他方法一样被访问,即:
sht.get_Range("A1",System.Reflection.Missing.Method)
我尝试使用 Boo、Ruby 和 IronRuby 来重复您的代码,同时使用语法糖样式和显式方法调用。在 IronRuby 中,我可以让它完美地工作,但只能在 32 位解释器中。在我配置的 32 位应用程序的常规 Ruby 中,它也运行良好。在 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。