문제

I am trying to process data in an Excel worksheet passed from a C# class to an F# class library. The C# project is an Excel AddIn project the F# class is this.

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

So if I call the class from C# like this

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
}
도움이 되었습니까?

해결책

Interop between F# and C# isn't a problem. You have various errors in your F# class:

  1. You cast an Object sh to Worksheet sht, but mistakenly use sh instead of sht later.

  2. Range doesn't have Item property.

  3. You add virtually everything related to Excel programming into the project. You only need Microsoft.Office.Interop.Excel in this example. It's better to remove unnecessary open commands, especially Microsoft.Office.Tools.Excel which is opened after Interop.Excel could have objects of the same names but have incompatible fields/interfaces.

  4. You should pass a Worksheet instead of an obj to avoid downcasting.

A minimal F# example that works:

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()

Moreover, your C# syntax is a bit off, you need something like:

// 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);
}

다른 팁

I guess the issue is a bit more complicated. I added a reference to the Microsoft.Office.Tools.Excel framework to the F# Library project. That is a no no! It will give compiler errors. In F#, avoid referencing the Microsoft.Tools.Office.Excel namespace as well in your F# library if you are writing an F# library that is part of a VSTO C# project. Otherwise you will have problems! So only add the reference to the Microsoft.Office.Interop.Excel assembly to your project and open Microsoft.Office.Interop.Excel in the F# file.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top