Good afternoon, I have a problem when trying to automate a horizontal depreciation scheme for a financial model in Excel.
For example, the variables are the following in different periods:
enter image description here
But the generated result is the following:
enter image description here
enter image description here
Behind it I have the following arrays in the ScheduleStack variable.
enter image description here
But I don’t understand how I can summarize it by Asset and Period. Since xlookup only takes the first asset it finds in the variable.
The code is the following:
schedule = LAMBDA(cost, periods, start,
LET(
_periods, SEQUENCE(periods + 1, 1, 0),
_depr, IFERROR(IF(_periods = 0, 0, SLN(cost, 0, periods)), 0),
_acc, SCAN(0, _depr, LAMBDA(a, b, a + b)),
_periodslabels, EOMONTH(start, _periods),
_dav, cost - _acc,
_array, CHOOSE({1, 2, 3, 4, 5}, _periodslabels, _periods, _depr, _acc, _dav),
_output, IF(_array, _array),
_output
)
);
array_create = LAMBDA(Rows, Columns, Defaults,
LET(
D, IF(
COLUMNS(Defaults) > 1,
INDEX(Defaults, 1, 0),
LEFT(INDEX(Defaults, 1, 1), SEQUENCE(1, Columns, LEN(INDEX(Defaults, 1, 1)), 0))
),
X, SEQUENCE(1, Columns),
Y, SEQUENCE(Rows, 1, 1, 0),
IFERROR(INDEX(D, 1, X * Y), "")
)
);
schedule_stack = LAMBDA(t, tv, tt, tc,
LET(
f_asset, ROWS(t),
f_vida, ROWS(tv),
f_time, ROWS(tt),
f_concepto, ROWS(tc),
c_asset, COLUMNS(t),
c_vida, COLUMNS(tv),
c_time, COLUMNS(tt),
indice_f_asset, SEQUENCE(f_asset, 1, 1),
indice_f_vida, SEQUENCE(f_vida, 1, 1),
indice_c_asset, SEQUENCE(1, c_asset, 1),
indice_c_vida, SEQUENCE(1, c_vida, 1),
tc_c, array_create(f_asset, f_concepto, TRANSPOSE(tc)),
info_table, LAMBDA(b,
HSTACK(
INDEX(tc_c, , b),
INDEX(t, indice_f_asset, b),
INDEX(tv, indice_f_vida, b),
INDEX(tt, , 1)
)
),
resultado, VSTACK(info_table(1), info_table(2)),
GetVal, LAMBDA(row, LAMBDA(col, INDEX(resultado, row, col))),
Schedule, LAMBDA(b,
LET(
args, GetVal(b),
depre_n.schedule(
args(2), //cost
args(3), //life
args(4) //start
)
)
),
Schedule1, Schedule(1),
AssetNameCol, LAMBDA(name, sch, EXPAND(name, ROWS(sch), 1, name)),
RowIndex, SEQUENCE(ROWS(Schedule(0))),
NameCol1, AssetNameCol(GetVal(1)(1), Schedule1),
Init, HSTACK(NameCol1, Schedule1),
Schedules, REDUCE(
Init,
DROP(RowIndex, 1),
LAMBDA(a, b,
LET(
Schedule_b, Schedule(b),
NameCol_b, AssetNameCol(GetVal(b)(1), Schedule_b),
VSTACK(a, HSTACK(NameCol_b, Schedule_b))
)
)
),
Schedules
)
);
waterfall = LAMBDA(
asset_purchases_table,
vida_table,
time_table,
concepto_table,
start,
end,
[vertical],
LET(
omitted, ISOMITTED(asset_purchases_table) + ISOMITTED(start) + ISOMITTED(end),
IF(
omitted,
"ERROR: asset_purchases_table, depn_fn, start or end is missing",
LET(
t, TRANSPOSE(asset_purchases_table),
tv, TRANSPOSE(vida_table),
tt, TRANSPOSE(time_table),
tc, concepto_table,
ReturnVertical, IF(ISOMITTED(vertical), FALSE, vertical),
PeriodCount, ROWS(asset_purchases_table),
PeriodLabels, tt,
ScheduleStack, depre_n.schedule_stack(t, tv, tt, tc),
Assets, tc,
GetAssetDepn, LAMBDA(x,
LET(
FilteredDepn, FILTER(
DROP(ScheduleStack, 0, 1),
CHOOSECOLS(ScheduleStack, 1) = x
),
//LET(a,PeriodLabels,VSTACK(a,CHOOSECOLS( ScheduleStack , 0 )))
XLOOKUP(
PeriodLabels,
CHOOSECOLS(FilteredDepn, 1),
CHOOSECOLS(FilteredDepn, 3),
0
)
//VSTACK(CHOOSECOLS( FilteredDepn , 1 ),CHOOSECOLS( FilteredDepn , 3 ))
)
),
Schedules, REDUCE(
GetAssetDepn(TAKE(Assets, 1)),
DROP(Assets, 1),
LAMBDA(a, b, HSTACK(a, GetAssetDepn(b)))
),
Totals, BYROW(Schedules, LAMBDA(r, SUM(r))),
Result, VSTACK(
HSTACK("", TRANSPOSE(Assets), "Total"),
HSTACK(PeriodLabels, Schedules, Totals)
),
IF(ReturnVertical, ScheduleStack, TRANSPOSE(ScheduleStack))
)
)
)
);
Luigi Rodriguez Lopez is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1