F#types的提供者FSharpX.ExcelFile和奇怪的types错误试图在不同的input上构造

我在文档库中有一个用户可编辑的Excel文件,它为F#程序定义了一些input。 我想用F#-y来读取它,所以我想我会尝试一下FSharpX和他们的ExcelFiletypes的提供者。

什么工作

该提供者通过NuGet安装并启用,这个工程:

open FSharpX type Example = ExcelFile<"example.xlsx", "Worksheet1", true> let file = new Example() for row in File.Data do ...... 

什么不是

但是,当我尝试用不同的文件初始化构造函数(一个是在运行时从数据库中取出并存储在临时位置)时,我得到了一个非常奇怪的types错误。

 let file = new Example(@"c:\temp\path\to.xlsx") 

结果是

types提供程序'FSharpx.TypeProviders.ExcelProvider + ExcelProvider'在提供的types“FSharpx.ExcelFile,filename =”example.xlsx“,sheetname =”Worksheet1“,forcestring =”True“'member'的上下文中报告了错误。构造函数”。 错误:在将expression式拼接到引用文字中时键入不匹配。 正在插入的expression式树的types与拼接操作所期望的types不匹配。 预期'System.String',但收到types'System.Tuple`2 [System.String,System.String]'。 考虑使用预期的expression式types进行types注释,例如(%% x:string)或(%x:string)。 参数名称:receivedType

咦?

我不知道它所说的元组可能来自哪里,我也没有任何关于如何初始化的想法。

奖金问题 :如果我想在运行时更改工作表名称,该怎么办? 现有的FSharpx提供者似乎不允许这样做。

这是提供者中的错误,而不是你的代码。 提供的构造函数使用传入的文件名,但底层代码需要文件名和工作簿名称(这是元组应该来自的地方)。

似乎是一个错误。 提供的接受单个文件名参数的构造函数不会在引用中正确调用内部构造函数:

 ty.AddMember(ProvidedConstructor([ProvidedParameter("filename", typeof<string>)], InvokeCode = fun [filename] -> <@@ ExcelFileInternal(%%filename) @@>)) .... type ExcelFileInternal(filename, sheetorrangename) 

我前面分叉了FSharpx.Exceltypes提供者,修改它,以便使用ClosedXML(而不是办公互操作),如果文件是> = office 2007(我注意到你的工作簿是)。 我还对API进行了一些更改,将工作表(和/或范围)公开为提供的types,“行”提供的types和“行{n}”types。

 type exc = ExcelFile<"C:\\temp\\Template.xlsx",false> let file = new exc(@"C:\\temp\\Book.xlsx") for row in file.Sheet1.Rows do printfn "%s" row.BID let sht1Row1Col20 = file.Sheet1.Row1.BID 

恐怕没有“Sheets”提供的types,所以在运行时不能改变工作表名称。 有一个string[]'SheetAndRangeNames'types,但是这对你不会太有用。 但是,实施起来不是特别棘手。 你可以在这里find它:

https://github.com/bennylynch/ExcelTypeProvider/