状態遷移表の読み込み

「状態遷移表の読み込み」をモジュールとして切り出す

状態遷移表

f:id:borsalino:20161010161329p:plain

モジュール

#light
module StateTable 
open Microsoft.Office.Interop.Excel
open System.Runtime.InteropServices

type File = string
type Sheet = string
type Address = string

type CellValue = string
type State = CellValue
type Variable = CellValue
type Action = CellValue
type Value = CellValue
type Transition = CellValue

type CreateRange = Range*int*int -> Address
type ToMatrixRange = Range*Range -> Address

type CellToValue = System.Object -> CellValue
type ColumnsToValues = Range -> CellValue[]
type RowsToValues = Range -> CellValue[]
type MatrixToValues = Range -> CellValue[][]

type StateTable = State[]*Variable[]*Action[]*Value[][]*Transition[][]
type ToStateTable = File*Sheet -> StateTable

let CreateRange (cell:Range, rows:int, columns:int):Address =
  cell.Address() + ":" + cell.Offset(rows-1,columns-1).Address()
let CellToValue (cell:System.Object):CellValue = (cell:?>Range).Value2:?>CellValue
let ColumnsToValues (range:Range) =
  [|for i in 1..range.Columns.Count do yield (range.[1,i] |> CellToValue)|]
let RowsToValues (range:Range):CellValue[] =
  [|for i in 1..range.Rows.Count do yield (range.[i,1] |> CellToValue)|]
let MatrixToValues (range:Range):CellValue[][] =
  [|for i in 1..range.Rows.Count do 
      yield [|for j in 1..range.Columns.Count do 
                yield (range.[i,j] |> CellToValue)|]|]

let ToMatrixRange ((hrange:Range),(vrange:Range)):string =
  (hrange.[2,1]:?>Range,
   vrange.Rows.Count,
   hrange.Columns.Count) |> CreateRange   

let ToStateTable ((file:File),(sheet:Sheet)):StateTable =
  let excel = ApplicationClass(Visible = false)
  let dir = System.IO.Directory.GetCurrentDirectory() 
  let workbooks = excel.Workbooks.Open(file)
  let worksheet = workbooks.Sheets.[sheet] :?> Worksheet
  
  let StateRange = worksheet.Range("A2:A5") // .Range("State")
  let VariableRange = worksheet.Range("B1:D1") // .Range("Variable")
  let ActionRange = worksheet.Range("E1:H1") // .Range("Action")
  let ValueRange = (VariableRange,StateRange) |> ToMatrixRange
  let TransitionRange = (ActionRange,StateRange) |> ToMatrixRange

  let states:State[] = StateRange |> RowsToValues
  let variables:Variable[] = VariableRange |> ColumnsToValues
  let actions:Action[] = ActionRange |> ColumnsToValues
  let values:Value[][] = worksheet.Range(ValueRange) |> MatrixToValues
  let transitions:Transition[][] = worksheet.Range(TransitionRange) |> MatrixToValues

  excel.Quit()
  excel |> Marshal.ReleaseComObject |> ignore
  (states,variables,actions,values,transitions)

呼び出し

#light
module main 
let (states,variables,actions,values,transitions) =
  let dir = System.IO.Directory.GetCurrentDirectory()
  (dir + @"\sample.xlsx","Sheet1")
    |> StateTable.ToStateTable