我正在使用ExcelDNA为Excel编写F#addin UDF,理想情况下,我希望根据其他CSV的内容动态加载CSV。
我一直在下面的F#数据库中使用类型提供程序和csv解析器: http://fsharp.github.io/FSharp.Data/library/CsvProvider.html
类型提供程序不允许我在编译之前将变量作为字符串传递,因为它不是静态的(也许我做错了 - 请看下面的代码不起作用)。
let getcontractperiod = new CsvProvider<"P:/Datastructures/contract_variables.csv", ",">()
let contractperiodfilelocation = getcontractperiod.Filter(fun row -> row.ContractModelID="MyContractTest").Data
let closescc = [| yield! contractperiodfilelocation |> Seq.map (fun x -> x.FileLocation) |]
let onstructure = new CsvProvider<closescc.[0], ",">()
提供的类型的静态参数无效。期待一种类型'字符串'的论点。
但是,如果我使用同一个库中的CSV Parser它可以工作(但是我失去了提供者的强类型方面)。
let getcontractperiod = new CsvProvider<"P:/Datastructures/contract_variables.csv", ",">()
let contractperiodfilelocation = getcontractperiod.Filter(fun row -> row.ContractModelID="MyContractTest").Data
let closescc = [| yield! contractperiodfilelocation |> Seq.map (fun x -> x.FileLocation) |]
let onstructure = CsvFile.Load(closescc.[0]).Cache()
我想知道的是:
由于这将在Excel中多次调用,如果使用CsvParse方法与CSV类型提供程序会有显着的性能损失,特别是如果我需要在csvparse方法中转换/转换任何内容。
注意我需要为每次计算加载大约4个csvs,csvs大约600-2000行。我现在无法选择访问数据库。
谢谢。
答案 0 :(得分:3)
传递给CsvProvider的静态字符串参数是用于推断架构的模板,但您可以在运行时使用不同的值。所以不要这样:
let sample = new CsvProvider<"Sample.csv">()
这样做:
let csv = CsvProvider<"Sample.csv">.Load("runtimeLocation.csv")
或者这个:
type CsvType = CsvProvider<"Sample.csv">
let csv = CsvType.Load("runtimeLocation.csv")
至于性能,CsvProvider在内部使用相同的csv解析器,因此CsvFile应该具有相似的性能特征,区别仅在于强类型