Copying columns with a specific value from one sheet to another sheet - google-sheets

I am using Google Docs Sheet for editing
I want to find out a way to copy the "Name" and "Variety" columns into another sheet where the "Germination %" column is 0.
Is there a way to do it automatically?

An apps script solution, using the onEdit() trigger or a time-based one. Depending on the size of the Sheet I'd recommend using the time based one.
Eg.
function onEdit( e ){
rang = e.range.getRange();
if( rang.getColumn() == 9 && rang.value() == "0" )
SpreadshettApp.openById(newId).appendRow( e.source.getRange(rang.getRow(), 1, 1, -1).getValues() );
}
Or you could display the results using the FILTER function.

Related

QUERY IMPORTRANGE while keeping row position

I have two spreadsheets, one client facing and one internal facing, that use IMPORTRANGE and QUERY + IMPORTRANGE to display data between one another.
The internal sheet is used to write copies for social media posts, quality check them and give approval. Once approval is given the client sheet needs to update to show the copies on the identically named pages AND in the correct rows.
Approval is given by ticking a checkbox in the internal sheet and the QUERY + IMPORTRANGE formula then pulls that into the client sheet. However, my abilities stop where I have to display this in the correct row position no matter which of the tickboxes are checked.
=iferror(QUERY(IMPORTRANGE("https://docs.google.com/spreadsheets/d/1CIXhcuTigYbggmPjBKpvnH7P-cjBDQfSIcmKN6_0T5M/edit#gid=2018991957","Cloud in FS Survey!C2:N"),"SELECT Col1, Col2, Col3, Col4, Col5, Col6 WHERE Col11 = TRUE"),"No copies approved")
I've seen some discussions of having a second sheet for of the categories (there are 8 in the non-redacted document) and using VLOOKUP to match an ID to the imported row of data, hence I've created 'Row' columns in all tabs on both sheets with the unique row number. However, I want to avoid having hidden tabs in the client facing sheet where they can be revealed by the client.
Any assistance would be appreciated.
Many thanks,
Mark
There are 2 ways to deal with it. If you a add serial number in sheet 1 where approvals are given, you may add another element to your query by adding order by serial no. column ASC
Else you could do the same with order by date column ASC
This way new additions will add below the imported data because they will always be in chronology and not mess up the order of older data.
Having direct importranges where static data exists is always risky.
Alternately, you could also use ID thing without creating an additional hidden sheet, direct vlookups with importrange nested inside the vlookup.
For example, =arrayformula(vlookup(search key, importrangexxx, index, false)
The best solution would be to have a hidden sheet. But all of the above can be decent alternate if you're not dealing with thousands of rows.
If you don't want to use helper sheet or column, you can use Apps Script and onEdit Trigger.
Using onEdit Trigger, you can run a function automatically when a user click the checkbox. Inside that function is a list of commands that will write data to the client side.
Example:
To start with Apps Script:
Go to Tools -> Script Editor.
In your script editor, delete the code in Code.gs
Paste the code provided below.
Click Save.
Code:
function showToClientSide(e) {
var val = e.value;
var range = e.range;
var row = range.getRow();
var col = range.getColumn();
var sheet = range.getSheet();
var clientSS = SpreadsheetApp.openById("Insert Client Sheet ID here")
if(val == "TRUE" && row > 1 && col == 13){ // check if checkbox is checked
var data = sheet.getRange(row, 3, 1, 9).getValues(); //get data from internal
var sh = clientSS.getSheetByName("Cloud in FS Survey"); //client sheet
sh.getRange(row, 3, 1, 9).setValues(data); //write internal data to client
}else if(val == "FALSE" && row > 1 && col == 13){
var sh = clientSS.getSheetByName("Cloud in FS Survey"); //client
sh.getRange(row, 3, 1, 9).clearContent(); //delete data when unchecked
}
}
To setup your Installable Trigger (onEdit):
In the left menu of your Apps Script, click Triggers
Click Add Trigger
Copy the setup below.
Save and Authorize the script.
Testing:
Internal Sheet:
Client Sheet:
Checkbox checked:
Internal:
Client:
Checkbox unchecked:
Internal:
Client:
References:
Installable Triggers
Event Objects
Class Range
Class Sheet

Is is possible in google sheet to protect certain columns, but allow rows to be added/removed?

I'm using arrayformulas to populate certain columns of my sheet, depending on values in other sheets. Occasionally users accidentally will put some value in these columns, and this will stop arrayformula from working. I want to protect these columns, but still allow adding/editing/deleting rows.
Consider this example spreadsheet: I want Id row to be protected, but allow addition/deletion of rows.
https://docs.google.com/spreadsheets/d/1Dnj7OE5XZL09gllHVwPgv-5GRoM-lxVCxTCI_-kURdM/edit#gid=0
Is this possible at all with Google Sheets?
You can't directly disable input but you can use Data Validation instead
By going to Data > Data Validation and filling it with the following:
Cell range: YourSheet!C2:C
Criteria: Custom formula is - =C2:C = A2:A & "["&B2:B&"]"
On invalid data: Reject input
Appeareance: Optional message
Once you've done this, try to fill some cell in the C column and you'll see a message: There was a problem - Your optional message
As a different approach you can use Apps Script Simple Triggers
By going to Tools > Script Editor and copying the following code:
function onEdit(e) {
var column = e.range.getColumn();
var sheet = SpreadsheetApp.getActiveSheet();
if (column === 3) {
e.range.setValue("");
}
}
Which is more like an "undo" function.
References
Simple Triggers
Event Objects > onEdit
rows could be added by brute force with this formula:
=ARRAYFORMULA(ROW(INDIRECT("1:"&ROWS(A:A)+1)))
but escalation cant be controlled

Google Sheets - Pushing a row to a second spreadsheet based on a value being entered

I'm new to this,
I have 2 google spreadsheets:
Spreadsheet A: The active sheet Containing multiple tabs with information to be Pushed to B.
Spreadsheet B: A spreadsheet with a single tab. The same headers and structure as spreadsheet A.
Based on the user selecting the answer "Yes" in the first column of any of the 1 tabs in Spreadsheet A, I would like that entire row to move over to Spreadsheet B.
I have modified a script that works on a single spreadsheet (ie moving rows from tab to tab) to attempt to get it to work between spreadsheets:
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var tss = SpreadsheetApp.openById('B').getSheetByName('Sheet 1');
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(r.getColumn() == 1 && r.getValue() == "Yes") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var target = tss.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
}
}
Probably needless to say, this yields no result. Having searched through a number of posts and forums I only see individuals posting about how to move rows between tabs but not between entirely separate spreadsheets. Is it even possible to do this? If so, what am I doing wrong in the script?
Thank you so much for anyone who takes the time to assist.
Anthony
Following a dialogue with the OP in the comments section, it was indicated that the original spreadsheet did not to be kept secret.
Consequently, the desired functionality can be provided by using a combination of IMPORTRANGE() and QUERY() in the spreadsheet with no need to use Google App Script. For instance,
=QUERY(IMPORTRANGE(url,range),"select A where B matches 'Yes'") or similar
This imports data from a second spreadsheet and then the QUERY() function acts as a way of filtering the imported range by certain criteria.
Once the imported range is authorised, the editors of the spreadsheet can access it by, e.g. removing or modifying the query. You could prevent this by protecting that particular cell, if needed.

