I need to find a performant and smart way to redesign the formula or the tables on which it depends (COSTO_DUMMY and GG_TARGET). Can you help me, please? I can add new support tables if needed
COSTO_DUMMY
| key | cost |
|---|---|
| AP01100GENNAIO | 33.9492 |
| AP01100FEBBRAIO | 32.108 |
| AP01100MARZO | 27.889 |
| AP01100APRILE | 34.7004 |
| AP01100MAGGIO | 29.2037 |
| AP01100GIUGNO | 33.3176 |
| AP01100LUGLIO | 31.6459 |
| AP01100AGOSTO | 49.5292 |
| AP01100SETTEMBRE | 29.51 |
| AP01100OTTOBRE | 31.129 |
| AP01100NOVEMBRE | 30.776 |
| AP01100DICEMBRE | 34.7 |
GG_TARGET
| key | days |
|---|---|
| 0050001643GENNAIO | 16.2 |
| 0050001643FEBBRAIO | 18.4 |
| 0050001643MARZO | 21.5 |
| 0050001643APRILE | 16.7 |
| 0050001643MAGGIO | 20.4 |
| 0050001643GIUGNO | 17.5 |
| 0050001643LUGLIO | 18.4 |
| 0050001643AGOSTO | 7.5 |
| 0050001643SETTEMBRE | 20.4 |
| 0050001643OTTOBRE | 19 |
| 0050001643NOVEMBRE | 19.5 |
| 0050001643DICEMBRE | 15.8 |
FACT_TABLE (the structure of this table cannot be modified); I have two column headers in a fixed position: the first one with AP% codes, the second one with the months
| AP01100 | AP01100 | AP01100 | AP01100 | AP01100 | AP01100 | AP01100 | AP01100 | AP01100 | AP01100 | AP01100 | AP01100 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| GENNAIO | FEBBRAIO | MARZO | APRILE | MAGGIO | GIUGNO | LUGLIO | AGOSTO | SETTEMBRE | OTTOBRE | NOVEMBRE | DICEMBRE | |
| 0050001643 | 1 | 4 |
I need to do this formula for each row of the fact table (to be added next to "DICEMBRE"):
(1 * jan_cost * jan_days + 1 * feb_cost * feb_days + ... + 1 * dec_cost * dec_days) +
(4 * feb_cost * feb_days + 4 * mar_cost * mar_days + ... + 4 * dec_cost * dec_days) +
(0 * mar_cost * mar_days + 0 * apr_cost * apr_days + ... + 0 * dec_cost * dec_days) +
.....
(0 * dec_cost * dec_days)
The meaning is: I want to recruit 1 person from january to december and 4 people from february to december (that's why the "4" from fact table ignores january information)
I started writing the following formula (only for the first person to recruit on january and it's missing a vlookup for gg_Target, anyway I think it's clear the way I am thinking about it... the wrong way) but I really hope there is something smarter:
=vlookup(concat(offset(G27;25-row();0);offset(G27;26-row();0));COSTO_DUMMY;2;FALSE)*G27 +
vlookup(concat(offset(G27;25-RIF.RIGA();1);offset(G27;26-row();1));COSTO_DUMMY;2;FALSE)*G27
....
In this formula I have the "1" of the fact_table on G27 cell (hence offset(G27;25-row();0) gives me "AP01100" while offset(G27;26-row();0)) gives me "GENNAIO")
Please, note that I want a constant value, so I am not expecting to use ctrl+shift+enter.
I have this office version

Assuming no Excel version constraints as per the tags listed in the question. The following is an array formula, that spills the entire result and considers more than one target key, even in the example there is only one value.
Assumptons and comments:
All previous assumption are based on the sample input data from the question. Here is the formula that covers a very general case, i.e. more than one target code, different AP codes:
It is a large formula, because it requires several intermediate calculations. It depends on the input ranges for only three names:
setA,setBandfcts. The rest of the names, are obtained from them, playing withDROP,TAKE,INDEX, etc, functions.To do the calculation we filter for months greater or equal than. We convert the input months in text format into Excel dates. The months in date format (
months) are generated usingEDATEfunction combined withSEQUENCE. The month is represented as the first date of the month in date format (we use as a reference year1900). We obtain the corresponding months in text format (tMonths) viaTEXTfunction (no need to take it from the FACT table), using Italian as specific locale (locname). I took the idea from here: Specifying a Language for theTEXTFunction.Now we use the following helper functions we created as user
LAMBDAfunctions:gMonth(x): Given an input datexin text format returns the corresponding month in date format. Created to make the formula easier to read and for debugging purposes.SPLIT(x): Given a keyxas input. It generates an array of two columns separating the key from the date. The second column returns the corresponding text date in date format.CALC(k,ap,m): Given a key (k), an AP code (ap) and a month (min date format), does the multiplication for cost and days only for months greater or equal thanm.Now we have all we need. We iterate over all rows (
lks) from from the FACT table. Each row (lk) contains the key code (k) and the multipliers (mults). We extract this information viaDROPandTAKEfunctions. Now we need to do the total sum for each row. We useREDUCEfor that to iterate over the index positions (idx). For each index (i), we obtain the AP code (ap) and the month (m), so we can invoke theCALCfunction on each iteration and accumulate the result (ac):Here is the output in
S3cell:As per OP additional information provided,
TAKEand userLAMBDAfunction are not available for his Excel version. Here a solution that doesn't use such functions: