[英]Excel prefix formula F#
I have a simple Excel spreadsheet where each cell either contains nothing, a value, or a simple 2 argument formula of the form: 我有一个简单的Excel电子表格,其中每个单元格都不包含任何内容,一个值或以下形式的简单2参数公式:
Function(Cell,Cell), (eg cell A3 might have the formula "=A1 + A2")
Function(Cell,Cell),(例如,单元格A3可能具有公式“ = A1 + A2”)
I would like to be able to open an Excel file using F# and for any cell get: 我希望能够使用F#打开Excel文件,并获取任何单元格的内容:
1 - null (because the cell has no value and no formula) 1-空(因为该单元格没有值,也没有公式)
2 - decimal or string (for a value) 2-十进制或字符串(用于值)
3 - a tuple of (string,string string) where the first value is the function (eg "+" and the 2nd and 3rd part of the tuple is the cell name (eg "A1" and "A2") 3-(字符串,字符串字符串)的元组,其中第一个值是函数(例如“ +”,元组的第二和第三部分是单元格名称(例如“ A1”和“ A2”))
So: Get("A1") and Get("A2") would both return a double, but Get("A3") would return a tuple ("+","A1","A2") 因此:Get(“ A1”)和Get(“ A2”)都将返回一个double,但是Get(“ A3”)将返回一个元组(“ +”,“ A1”,“ A2”)
How would I do this in F# ? 我将如何在F#中执行此操作?
Once you get a reference to a worksheet object (after starting excel and opening the file with your data), you can use the Range
member to get a specified cell. 一旦获得对工作表对象的引用(启动excel并使用数据打开文件之后),就可以使用
Range
成员来获取指定的单元格。 Then you can use Value2
property to get a value (eg string/double), which also returns the result of a formula. 然后,您可以使用
Value2
属性获取一个值(例如,字符串/双精度),该值还返回公式的结果。 To get the formula, you can use Formula
member. 要获取公式,可以使用
Formula
成员。
I didn't find any good way for testing whether the value is automatically calculated or not, but you can check if the Formula
value starts with the =
character. 我没有找到测试该值是否自动计算的好方法,但是您可以检查
Formula
值是否以=
字符开头。 If you really only need as simple formulas as the one you describe (without parentheses etc.) then a simple regular expression should do the trick: 如果您确实只需要描述的简单公式(不带括号等),那么一个简单的正则表达式就可以解决问题:
let reg = new Regex("=([A-Z]+[0-9]+)([^A-Z0-9]+)([A-Z]+[0-9]+)")
let getInfo (cell:Range) =
let formula = cell.Formula.ToString().Replace(" ", "")
match formula.StartsWith("="), cell.Value2 with
| true, _ ->
let g = reg.Match(formula).Groups
Formula(g.Item(1),g.Item(2),g.Item(3))
| :? float as n -> Float(n)
| :? string as s -> String(s)
| _ -> Empty
This returns a value of the following data type which covers all your cases: 这将返回一个涵盖您所有情况的以下数据类型的值:
type CellInfo =
| Empty
| Float of float
| String of string
| Formula of string * string * string
BTW: To load an excel in F# Interactive, you need something like this: 顺便说一句:要在F#Interactive中加载excel,您需要以下内容:
#r "Microsoft.Office.Interop.Excel.dll"
// Run Excel as a visible application
let app = new ApplicationClass(Visible = true)
// Create new file using the default template
let workbook = app.Workbooks.Add(XlWBATemplate.xlWBATWorksheet)
// Get the first worksheet
let worksheet = (workbook.Worksheets.[1] :?> _Worksheet)
This really gave me an idea and I tried using FsLex/FsYacc to process your Excel cells. 这确实给了我一个主意,我尝试使用FsLex / FsYacc处理您的Excel单元格。 It's maybe not exactly what you imagined, but it may be useful and it's also not very big.
它可能与您想像的不完全一样,但可能很有用,而且范围也不大。 Basically, the code I wrote runs like this:
基本上,我编写的代码是这样运行的:
let teststrings = [ "1002";
"=SUM(B2:B12)";
"=A1+AVERAGE(B2:B4)";
"=B3+G7";
"=MIN(MEAN(A3:A20))";
"=A1+B4*C6"
];
teststrings |> List.iter (fun s -> (convert s |> printfn "%A" s))
and the output looks like 和输出看起来像
"1002" "(SUM,(RANGE,B2,B12))" "(+,A1,(AVERAGE,(RANGE,B2,B4)))" "(+,B3,G7)" "(MIN,(MEAN,(RANGE,A3,A20)))" "(+,A1,(*,B4,C6))" “ 1002”“(SUM,(RANGE,B2,B12))”“((+,A1,(AVERAGE,(RANGE,B2,B4)))”“”((+,B3,G7)“”((最小,(RANGE,A3,A20)))“”((+,A1,(*,B4,C6))“”
The whole thing is too big to put in this box, but have a look here . 整个东西太大了,无法放入此盒子,但在这里看看。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.