Conditional formatting on Multiple Rows based on cell value

In my Google Form, I have custom formatting setup for my dropdown lists that will highlight the entire row based on the value chosen.
Custom formula is
=$B3="Highlight: 1 Row"
But how can I highlight multiple rows if I wanted to?
Google Sheet Example: Highlight Multiple Rows
Screenshot Example:
UPDATE (01-26-2017)
The purpose of this "multi row" feature will be used inside a more robust spreadsheet that generates Google Forms from a Google Sheet. For this particular use case, there are many different "dropdowns" for the user to choose from that control where the user can type. This can quickly become hard to navigate the longer your sheet becomes. The best way it seems to handle this is through conditional formatting.
Highlight Multiple Rows (Test Google Sheet)
Create Form From Sheet (YouTube Tutorial)
Create Form From Sheet (Google Sheet)
Create Form From Sheet (Google Script)
Use this custom formula
=$B$3="Highlight: 2 Row"
Make sure the range you want this rule to apply to, is two rows long
e.g: B3:Z4
Now when "Highlight: 2 Row" is entered in B3 two rows should be highlighted.
UPDATE:
Below is a google script that should work
function onEdit(e) {
var sh, colors, rows, rowsBefore;
sh = e.source.getActiveSheet();
colors = ["#fff2cc", "#fce5cd", "#d9ead3", "#cfe2f3"];
if (sh.getName() !== 'Example' || e.range.columnStart !== 2 || e.range.rowStart < 8 || typeof e.value == 'object') return;
rowsBefore = e.oldValue ? e.oldValue.replace(/\D/g, '') : 1;
rows = e.value.replace(/\D/g, '');
sh.getRange(e.range.rowStart, 4, rowsBefore, sh.getLastColumn()).setBackground("white")
sh.getRange(e.range.rowStart, 4, rows, sh.getLastColumn()).setBackground(colors[rows - 1])
}
Change sheet name (and range) to suit. Note that this script is on a simple onEdit trigger: it will be fired when an edit is done in col B of the sheet 'Example'. Do not try to run the script by clicking the 'play' button in the script editor as it will return an error. See if that helps ?

