我正在使用后期绑定(在C#中,使用Reflection等)通过COM访问Excel。换句话说,我首先使用
获取Excel.Application对象Type excelType = Type.GetTypeFromProgId("Excel.Application");
object excelApplication = Activator.CreateInstance(excelType);
(实际上,它比这更通用,但这给出了这个想法)。
正如很多人在StackOverflow中所提到的,查看如何使用COM接口到Office的一个好方法是在Excel中记录一个宏,然后查看VBA代码以查看要调用的类成员。
当我这样做时,我看到如果你有一个活动单元格的引用(从Excel.Application对象的ActiveCell属性获得),那么VBA引用ActiveCell.Offset(x,y)来引用一个单元格相对到那个ActiveCell(x和y是行和列索引)。但是,如果我尝试使用后期绑定访问Cell的Offset方法,则InvokeMember方法将失败,并显示“未找到成员”的异常。
如果我使用Visual Studio对象浏览器来检查Microsoft.Office.Interop.Excel命名空间和ApplicationClass类(我假设它可以很好地了解上面的C#代码通过ProgId获取它的COM接口) ,它表明ApplicationClass有一个ActiveCell属性,类型为Microsoft.Office.Interop.Excel.Range。并且检查该类显示它确实没有名为“Offset”的成员,因此当我尝试调用它时“找不到成员”。
这似乎意味着VBA宏正在使用与通过COM公开的Excel不同的对象模型!是的,或者我错过了什么?如果是这种情况,我如何通过COM中的后期绑定获得相同的VBA对象模型?
或者,是否有某种方法,使用Offset以外的方法,能够将ActiveCell移动到下一行的开头,这正是我想要的?
答案 0 :(得分:0)
你可以试试这个:
dim i as integer
i = ActiveCell.Row + 1
Excel.ActiveSheet.Cells(i,1).value = "Whatever your value is."
答案 1 :(得分:0)
如果您知道如何,答案就像往常一样容易。
我的代码在我的问题中的示例中稍微向下看起来有点像这样:
object activeCell;
object result;
// in here code to get the correct value into activeCell
if(activeCell.GetType().GetProperty("Offset") == null){
result = activeCell.GetType().InvokeMember("Offset", BindingFlags.InvokeMethod, null, activeCell, new object[] {1, 0});
}
InvokeMember抛出异常并显示“未找到成员”的消息。
当我将参数更改为InvokeMember时,如下所示:
result = activeCell.GetType().InvokeMember("Offset", BindingFlags.InvokeMethod | BindingFlags.GetProperty, null, activeCell, new object[] {1, 0});
然后它奏效了。
为什么它的工作原理仍然是一个谜,如果他们回答的话我肯定会赢得一些声誉。