119 lines
3.7 KiB
V
119 lines
3.7 KiB
V
module spreadsheet
|
|
|
|
import incubaid.herolib.ui.console
|
|
|
|
// smartstring is something like 3:2,10:5 means end month 3 we start with 2, it grows to 5 on end month 10 .
|
|
// the cells out of the mentioned ranges are not filled if they are already set .
|
|
// the cells which are empty at start of row will become 0 .
|
|
// the cells which are empty at the back will just be same value as the last one .
|
|
// currencies can be used e.g. 3:10usd,20:30aed (so we can even mix) .
|
|
// first cell is 1, the start is 0 (month 0) .
|
|
// if the smartstr, is empty then will use existing values in the row to extra/intra polate, the empty values will be filled in
|
|
pub fn (mut r Row) extrapolate(smartstr string) ! {
|
|
// put the values in the row
|
|
// console.print_debug("extrapolate: ${smartstr}")
|
|
for mut part in smartstr.split(',') {
|
|
part = part.trim_space()
|
|
if part.contains(':') {
|
|
splitted := part.split(':')
|
|
if splitted.len != 2 {
|
|
return error("smartextrapolate needs '3:2,10:5' as format, now ${smartstr} ")
|
|
}
|
|
mut x := splitted[0].int()
|
|
if x < 0 {
|
|
return error('Cannot do smartstr, because the X is out of scope.\n${smartstr}')
|
|
}
|
|
if x > r.sheet.nrcol - 1 {
|
|
x = r.sheet.nrcol - 1
|
|
}
|
|
r.cells[x].set(splitted[1])!
|
|
}
|
|
}
|
|
|
|
mut xlast := 0 // remembers where there was last non empty value
|
|
mut has_previous_value := false
|
|
mut xlastval := 0.0 // the value at that position
|
|
mut xlastwidth := 0 // need to know how fast to go up from the xlast to xnew
|
|
mut xnewval := 0.0
|
|
// console.print_debug(r)
|
|
for x in 0 .. r.cells.len {
|
|
// console.print_debug("$x empty:${r.cells[x].empty} xlastwidth:$xlastwidth xlastval:$xlastval xlast:$xlast")
|
|
if r.cells[x].empty && !has_previous_value {
|
|
continue
|
|
}
|
|
has_previous_value = true
|
|
if r.cells[x].empty == false && xlastwidth == 0 {
|
|
// we get new value, just go to next
|
|
xlast = x
|
|
xlastval = r.cells[x].val
|
|
xlastwidth = 0
|
|
// console.print_debug(" lastval:$xlastval")
|
|
continue // no need to do anything
|
|
}
|
|
// if we get here we get an empty after having a non empty before
|
|
xlastwidth += 1
|
|
if r.cells[x].empty == false {
|
|
// now we find the next one not being empty so we need to do the interpolation
|
|
xnewval = r.cells[x].val
|
|
// now we need to walk over the inbetween and set the values
|
|
yincr := (xnewval - xlastval) / xlastwidth
|
|
mut yy := xlastval
|
|
// console.print_debug(" yincr:$yincr")
|
|
for xx in (xlast + 1) .. x {
|
|
yy += yincr
|
|
r.cells[xx].set('${yy:.2f}')!
|
|
}
|
|
xlast = x
|
|
xlastval = xnewval
|
|
xlastwidth = 0
|
|
xnewval = 0.0
|
|
}
|
|
}
|
|
// console.print_debug("ROW1:$r")
|
|
|
|
// now fill in the last ones
|
|
xlastval = 0.0
|
|
for x in 0 .. r.cells.len {
|
|
if r.cells[x].empty == false {
|
|
xlastval = r.cells[x].val
|
|
continue
|
|
}
|
|
r.cells[x].set('${xlastval:.2f}')!
|
|
}
|
|
|
|
// console.print_debug("ROW:$r")
|
|
// if true{panic("s")}
|
|
}
|
|
|
|
// something like 3:2,10:5 means end month 3 we set 2, month 10 5
|
|
// there i no interpolation, all other fields are set on 0
|
|
pub fn (mut r Row) smartfill(smartstr string) ! {
|
|
// console.print_debug("smartfill: ${smartstr}")
|
|
for mut part in smartstr.split(',') {
|
|
part = part.trim_space()
|
|
if part.contains(':') {
|
|
splitted := part.split(':')
|
|
if splitted.len != 2 {
|
|
return error("smartextrapolate needs '3:2,10:5' as format, now ${smartstr} ")
|
|
}
|
|
x := splitted[0].int()
|
|
if x < 0 {
|
|
return error('Cannot do smartstr, because the X is out of scope.\n${smartstr}')
|
|
}
|
|
if x >= r.sheet.nrcol {
|
|
// If the index is at or beyond the array bounds, use the last available index
|
|
r.cells[r.sheet.nrcol - 1].set(splitted[1])!
|
|
} else {
|
|
r.cells[x].set(splitted[1])!
|
|
}
|
|
} else {
|
|
r.cells[0].set(part)!
|
|
}
|
|
}
|
|
for x in 0 .. r.cells.len {
|
|
if r.cells[x].empty {
|
|
r.cells[x].set('0.0')!
|
|
}
|
|
}
|
|
}
|