Skip to content

Commit

Permalink
Fix critical FsWorksheet error and add non-static methods for functio…
Browse files Browse the repository at this point in the history
…nalities
  • Loading branch information
omaus committed Mar 5, 2023
1 parent a2fc967 commit 810424f
Showing 1 changed file with 129 additions and 65 deletions.
194 changes: 129 additions & 65 deletions src/FsSpreadsheet/FsWorksheet.fs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@ type FsWorksheet (name, fsRows, fsTables, fsCellsCollection) =
// METHODS
// -------

/// Returns a copy of the FsWorksheet.
member self.Copy() =
let newSheet = FsWorksheet(self.Name)
self.Tables
|> List.iter (
fun t ->
newSheet.Table(t.Name, t.RangeAddress, t.ShowHeaderRow)
|> ignore
)
for row in (self.Rows) do
let (newRow : FsRow) = newSheet.Row(row.Index)
for cell in row.Cells do
let newCell = newRow.Cell(cell.Address,newSheet.CellCollection)
newCell.SetValue(cell.Value)
|> ignore
newSheet

/// Returns the FsRow at the given index. If it does not exist, it is created and appended first.
member self.Row(rowIndex) =
match _rows |> List.tryFind (fun row -> row.Index = rowIndex) with
Expand All @@ -63,17 +80,67 @@ type FsWorksheet (name, fsRows, fsTables, fsCellsCollection) =
failwithf "Row may not have a range address spanning over different row indices"
self.Row(rangeAddress.FirstAddress.RowNumber).RangeAddress <- rangeAddress

/// Inserts an FsRow into the FsWorksheet before a reference FsRow.
member self.InsertBefore(row : FsRow, refRow : FsRow) =
_rows
|> List.iter (
fun (r : FsRow) ->
if r.Index >= refRow.Index then
r.Index <- r.Index + 1
)
self.Row(row.Index) |> ignore
self

/// Returns true if the FsWorksheet contains an FsRow with the given rowIndex.
member self.ContainsRowAt(rowIndex) =
self.Rows
|> List.exists (fun t -> t.Index = rowIndex)

/// Removes the FsRow at the given rowIndex.
member self.RemoveRowAt(rowIndex) =
let newRows =
_rows
|> List.filter (fun r -> r.Index <> rowIndex)
_rows <- newRows

/// Removes the FsRow at a given rowIndex of the FsWorksheet if the FsRow exists.
member self.TryRemoveAt(rowIndex) =
if self.ContainsRowAt rowIndex then
self.RemoveRowAt rowIndex
self

/// Sorts the FsRows by their rowIndex.
member self.SortRows() =
_rows <- _rows |> List.sortBy (fun r -> r.Index)

/// Applies function f to all FsRows and returns the modified FsWorksheet.
member self.MapRowsInPlace(f : FsRow -> FsRow) =
let indeces = self.Rows |> List.map (fun r -> r.Index)
indeces
|> List.map (fun i -> f (self.Row(i)))
|> fun res -> _rows <- res
self

/// Returns the highest index of any FsRow.
member self.GetMaxRowIndex() =
try
self.Rows
|> List.maxBy (fun r -> r.Index)
with :? System.ArgumentException -> failwith "The FsWorksheet has no FsRows."

/// Gets the string values of the FsRow at the given 1-based rowIndex.
member self.GetRowValuesAt(rowIndex) =
if self.ContainsRowAt rowIndex then
self.Row(rowIndex).Cells
|> Seq.map (fun c -> c.Value)
else Seq.empty

/// Gets the string values at the given 1-based rowIndex of the FsRow if it exists, else returns None.
member self.TryGetRowValuesAt(rowIndex) =
if self.ContainsRowAt rowIndex then
Some (self.GetRowValuesAt rowIndex)
else None

/// Checks the cell collection and recreate the whole set of rows, so that all cells are placed in a row
member self.RescanRows() =
let rows = _rows |> Seq.map (fun r -> r.Index,r) |> Map.ofSeq
Expand Down Expand Up @@ -108,27 +175,50 @@ type FsWorksheet (name, fsRows, fsTables, fsCellsCollection) =
member self.Table(tableName,rangeAddress) =
self.Table(tableName,rangeAddress,true)

/// Returns the FsCell at the given row- and columnIndex if the FsCell exists, else returns None.
member self.TryGetCellAt(rowIndex, colIndex) =
self.CellCollection.TryGetCell(rowIndex, colIndex)

/// Returns the FsCell at the given row- and columnIndex.
member self.GetCellAt(rowIndex, colIndex) =
self.TryGetCellAt(rowIndex, colIndex).Value

/// Adds a value at the given row- and columnIndex to the FsWorksheet.
///
/// If a cell exists at the given postion, it is shoved to the right.
member self.InsertValueAt(value : 'a, rowIndex, colIndex)=
//let row = FsWorksheet.getRowAt rowIndex sheet
let cell = FsCell(value)
self.CellCollection.Add(int32 rowIndex, int32 colIndex, cell)

/// Adds a value at the given row- and columnIndex.
///
/// If an FsCell exists at the given position, overwrites it.
member self.SetValueAt(value : 'a, rowIndex, colIndex) =
match self.CellCollection.TryGetCell(rowIndex, colIndex) with
| Some c ->
c.SetValue value |> ignore
self
| None ->
self.CellCollection.Add(rowIndex, colIndex, value)
self

// TO DO (later)
//static member tryRemoveValueAt

/// Removes the value at the given row- and columnIndex from the FsWorksheet.
member self.RemoveValueAt(rowIndex, colIndex) =
self.CellCollection.Remove(int32 rowIndex, int32 colIndex)
self


// --------------
// STATIC METHODS
// --------------

/// Returns a copy of a given FsWorksheet.
static member copy (sheet : FsWorksheet) =
let newSheet = FsWorksheet(sheet.Name)
sheet.Tables
|> List.iter (
fun t ->
newSheet.Table(t.Name, t.RangeAddress, t.ShowHeaderRow)
|> ignore
)
for row in (sheet.Rows) do
let newRow = newSheet.Row(row.Index)
for cell in row.Cells do
let newCell = newRow.Cell(cell.Address,newSheet.CellCollection)
newCell.SetValue(cell.Value)
|> ignore
newSheet
sheet.Copy()


// ------
Expand All @@ -137,13 +227,7 @@ type FsWorksheet (name, fsRows, fsTables, fsCellsCollection) =

/// Inserts an FsRow into the FsWorksheet before a reference FsRow.
static member insertBefore row (refRow : FsRow) (sheet : FsWorksheet) =
FsWorksheet.getRows sheet
|> List.iter (
fun (r : FsRow) ->
if r.Index >= refRow.Index then
r.Index <- r.Index + 1
)
FsWorksheet.appendRow row sheet
sheet.InsertBefore(row, refRow)

/// Appends an FsRow to an FsWorksheet if the rowIndex is not already taken.
static member appendRow (row : FsRow) (sheet : FsWorksheet) =
Expand Down Expand Up @@ -172,8 +256,7 @@ type FsWorksheet (name, fsRows, fsTables, fsCellsCollection) =

/// Returns true if the FsWorksheet contains an FsRow with the given rowIndex.
static member containsRowAt rowIndex (sheet : FsWorksheet) =
sheet.Rows
|> List.exists (fun t -> t.Index = rowIndex)
sheet.ContainsRowAt rowIndex

// QUESTION: Does that make any sense at all? After all, CellValues are changed inPlace anyway
///// Builds a new FsWorksheet whose FsRows are the result of of applying the given function f to each FsRow of the given FsWorksheet.
Expand All @@ -190,10 +273,7 @@ type FsWorksheet (name, fsRows, fsTables, fsCellsCollection) =

/// Applies function f in a given FsWorksheet to all FsRows and returns the modified FsWorksheet.
static member mapRowsInPlace (f : FsRow -> FsRow) (sheet : FsWorksheet) =
let indeces = sheet.Rows |> List.map (fun r -> r.Index)
for i in indeces do
sheet.Row(i) <- f (sheet.Row(i))
sheet
sheet.MapRowsInPlace f

/// Returns the number of FsRows contained in the FsWorksheet.
static member countRows (sheet : FsWorksheet) =
Expand All @@ -210,31 +290,24 @@ type FsWorksheet (name, fsRows, fsTables, fsCellsCollection) =
sheet.RemoveRowAt rowIndex

// TO DO (later)
/// If an FsRow with index rowIndex exists in the FsWorksheet, moves it downwards by amount. Negative amounts will move the FsRow upwards.
///// If an FsRow with index rowIndex exists in the FsWorksheet, moves it downwards by amount. Negative amounts will move the FsRow upwards.
//static member moveRowVertical amount rowIndex (sheet : FsWorksheet) =
// match FsWorksheet.containsRowAt

// TO DO (later)
//static member moveRowBlockDownward rowIndex sheet =


/// Returns the highest index of any FsRow in a given FsWorksheet.
static member getMaxRowIndex (sheet : FsWorksheet) =
try
sheet.Rows
|> List.maxBy (fun r -> r.Index)
with :? System.ArgumentException -> failwith "Given FsWorksheet has no FsRows."
sheet.GetMaxRowIndex()

/// Gets the string values of the FsRow at the given 1-based rowIndex.
static member getRowValuesAt rowIndex sheet =
(FsWorksheet.getRowAt rowIndex sheet).Cells
|> Seq.map (fun c -> c.Value)

/// Gets the string values of the FsRow at the given 1-based rowIndex if it exists, else returns None.
static member tryGetRowValuesAt rowIndex sheet =
(FsWorksheet.tryGetRowAt rowIndex sheet)
|> Option.map (
fun r -> r.Cells
>> Seq.map (fun c -> c.Value)
)
/// Gets the string values of the FsRow at the given 1-based rowIndex of a given FsWorksheet.
static member getRowValuesAt rowIndex (sheet : FsWorksheet) =
sheet.GetRowValuesAt rowIndex

/// Takes an FsWorksheet and gets the string values at the given 1-based rowIndex of the FsRow if it exists, else returns None.
static member tryGetRowValuesAt rowIndex (sheet : FsWorksheet) =
sheet.TryGetRowValuesAt rowIndex

// TO DO (later)
//static member tryGetIndexedRowValuesAt rowIndex sheet =
Expand All @@ -249,11 +322,11 @@ type FsWorksheet (name, fsRows, fsTables, fsCellsCollection) =

/// Returns the FsCell at the given row- and columnIndex of a given FsWorksheet if the FsCell exists, else returns None.
static member tryGetCellAt rowIndex colIndex (sheet : FsWorksheet) =
sheet.CellCollection.TryGetCell(rowIndex, colIndex)
sheet.TryGetCellAt(rowIndex, colIndex)

/// Returns the FsCell at the given row- and columnIndex of a given FsWorksheet.
static member getCellAt rowIndex colIndex sheet =
(FsWorksheet.tryGetCellAt rowIndex colIndex sheet).Value
static member getCellAt rowIndex colIndex (sheet : FsWorksheet) =
sheet.GetCellAt(rowIndex, colIndex)

// TO DO (later)
//static member tryGetCellValueAt rowIndex colIndex sheet =
Expand All @@ -262,33 +335,24 @@ type FsWorksheet (name, fsRows, fsTables, fsCellsCollection) =
//static member getCellValueAt rowIndex colIndex sheet =


/// Adds a value at the given row- and columnIndex to the FsWorksheet.
/// Adds a value at the given row- and columnIndex to a given FsWorksheet.
///
/// If a cell exists at the given postion, it is shoved to the right.
/// If an FsCell exists at the given position, it is shoved to the right.
static member insertValueAt (value : 'a) rowIndex colIndex (sheet : FsWorksheet)=
//let row = FsWorksheet.getRowAt rowIndex sheet
let cell = FsCell(value)
sheet.CellCollection.Add(int32 rowIndex, int32 colIndex, cell)
sheet.InsertValueAt(value, rowIndex, colIndex)

/// Adds a value at the given row- and columnIndex.
/// Adds a value at the given row- and columnIndex of a given FsWorksheet.
///
/// If a cell exists at the given position, overwrites it.
/// If an FsCell exists at the given position, it is overwritten.
static member setValueAt (value : 'a) rowIndex colIndex (sheet : FsWorksheet) =
match sheet.CellCollection.TryGetCell(rowIndex, colIndex) with
| Some c ->
c.SetValue value |> ignore
sheet
| None ->
sheet.CellCollection.Add(rowIndex, colIndex, value)
sheet
sheet.SetValueAt(value, rowIndex, colIndex)

// TO DO (later)
//static member tryRemoveValueAt

/// Removes the value at the given row- and columnIndex from the FsWorksheet.
/// Removes the value at the given row- and columnIndex from an FsWorksheet.
static member removeValueAt rowIndex colIndex (sheet : FsWorksheet) =
sheet.CellCollection.Remove(int32 rowIndex, int32 colIndex)
sheet
sheet.RemoveValueAt(rowIndex, colIndex)


// ------------
Expand Down

0 comments on commit 810424f

Please sign in to comment.