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!
Row 1 in both Sheet 1 and Sheet 2 are frozen, with column names.
Once I have a working script, I will setup a corresponding onChange trigger to execute the script.
Due to the way new data containing rows are added to Sheet 1, the script itself cannot be written with onChange/onEdit syntax, I just need a function that works, and I'll use an onChange trigger to execute it.
Step 1:
Sheet 1 - a new data containing row was added (Row 2).
A
B
C
1
City
State
Country
2
Los Angeles
CA
USA
Sheet 2 - the data from Sheet 1 - Row 2 should be copied to the next available row, which in this case would be Row 2.
A
B
C
1
City
State
Country
2
Los Angeles
CA
USA
Step 2:
Sheet 1 - after the data from Row 2 has been copied to the next available row in Sheet 2, then Row 2 should be cleared.
A
B
C
1
City
State
Country
2
blank
blank
blank
Step 3:
Sheet 1 - a new data containing row was added (Row 2).
A
B
C
1
City
State
Country
2
Miami
FL
USA
Sheet 2 - the data from Sheet 1 - Row 2 should be copied to the next available row, which in this case would be Row 3.
A
B
C
1
City
State
Country
2
Los Angeles
CA
USA
3
Miami
FL
USA
Step 4:
Sheet 1 - after the data from Row 2 has been copied to the next available row in Sheet 2, then Row 2 should be cleared.
A
B
C
1
City
State
Country
2
blank
blank
blank
...and so on
Sheet 1 should only ever have two rows. Row 1 for the column names and Row 2, which will be blank to start, then filled with data (which should then be copied over to Sheet 2), then cleared so that it is blank again, repeat.
Sheet 2's row count should be continually growing, one by one, as individual data containing rows populate into Sheet 1 - Row 2 over time and get copied over.
The incoming data that fills Sheet 1 - Row 2 comes from an external app, I'm never manually entering data into that sheet/row. The incoming data fills all columns in Sheet 1 - Row 2, all at once.
Try
function onOpen() {
SpreadsheetApp.getUi().createMenu('⇩ M E N U ⇩')
.addItem('👉 Transfer data form Sheet1 to Sheet2', 'moveData')
.addToUi();
}
function moveData() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var rng = ss.getSheetByName('Sheet1').getRange('A2:C2')
ss.getSheetByName('Sheet2').getRange(ss.getSheetByName('Sheet2').getLastRow()+1,1,1,3).setValues(rng.getValues())
rng.clearContent()
}
I have google sheet collecting data from 7 other sheets of the same structure. Each of the sheet has its own owner, they fill the info and the final column is the "approved" col that they leave empty.
Now what I want to do is to be able to approve those rows from the master sheet.
Master sheet collects the info from the other sheets using query and multiple importrange functions and filter out rows that have null value in the first column or have a "approved" column = 'yes'.
So what I want to happen is approving those rows from the master and as soon as that happens they should disappear from master. What's the best way to create communication that communication? This is probably important - combination of 3 columns would create a unique id of the row.
Sheet 1
Date Name Sheet Approved
2020-01-01 A 1
2020-01-02 B 1 Yes
Sheet 2
Date Name Sheet Approved
2020-01-01 C 2
2020-01-02 D 2
Sheet 3
Date Name Sheet Approved
2020-01-01 E 3 Yes
2020-01-02 F 3
Master
Date Name Sheet Dummy* Approved
2020-01-01 A 1
2020-01-01 C 2
2020-01-02 D 2
2020-01-02 F 3
*Using dummy to filter out rows already approved
and now as soon as I add approved in Master for name A, I want that cell to change in sheet 1 (and using my query function filter it would disappear from the Master)
Master
Date Name Sheet Dummy* Approved
2020-01-01 A 1 Yes
2020-01-01 C 2
2020-01-02 D 2
2020-01-02 F 3
Sheet 1
Date Name Sheet Approved
2020-01-01 A 1 Yes
2020-01-02 B 1 Yes
Master
Date Name Sheet Dummy* Approved
2020-01-01 C 2
2020-01-02 D 2
2020-01-02 F 3
Any ideas or directions?
Per suggestions - added links to sheets I already have (limited to 2 owners since it doesn't matter atm)
Master
https://docs.google.com/spreadsheets/d/1a6XoQvmGNSq3D0t5eaVXHoYBmSTVhn4T7GUMdmscWvE/edit?usp=sharing
Owner1
https://docs.google.com/spreadsheets/d/1hjs7hoKqDEsGEdyMmWRlrlBer4w7dcV4TH8I1FSvwjk/edit?usp=sharing
Owner2
https://docs.google.com/spreadsheets/d/1WJ1LiZixmrtla3BFAaUOWyQ_SfFfZIT-I38138X4cNE/edit?usp=sharing
I am sure many solutions exist, my thought would be to have the other 7 sheets import to a tab in the owner's sheets. Then in each owner's sheet for the Approved cell write a query to return the Approved column from the imported sheet using the combination of 3 columns that create the unique id of the row.
Update:
I am working with the shared sheets you shared and I added a tab to the Owner 1 sheet to import the data from the master. I then added a formula in F2 for sheet1:
=if(isna(query(MasterImport!$A$1:$F,"SELECT F WHERE A = date '"&TEXT(A3,"yyyy-mm-dd")&"' AND B ='"&B3&"' AND C = '"&C3&"' LABEL F ''",1)),"",query(MasterImport!A2:F,"SELECT F WHERE A = date '"&TEXT(A3,"yyyy-mm-dd")&"' AND B ='"&B3&"' AND C = '"&C3&"' LABEL F ''",1))
However, it seems to be creating a circular reference of sorts and Sheets keeps showing and removing so this approach will not work.
So, I added a tab to the master sheet importing all owner sheets where the date col is not null and changed the query range in sheet1 to the OwnerImports tab.
=QUERY(OwnerImports!A2:F, "select * where F is null",0)
I also changed the formula in the owner sheet to query the OwnerImports tab instead of Sheet1.
=if(isna(query(MasterImport!$A$1:$F,"SELECT F WHERE A = date '"&TEXT(A3,"yyyy-mm-dd")&"' AND B ='"&B3&"' AND C = '"&C3&"' LABEL F ''",1)),"",query(MasterImport!A2:F,"SELECT F WHERE A = date '"&TEXT(A3,"yyyy-mm-dd")&"' AND B ='"&B3&"' AND C = '"&C3&"' LABEL F ''",1))
I believe it is working. You would mark the row Accepted in the OwnerImports tab and it is reflected in the Sheet1 tab.
There does seem to be some lag on the owner sheet, refreshing the sheet helps. This was a hairy one!
Similar to Auto fill a column in Google Sheets with formulas when new rows are added where I have a Zapier that auto-populates a specific worksheet in a google sheet.
I have Columns A through F. The F column has an associated formula to it (referencing the C column in the same row) that I'd like to have applied when a new row is auto-generated above it.
Note: I can't use arrayformula because Zapier will assume that the row has content and will open a new row above it
Example of google sheet
A B C D E F G
1 Name Email Lecture Date Quiz Score Code
2 Neil foo#bar 2 5/5 4 Pass (formula ref C2)
3 Rose bar#foo 10 4/5 5 Failed (formula ref C3)
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.