Trying to sum arrays that overlap by grabbing data from a table - google-apps-script

my issue is hard to explain so I'm going to give you an example.
Let the sample arrays be:
array1: 1,2,0,4
array2: 0,0,1,0
array3: 0,1,6,2
I have these numbers separated by cell and not comma, but that doesn't matter.
Next step is: I type (as text, not formula) array1 + array2 in a column, and I want to get the result.
So first example:
1| array1 + array2
would give:
1| 1 (array1 1st value) + 0 (array2 1st value) = 1
2| 2 (array1 2nd value) + 0 (array2 2nd value) = 2
3| 0 (arra1 3rd value) + 1 (array2 3rd value) = 1
4| 4 (array1 4th value) + 0 (array2 4th value) = 4
Another example (different cells):
1| array1
2| array2
this would return=
1| 1 (array1 1st value) = 1 (there is no other array value there so nothing else is added)
2| 2 (array1 2nd value) + 0 (array2 1st value) = 2
3| 0 (arra1 3rd value) + 0 (array2 2rd value) = 0 4|
4 (array1 4th value) + 1 (array2 3rd value) = 5
5| 0 (array2 4th value) = 0
Third example:
1| array1 + array3
2|
3| array2
this returns=
1| 1 (arr1 1st) + 0 (arr3 1st) = 1
2| 2 (arr1 2nd) + 1 (arr3 2nd) = 3
3| 0 (arr1 3rd) + 6 (arr3 3rd) + 0 (arr2 1st) = 6
4| 4 (arr1 4th) + 2 (arr3 4th) + 0 (arr2 2nd) = 6
5| 1 (arr2 3rd) = 1 6| 0 (arr2 (4th) = 0
Notes: the arrays aren't limited to 4 values, it depends on my database and they go up to 26 cells (1 per value for each array name). I reduced them to 4 for this example only.
My database is static though, so you don't need to worry about array2 becoming something else mid calculations. If array2 is "a b c d" it will be that until the end.
Some ways to interpret this
So in other words I want to treat them as arrays that would have overlapped otherwise, but keep adding the values.
Another way to see it is imagine REF errors didn't exist due to overlapping a cell, and it just kept going.
You could fix this by adding more auxiliary columns and adding values on separate columns to make sure they don't overlap, but you would need a ridiculous amount of columns for this and we already tried it, it went horribly wrong.
I know this request might not be clear so I'll reply to anyone that tries to help, other people struggled with this in the past and if I'm here it's because it's my last resort before giving up.
I have tried asking in the sheets Discord and I got told to come here many times to be fair but every new person that got involved with this found a new approach but we never managed to solve it.
I ended up receiving a script that does this and it does the job but it's extremely slow. Even if you help me fix the script instead, I need to solve this for multiple formulas, as my sheet depends on this several times.
Having that script run on edit was horrible for its performance.
I'm going to be posting here the script that does the job ONLY because I think it could help you understand the issue and NOT because I'm trying to fix the script. I'm trying to get rid of it.
code
Here "abilities" would be that column where I typed array1 + array3, etc., and "database" is the whole array that contains both the array name and its respective values.
Once again, the way the database is setup is:
name1 | value1 | value2 | ... | valueN
:
. nameN | value1 | value2 | ... | valueN
Obviously the values are different for every array (or "name") that exists, but I have them stored. So for testing purposes you could just set a simple database with random names and values.
example

Here you have a potential solution. It extends through an amount of rows equal to the last column of your sheet plus the last value found in column A for the names of arrays, so you're sure everything is taken:
COLUMNS(B1:1)+INDEX(MAX(ROW(A:A)*(A:A<>"")))-ROW()
With BYROW and SEQUENCE, you'll have a SUM of the MAPped cells through the values, having the position with MATCH of each of the arrays names.
I've created up to five arrays, with more decimals in each case so you can easily see what values are taken in each opportunity.
=BYROW(SEQUENCE(COLUMNS(B1:1)+INDEX(MAX(ROW(A:A)*(A:A<>"")))-ROW()),
LAMBDA(each,SUM(
MAP(A1:A5,LAMBDA(arr,IFNA(IF(MATCH("*"&arr&"*",A7:A,0)<=each,IFERROR(INDEX(B1:5,ROW(arr),each-MATCH("*"&arr&"*",A7:A,0)+1)))))))))
Other setup:
Let me know!
UPDATE:
With the possibility of starting arrays again you can use:
=BYROW(SEQUENCE(COLUMNS(B1:1)+INDEX(MAX(ROW(A:A)*(A:A<>"")))-ROW()),
LAMBDA(each,SUM(MAP(A1:A5,LAMBDA(arr,IFNA(IFERROR(INDEX(B1:5,ROW(arr),each+row()-XLOOKUP(1,INDEX(--REGEXMATCH(A7:INDEX(A7:A,each),arr)),INDEX(ROW(A7:INDEX(A7:A,each))),-90,0,-1)))))))))
RE-UPDATE
For avoiding similar matching values, you can use this formula. Always separate with the same character, "+" in my formula, or change it accordingly:
=BYROW(SEQUENCE(COLUMNS(B1:1)+INDEX(MAX(ROW(A:A)*(A:A<>"")))-ROW()),
LAMBDA(each,SUM(MAP(A1:A5,LAMBDA(arr,IFNA(IFERROR(INDEX(B1:5,ROW(arr),each+row()-XLOOKUP(1,BYROW(A7:INDEX(A7:A,each),LAMBDA(v,IF(IFERROR(MATCH(arr,TRIM(SPLIT(v,"+")),0),)>0,1,0))),INDEX(ROW(A7:INDEX(A7:A,each))),-90,0,-1)))))))))

Solution presented by the Spreadsheets Discord (Astral):
=ArrayFormula(lambda(keys,values,queries,lambda(lastrow,reduce(if(sequence(lastrow+columns(values)-1),),sequence(lastrow),lambda(a,c,byrow({a,transpose(split(transpose(iferror(rept("🧋",c-1)&bycol(split(index(range,c)," +"),lambda(x,join("🧋",filter(values,keys=x))))&rept("🧋",lastrow-c),rept("🧋",lastrow+columns(values)-2))),"🧋",,))},lambda(x,sum(x))))))(max(if(queries="",,row(queries)))-row()+1))(names,damage,range))
names (range of array names)
damage (range of array values)
range (where you type "array1 + array2")
It has a few issues but they can all be solved with some auxiliary columns.
Thanks for the help!

Related

Shared foreign keys without duplication of entries?

Sorry for the beginner question.
I have an Outputs table:
ID
value
0
x
1
y
2
z
And an Inputs table that is linked to the Outputs through the outputsID:
ID
outputsID
name
0
0
A
1
1
B
2
1
C
3
2
B
4
2
C
Assuming that multiple outputs have at least one shared input (in this example outputID 1,3 and 2,4 are the same), is there a way to avoid the duplication of entries in my Inputs table (inputID 3 and 4)?
The 'normal' answer to your question is no. Rows 1 and 2 address output 1, and Rows 3 and 4 address output 2. They aren't duplicates and each reflect something distinct.
So if you are a beginner, I would say you shouldn't want to get rid of these rows.
That said, there are some more advanced techniques. For example, you could have the OutputsID column be an array with multiple values. This is harder, more complex, and non-standard.

Power BI: transform JSON Records into columns by Record row index

This is my first day using Power BI so go easy on me!
Within my table I have a column of JSON records
[Column of JSON records]
Each Record has 3 rows, with 2 columns (I only need the value of the first column).
[Record with 3 rows]
As the index/position of each record's rows represents the same thing, I want to convert the index/position into a new column in the table, and populate it with each records' corresponding value from column 1.
For example:
The JSON Record from table row 1:
----
1479
1481
1486
---
The JSON Record from table row 2:
----
1351
1536
1356
---
Expected output:
New Column 1 | New Column 2
1479 | 1351
1481 | 1536
1486 | 1356
I have searched for a solution but to no avail. Hopefully someone can help me here. Let me know if you need any further clarification.
Thanks in advance!
I've found a way to achieve this by using a couple of Transform functions. I reversed parsing the column to JSON, and instead used the Split Column function to separate the JSON by the , delimiter (creating the 3 columns I required), and then isolated the required data within the columns using the Extract function.

Find the next empty row within a range

Is there an easy way in App Script to find the next empty row within a range, for example I'd like the following:
A B C D E
1|CODE RM1 RM2 RM3 NAME
2| 021 x x Pete
3| 531 x x Mike
4| 141 John
5| 155 x x Paul
return the next row blank row in the range B2:D
so it would return Row 4
other rows (like rows A & E in the above example) will have data so should be ignored.
I'm trying to write to the next blank row from another sheet (or tab) which has an input area for users to enter data and hit a button, the data will then add to the blank row on the target page (first row of DATA!B2:D)
Try this to do that with a spreadsheet formula:
=+filter(row(B2:D), not(len(B2:B & C2:C & D2:D)))
If you do not want the row number, but the value in column A, replace row(B2:D) with A2:A.
To do this in Apps Script, try this pattern:
const range = SpreadsheetApp.getActive().getRange('Sheet1!B2:D');
const firstBlankRow = range.getValues().findIndex(row => !row.join('')) + 1;

How to add a seperate column instead of a row group in a matrix SSRS Report

I am trying to create a matrix report in SSRS using Visual Studuio 2008 .
My reports are .rdlc reports
This is how I want the report look like
Product Name |Year | Question1| Question 2| so on........
Test 1 |2012 | Response1| Response 2| so on........
Test 1 |2013 | Response1| Response 2| so on........
But my report comes as like this
Product Name | Question1| Question 2| so on........
Test 1 |2012 | Response1| Response 2| so on........
|2013 | Response1| Response 2| so on........
I am not able to achieve this the year column is adding a sub group
but not as a seperate column
When I right click on the Product Name row these are the options i get though
Here is the screen shot of the report
Let me know if any other option i have .
Thanks ,
Sravanthi
It would be easier to troubleshoot if you post your report design.
Method 1 Split Cells
Step 1. Right click on the detail row for product (where it says Fields!Product.Value or Test) and insert a row. Insert Row > Inside Group - Below
Step2. Right click on the data/detail row for product and you will see an option for split cells. Click on that. It will split the cells.
Step 3. Delete the row added in step 1 without deleting any row groupings.
Step 4. Run your report, you should see the changes.
Method 2 Delete the columns and re-add them
Step 1. Delete Product and Year columns without deleting the associated groups.
Step 2. Right Click on your Question column and click on Insert Column > Outside Group - Left. Do that twice.
Step 3. In those newly generated columns add the Product and Year header and data.
Step 4. Run your report, you should see the changes.

Define quadrant based on positive/negative values in two columns

I have a data set with two columns of positive and negative numbers. I would like to create a third column that reflects which quadrant they would appear in if plotted in Cartesian space.
For example, if Column A is positive, and Column B is positive, then Column C would record "I." If column A is negative, and Column B is negative, then Column C would record "III," and so on.
I suspect I can do this with an if else function and then loop or apply it across rows in the data set, but my attempts to write the if else have so far failed.
Well, the following would give you values between 1 and 4:
C <- (A<0) + (B<0)*2L + 1L
This transforms the whole column in one go. The magic lies in that FALSE/TRUE is treated as 0/1, and you can do math on it. By using 2L and 1L instead of 2 and 1, you keep the result as integers instead of forcing a coercion to doubles (which is slower and takes more memory).
Then assuming you want to map to these quadrants:
+B
|
II | I
-A -----+---- +A
III | IV
|
-B
You could use this (updated to use a data.frame):
# Sample data.frame with columns a & b
d <- data.frame(a=c(1,-1,-1,1), b=c(1,1,-1,-1))
quadrantNames <- c('I', 'II', 'IV', 'III') # Your labels...
d <- within(d, c <- quadrantNames[(a<0) + (b<0)*2L + 1L])
head(d) # print data
a b c
1 1 1 I
2 -1 1 II
3 -1 -1 III
4 1 -1 IV
...and if you want the quadrants mapped differently, just change the order of the labels in quadrantNames.