And now for something completely different, Emulating excel in gleam.

Just gone put code here

Code:
import gleam/dict.{type Dict}
import gleam/float
import gleam/io
import gleam/list
import gleam/option.{None, Some}
import gleam/result

// --- 1. TYPE DEFINITIES ---

pub type CellValue {
  Number(Float)
  Text(String)
  Empty
}

type RowKey = String
type ColKey = String

pub type ExcelTable = Dict(RowKey, Dict(ColKey, CellValue))


// --- 2. HOOFDFUNCTIE ---

pub fn main() {
  let table: ExcelTable = dict.new()

  // Vul rij 1 met data
  let table = set_cell(table, row: "1", col: "A", value: Number(10.5))
  let table = set_cell(table, row: "1", col: "B", value: Number(20.0))
  let table = set_cell(table, row: "1", col: "C", value: Text("Niet meerekenen"))
  let table = set_cell(table, row: "1", col: "D", value: Number(5.0))

  // Update cel A1 (overschrijf de oude waarde 10.5 naar 15.0)
  let table = set_cell(table, row: "1", col: "A", value: Number(15.0))

  // --- Test 1: Een specifieke cel uitlezen ---
  io.print("Cel A1 bevat: ")
  case get_cell(table, row: "1", col: "A") {
    Number(val) -> io.println(float.to_string(val))
    Text(txt) -> io.println("Tekst: " <> txt)
    Empty -> io.println("Leeg")
  }

  // --- Test 2: Berekening uitvoeren (Excel SOM formule) ---
  let totaal_rij_1 = sum_row(table, row: "1")
  io.print("Som van alle getallen in Rij 1 (A1 + B1 + D1): ")
  io.println(float.to_string(totaal_rij_1))
}


// --- 3. HELPER FUNCTIES ---

pub fn set_cell(
  table: ExcelTable,
  row row_key: RowKey,
  col col_key: ColKey,
  value value: CellValue,
) -> ExcelTable {
  dict.upsert(table, row_key, fn(maybe_row) {
    case maybe_row {
      Some(existing_row) -> dict.insert(existing_row, col_key, value)
      None -> dict.new() |> dict.insert(col_key, value)
    }
  })
}

pub fn get_cell(table: ExcelTable, row row_key: RowKey, col col_key: ColKey) -> CellValue {
  let maybe_value = {
    use row_dict <- result.try(dict.get(table, row_key))
    dict.get(row_dict, col_key)
  }

  case maybe_value {
    Ok(value) -> value
    Error(Nil) -> Empty
  }
}

pub fn sum_row(table: ExcelTable, row row_key: RowKey) -> Float {
  case dict.get(table, row_key) {
    Error(Nil) -> 0.0
    Ok(row_dict) -> {
      let cellen_lijst = dict.values(row_dict)
      
      list.fold(cellen_lijst, 0.0, fn(totaal, cel) {
        case cel {
          Number(getal) -> totaal +. getal
          Text(_) -> totaal
          Empty -> totaal
        }
      })
    }
  }
}

And as we all know gleam has only "immutable" data structures by design.
 
1779136372632.png
 
Back
Top