arrayformula that can "skip" rows

I need to introduce functionality into a google spreadsheet that will allow the user to edit the result of an array formula. The reason for the requirement is that an ARRAYFORMULA sets a default value for a group of cells, but the user sometimes needs to overwite these defaults. I'd like to know if this is even remotely possible.
example:
Row(#)|Array_1 |Array_2
------------------------------------
1 |a |=arrayformula(Array_1)
2 |b |""
3 |c |""
4 |d |""
So all rows in Array_2 are populated by an array formula. However the user wants to go directly to the second cell in Array_2 and change its value. Of course, by design ARRAYFORMULA will break. Is there some way to modify ARRAYFORMULA, so that it will simply skip over the cell that the user has edited and continue on its way as if nothing has happeded?
I realize this is an old problem but I was searching for this today and made a script that works for me.
This script puts a formula in an adjacent cell when a cell is edited in the second column. This way you can just overwrite the formula if you need to input something manually and you don't need to have the formulas go into all of the rows beforehand. I had people accidentally edit the formula and mess it up most of the time when they were pre-filled, so this works better for me.
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetList = ["Sheet1","Sheet2","Sheet3"]; // list of sheets to run script on
for (i = 0; i < sheetList.length; i++) {
var sheetName = ss.getSheetByName(sheetList[i]);
// only runs if sheet from sheetList is found
if (sheetName != null) {
var aCell = sheetName.getActiveCell();
var col = aCell.getColumn();
var adjacentCell = aCell.offset(0, -1);
var formula = 'INPUT FORMULA HERE'; // put the formula you want in the adjacentCell here. Don't use it in an arrayformula
// only runs if active cell is in column 2, if the adjacentCell is empty, and if the active cell is not empty(otherwise it runs if you delete something in column 2)
if(col==2 && adjacentCell.getValue()=="" && aCell.getValue()!="") {
adjacentCell1.setValue(formula);
}
}
}
}
Will changing the value not throw out the output of the remaining formulas?
If not, you could set up 2 new tabs: one which will receive the user over-ride values, and another "reflection" tab which you populate with
IF(tabOverride!Rx:Cy, tabOverride!Rx:Cy, tabArray!Rx:Cy)
basically the new tabs are cloned layouts of your array tab, creating an override input layer, plus a presentation layer that uses the IF('override value exists', 'then show override', 'else show array out put') logic to return the desired values.
hope that makes sense!

Resources