我有一个简单的Excel电子表格,其中每个单元格要么不包含任何内容,要么包含一个值,或者包含表单的一个简单的2参数公式:
函数(单元格,单元格),(例如单元格A3可能有公式"=A1 + A2")
我希望能够使用F#打开一个Excel文件,对于任何一个单元格get:
1- null (因为单元格没有值也没有公式)
2-小数或字符串(对于一个值)
3-一个元组( string,string字符串),其中第一个值是函数(例如"+“,而元组的第2和第3部分是单元格名。"A1“和"A2")
所以: Get( "A1“)和Get("A2")都将返回一个double,但是Get("A3")将返回一个元组("+”、“A1”、"A2")。
我如何在F#中做到这一点?
发布于 2010-09-14 07:57:15
一旦您获得对工作表对象的引用(在启动excel并使用数据打开文件之后),您可以使用Range
成员获得指定的单元格。然后可以使用Value2
属性获得一个值(例如string/double),该值还返回一个公式的结果。要获得公式,可以使用Formula
成员。
我没有找到任何测试该值是否自动计算的好方法,但您可以检查Formula
值是否以=
字符开头。如果你真的只需要像你描述的那样简单的公式(没有括号等等)。然后,一个简单的正则表达式应该能做到这一点:
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
这将返回以下数据类型的值,该值涵盖所有情况:
type CellInfo =
| Empty
| Float of float
| String of string
| Formula of string * string * string
顺便说一句:要在F#互动中加载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)
发布于 2010-09-16 16:57:00
这确实给了我一个想法,我尝试使用FsLex/FsYacc来处理Excel单元格。这也许不是你想象中的那样,但它可能很有用,而且也不是很大。基本上,我编写的代码运行如下:
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))
输出结果看起来就像
"1002“(SUM,(RANGE,B2,B12))”"(+,A1,(AVERAGE,(RANGE,B2,B4) "(+,B3,G7)“(MIN,(RANGE,(RANGE,A3,A20) "(+,A1,(*,B4,C6))”
整件东西太大了,不能放进这个盒子里,但是请看一下这里。
https://stackoverflow.com/questions/3705513
复制相似问题