Префикс Excel с формулой F # - PullRequest
2 голосов
/ 14 сентября 2010

У меня есть простая электронная таблица Excel, в которой в каждой ячейке либо ничего не содержится, либо значение, либо простая формула с двумя аргументами в виде:

Функция (ячейка, ячейка) (например, ячейка A3 может иметь формулу "= A1 + A2")

Я хотел бы иметь возможность открыть файл Excel, используя F #, и для любой ячейки получить:

1 - ноль (поскольку ячейка не имеет значения и формулы)

2 - десятичное или строковое (для значения)

3 - кортеж (строка, строка), где первое значение - это функция (например, «+», а вторая и третья части кортежа - это имя ячейки (например, «А1» и «А2»)

Итак: Get ("A1") и Get ("A2") оба возвращают double, но Get ("A3") возвращает кортеж ("+", "A1", "A2")

Как бы я это сделал в F #?

Ответы [ 2 ]

4 голосов
/ 14 сентября 2010

Как только вы получите ссылку на объект рабочего листа (после запуска Excel и открытия файла с вашими данными), вы можете использовать элемент Range, чтобы получить указанную ячейку. Затем вы можете использовать свойство Value2 для получения значения (например, string / double), которое также возвращает результат формулы. Чтобы получить формулу, вы можете использовать Formula member.

Я не нашел хорошего способа проверить, рассчитывается ли значение автоматически или нет, но вы можете проверить, начинается ли значение 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

Кстати: чтобы загрузить Excel в F # Interactive, вам нужно что-то вроде этого:

#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) 
0 голосов
/ 17 сентября 2010

Это действительно дало мне идею, и я попытался использовать 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, (MEAN, (RANGE, A3, A20))) "" (+, A1, (*,B4, C6)) "

Все это слишком велико, чтобы положить в эту коробку, но посмотрите здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...