我正在尝试处理从C#类传递到F#类库的Excel工作表中的数据。 C#项目是一个Excel AddIn项目,F#类就是这个。
namespace DataLib
open System
open System.Reflection
open System.Collections.Generic
open FSharpx.TypeProviders.Excel
open Microsoft.FSharp.Core.CompilerServices
open System.IO
open System.Linq
open System.Text
open System.Windows.Forms
open Microsoft.Office.Core
open Microsoft.Office.Interop.Excel
open Microsoft.Office.Tools.Excel
type sheet = Microsoft.Office.Interop.Excel.Worksheet
type Class1() =
member this.X = "F#"
member this.Readsheet (sh:obj)=
let sht = sh:?>Worksheet// exception here
let v=sh.Cells.[1,1] // Exception COM object does not have Cells property etc...
sh.Range.Item(1,1).ToString() //error here ca
所以,如果我像这样从C#调用类
using DataLib;
public void useExcel(sh as Excel.Worksheet) //Excel.Worksheet is Excel Interop object
{
Class1 one = new Class1()
one.Readsheet(sh) //Exception thrown here in F# class
}
答案 0 :(得分:2)
F#和C#之间的互操作不是问题。您的F#类中有各种错误:
您将对象sh
投射到工作表sht
,但稍后错误地使用sh
而不是sht
。
Range
没有Item
属性。
您几乎可以将与Excel编程相关的所有内容添加到项目中。在此示例中,您只需要Microsoft.Office.Interop.Excel
。最好删除不必要的open
命令,尤其是在Microsoft.Office.Tools.Excel
可能具有相同名称但具有不兼容的字段/接口的对象之后打开的Interop.Excel
。
您应该传递Worksheet
而不是obj
以避免向下转发。
最小的F#示例:
namespace DataLib
open Microsoft.Office.Interop.Excel
type Class1() =
member this.X = "F#"
member this.Readsheet (sh: Worksheet) =
let v = sh.Cells.[1, 1]
sh.Range(1, 1).ToString()
此外,你的C#语法有点偏,你需要这样的东西:
// Add "using Microsoft.Office.Interop.Excel;"
// and "using DataLib;" to namespace declarations
public void useExcel(Worksheet sh) // Worksheet is Excel Interop object
{
Class1 one = new Class1();
one.Readsheet(sh);
}
答案 1 :(得分:0)
我想这个问题有点复杂。我在F#Library项目中添加了对Microsoft.Office.Tools.Excel框架的引用。那不是不!它会给编译器错误。在F#中,如果您正在编写属于VSTO C#项目的F#库,请避免在F#库中引用Microsoft.Tools.Office.Excel命名空间。否则你会遇到问题!因此,只需将Microsoft.Office.Interop.Excel程序集的引用添加到项目中,然后在F#文件中打开Microsoft.Office.Interop.Excel。