Run app script if cell in specific sheet changes value - google-apps-script

I want to run this script automatically whenever the value in cell A1 in sheet "NETRankingsRohdaten" changes. Thanks for help.
function NETsaveData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var reportSheet = ss.getSheetByName("NETRankingsRohdaten");
var recordsSheet = ss.getSheetByName("NETDatabase")
var NETsaveData = reportSheet.getRange("A2:F")
.getValues();
var lastRow = recordsSheet.getLastRow();
//copy data
recordsSheet.getRange(lastRow+ 1, 1, NETsaveData.length, 6)
.setValues(NETsaveData);
}

I believe your goal is as follows.
You want to run the script when the cell "A1" of "NETRankingsRohdaten" sheet is edited.
In this case, how about using OnEdit trigger? When OnEdit trigger is used, your script becomes as follows.
Modified script:
function onEdit(e) {
var range = e.range;
var reportSheet = range.getSheet();
if (reportSheet.getSheetName() != "NETRankingsRohdaten" || range.rowStart != 1 || range.columnStart != 1) return;
var ss = e.source;
var recordsSheet = ss.getSheetByName("NETDatabase")
var NETsaveData = reportSheet.getRange("A2:F").getValues();
var lastRow = recordsSheet.getLastRow();
recordsSheet.getRange(lastRow + 1, 1, NETsaveData.length, 6).setValues(NETsaveData);
}
In this case, when the cell "A1" of "NETRankingsRohdaten" sheet is edited, the script is run. So, when you directly run this function, an error occurs. Please be careful about this.
Note:
If you want to use NETsaveData(), you can also use the following script. In this case, your NETsaveData() is not modified. But when the cell "A1" of "NETRankingsRohdaten" sheet is edited, the script is run.
function onEdit(e) {
var range = e.range;
var reportSheet = range.getSheet();
if (reportSheet.getSheetName() != "NETRankingsRohdaten" || range.rowStart != 1 || range.columnStart != 1) return;
NETsaveData();
}
References:
Simple Triggers
Event Objects

Related

Run Google appscript on change of dropdonw

I am very new to Google Appscript and support of this community will really be appreciated. Using different posts on the Stakeoverflow community I had designed an appscript to copy and paste the data from one worksheet to another and this is working fine (the data of worksheet named Copy is paste in worksheet named Paste). I had also created a worksheet named Trigger and in that I had created a dropdown in cell A1, now I want my script to run every time when the dropdonw in this sheet is changed. I had checked the different solutions on this community but as am new to appscirpt could not design a perfect solution to my case. Below is the link to the sheet and my current script.
https://docs.google.com/spreadsheets/d/1xy5eN8_PHXi9RPWK_EKg99dylaDjQ9lcilrSW0GP4B0/edit#gid=0
function Referesh() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Copy");
var pasteSheet = ss.getSheetByName("Paste");
var source = copySheet.getRange(2,1,copySheet.getLastRow(),2);
var rub = copySheet.getRange(2,1,copySheet.getLastRow(),2);
var destination =
pasteSheet.getRange(pasteSheet.getLastRow()+1,2,copySheet.getLastRow(),2);
source.copyTo((destination), {contentsOnly: true});
rub.clearContent();
console.log(pasteSheet.getLastRow());
}
Any help on above will be appreciated.
I believe your goal is as follows.
You want to automatically run your script by changing the dropdown list of the cell "A1" of "Trigger" sheet.
In this case, how about using the OnEdit simple trigger as follows?
Modified script:
Please copy and paste the following script to the script editor of Spreadsheet and save the script. When you use this script, in this case, please change the dropdown list of the cell "A1" of "Trigger" sheet to "Run". By this, the script is run.
function onEdit(e) {
var sheetName = "Trigger";
var runScript = "Run";
var { range, source, value } = e;
var sheet = range.getSheet();
if (sheet.getSheetName() != sheetName || range.columnStart != 1 || range.rowStart != 1 || value != runScript) return;
var ss = source;
var copySheet = ss.getSheetByName("Copy");
var pasteSheet = ss.getSheetByName("Paste");
var source = copySheet.getRange(2, 1, copySheet.getLastRow(), 2);
var rub = copySheet.getRange(2, 1, copySheet.getLastRow(), 2);
var destination = pasteSheet.getRange(pasteSheet.getLastRow() + 1, 2, copySheet.getLastRow(), 2);
source.copyTo((destination), { contentsOnly: true });
rub.clearContent();
console.log(pasteSheet.getLastRow());
range.setValue("Refresh"); // By this script, the value of "Run" is changed to "Refresh".
}
Note:
It seems that there are 2 values of Run and Refresh in your dropdown list. Unfortunately, I couldn't know the trigger value. So, in this sample script, when the dropdown list is changed to Run, the script is run by the simple trigger. If you want to change this, please modify the above script.
When you run directly onEdit with the script editor, an error occurs because of no event object. So, please be careful about this.
If you want to ignore the trigger value, I think that the following script might be able to be used. In this case, the dropdown list is changed, the script is run.
function onEdit(e) {
var sheetName = "Trigger";
var { range, source } = e;
var sheet = range.getSheet();
if (sheet.getSheetName() != sheetName || range.columnStart != 1 || range.rowStart != 1) return;
var ss = source;
var copySheet = ss.getSheetByName("Copy");
var pasteSheet = ss.getSheetByName("Paste");
var source = copySheet.getRange(2, 1, copySheet.getLastRow(), 2);
var rub = copySheet.getRange(2, 1, copySheet.getLastRow(), 2);
var destination = pasteSheet.getRange(pasteSheet.getLastRow() + 1, 2, copySheet.getLastRow(), 2);
source.copyTo((destination), { contentsOnly: true });
rub.clearContent();
console.log(pasteSheet.getLastRow());
}
Reference:
Simple Triggers

Google Script - Unable to copy from one sheet to another

This is my first Google Script and I am coming from a VBA background so I have likely missed something obvious. I am attempting to copy from one sheet to another, some that is quite simple in VBA, but I am struggling with it and I dont understand what I am missing
The below code I would have though would copy a range in one sheet to another sheet. Not the whole range, just a section of it and only 1 row per an OnEdit()
I checked the ranges I am wanting to copy from and copy to using targetSheet.getRange(targetSheet.get1stNonEmptyRowFromBottom(1) + 1, 1,1,numColumns-1).activate(); & sheet.getRange(row, 1, 1, numColumns-1).activate(); and it selects the range I would expect
Currently the execution doesn't show any fails either
function onEdit(e) {
//This is sheet we will be copied to
const VALUE = ["LEAD","LANDSCAPE"];
//This is the column for the check box
const COLUMN_NUMBER = 25
//The main sheet that is being copied from
const MAIN_SHEET = 'Form Responses 1'
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var lead_or_landscape = sheet.getRange(row,20).getValue();
//This is so we dont run this by mistake on another cell edit or sheet
if((COLUMN_NUMBER == cell.getColumn() && MAIN_SHEET == sheet.getName && cell.isChecked() == true)
&& (lead_or_landscape == VALUE[0] || lead_or_landscape == VALUE[1])){
//copies row from current sheet to the specificed sheet (Lead or landscape)
var numColumns = sheet.getLastColumn();
var targetSheet = spreadsheet.getSheetByName(lead_or_landscape);
var target = targetSheet.getRange(targetSheet.get1stNonEmptyRowFromBottom(1) + 1, 1,1,numColumns-1);
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target());
}
}
Object.prototype.get1stNonEmptyRowFromBottom = function (columnNumber, offsetRow = 1) {
const search = this.getRange(offsetRow, columnNumber, this.getMaxRows()).createTextFinder(".").useRegularExpression(true).findPrevious();
return search ? search.getRow() : offsetRow;
};
You've to use parentheses in sheet.getName() and not use them in copyTo(target())
And you can use sheet.appendRow() method instead of copyTo(), that is easier.
function onEdit(e) {
//This is sheet we will be copied to
const sheets = ["LEAD","LANDSCAPE"];
//This is the column for the check box
const colNumber = 25;
//The main sheet that is being copied from
const mainSheet = 'Form Responses 1';
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var leadOrLandscape = sheet.getRange(row,20).getValue();
//This is so we dont run this by mistake on another cell edit or sheet
if(colNumber == cell.getColumn()
&& mainSheet == sheet.getName()
&& cell.isChecked() == true
&& sheets.includes(leadOrLandscape)){
//copies row from current sheet to the specificed sheet (Lead or landscape)
var numColumns = sheet.getLastColumn();
var targetSheet = spreadsheet.getSheetByName(leadOrLandscape);
targetSheet.appendRow(sheet.getRange(row, 1, 1, numColumns-1).getValues()[0])
}
}
I just took a quick look at your code, are you sure about this line?
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target());
it shouldn't rather be
sheet.getRange(row, 1, 1, numColumns-1).copyTo(target);

Google Script - onEdit(e) to trigger specific cell change

I'm currently using the below script to trigger an automatic cell edit. However, as a script basically runs every time any cell on the worksheet is edited, I wonder if there is a way to modify it so that it only works when let's say a cell B24 is edited or a range of cells from B24 - B30 are then trigger the script. It seems like an onEdit (e) function could be an answer but I'm struggling to modify the code accordingly. Would you guys be so kind and help?
function myfunction() {
var app = SpreadsheetApp;
var targetSheet = app.getActiveSpreadsheet().getSheetByName("ABC");
targetSheet.getRange(154,2).setValue("Bingo");
}
When using the below onEdit(e) I keep receiving an error message " target sheet not defined"
function onEdit(e) {
var range = e.range;
var spreadSheet = e.source;
var sheetName = spreadSheet.getActiveSheet().getName();
var column = range.getColumn();
var row = range.getRow();
if(sheetName == 'Harmonogram wpłat' && column == 2 && row == 24)
{
SpreadsheetApp.getActiveSpreadsheet().gatSheetByName('ABC').getRange('B154').setValue('Bingo');
}
}
Most likely, the error is due to the typo in the last line of your code.
gatSheetByName('ABC')
should be
getSheetByName('ABC')
See if that helps?
Modification points:
You have a typo as the other answer has already mentioned. It should be getSheetByName(name) and not gatSheetByName(name).
You want to execute the script when a cell in the range B24 - B30 is edited. To achieve that you need to modify the if condition to include that range:
if(sheetName == 'Harmonogram wpłat' && column == 2 && row > 23 && row<31)
SpreadsheetApp.getActiveSpreadsheet() can be replaced by spreadSheet since e.source is exactly the same thing.
Solution:
function onEdit(e) {
var range = e.range;
var spreadSheet = e.source;
var sheetName = spreadSheet.getActiveSheet().getName();
var column = range.getColumn();
var row = range.getRow();
if(sheetName == 'Harmonogram wpłat' && column == 2 && row > 23 && row<31){
spreadSheet.getSheetByName('ABC').getRange('B154').setValue('Bingo');
}
}

Sort by Named Range in Dropdown List

I am trying to create a sort function using Google Apps Script. I have about 20 columns in a Google sheet and want users to have the ability to sort the sheet by the click of a button rather than using the filter view because they keep on messing it up.
Rather than having 20 buttons for each column, I want one button with script which links to a dropdown list of Named Ranges being the same as the column headers.
Not sure if this is possible but this is a sample of my sheet:
I am struggling to get this script to work:
function sortByRangeName(rangeName){
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('Sheet 1');
var namedRange = ss.getRangeByName();
var startCol = namedRange.getColumn();
var lastCol = namedRange.getLastColumn();
var range = sheet.getRange('E1');
var value = range.getValue();
var rangeName = ss.getRangeByName(value);
var columnForSorting = (startCol <= dataRange.getLastColumn()) ? startCol : null;
if (namedRange && (startCol == lastCol) && columnForSorting) {
dataRange.sort({column: columnForSorting, ascending: false});
}
else {
throw new Error(Utilities.formatString("Range name: %s, startCol: %s, lastCol: %s, columnForSorting: %s", header, startCol, lastCol, columnForSorting));
}
}
This is a link to my spreadsheet:
Sample Spreadsheet
Try an Installable onEdit() with this function:
function sortByColumn(e) {
const sh=e.range.getSheet();
if(sh.getName()=='Sheet 1' && e.range.columnStart==5 && e.range.rowStart==1 && e.value) {
const hA=sh.getRange(2,1,1,sh.getLastColumn()).getValues()[0];
const col={};
hA.forEach(function(h,i){col[h]=i+1;});
const rg=sh.getRange(3,1,sh.getLastRow()-2,sh.getLastColumn());
rg.sort({column:col[e.value],ascending:true});
}
}
I believe your goal as follows.
You want to sort the range of "A3:E" with each column using the named ranges when the dropdown list at the cell "E1" on "Sheet 1" is selected.
Modification points:
In your script,
At var namedRange = ss.getRangeByName(), the argument is not used.
dataRange is not declared.
When above issues are resolved, the script works. But in this case, unfortunately, your goal cannot be achieve.
In order to achieve above goal, in this answer, the OnEdit event trigger is used.
In your dropdown list, it seems that there is the names including the space. Please be careful this. For this, I used trim().
Modified script:
Please copy and paste the following script to the script editor on the Google Spreadsheet. And, please select the dropdown list. By this, the values are sorted using the named ranges with the column selected by the dropdown list.
function onEdit(e) {
var range = e.range;
var sheet = range.getSheet();
if (sheet.getSheetName() != "Sheet 1" || range.getA1Notation() != "E1") return;
sheet.getDataRange().offset(2, 0).sort({
column: e.source.getRangeByName(e.value.trim()).getColumn(),
ascending: false
});
}
Note:
When the issues are removed from your script, it becomes as follows. I thought that knowing the modification points in your script might be help to study the script. So I also added this.
function sortByRangeName(rangeName){
rangeName = "Branch"; // This is a sample value
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('Sheet 1');
var namedRange = ss.getRangeByName(rangeName.trim()); // Modified
var startCol = namedRange.getColumn();
var lastCol = namedRange.getLastColumn();
var range = sheet.getRange('E1');
var value = range.getValue();
var rangeName = ss.getRangeByName(value);
var dataRange = sheet.getDataRange().offset(2, 0); // Added
var columnForSorting = (startCol <= dataRange.getLastColumn()) ? startCol : null;
if (namedRange && (startCol == lastCol) && columnForSorting) {
dataRange.sort({column: columnForSorting, ascending: false});
} else {
throw new Error(Utilities.formatString("Range name: %s, startCol: %s, lastCol: %s, columnForSorting: %s", header, startCol, lastCol, columnForSorting));
}
}
References:
Simple Triggers
Event Objects
getRangeByName(name)
trim()

Copying part of a row from one Google spreadsheet to another google spreadsheet based on a value in a cell?

I am trying to write a script to copy column B:K of a specific row based on if column 11 (K) has a "Y" on it.
I have scripts that move from one sheet to another within the same spreadsheet that work just fine but I am really struggling with one spreadsheet to another and only moving part of the row instead of the whole thing.
Below is the script thus far... would love help!
function onEdit() {
var sss = SpreadsheetApp.openById("15RWoaW8tRLVGOTDrZvBLJwx0beWEsV3x8pfwGe2zMfc").getSheetByName("2018 2 Week Snapshot for Jim"); // sss = source spreadsheet
var r = sss.getActiveRange();
if(sss.getName() == "2018 2 Week Snapshot for Jim" && r.getColumn() == 11 && r.getValue() == "Y") {
var row = r.getRow();
var numColumns = sss.getLastColumn();
var tss = SpreadsheetApp.openById("1dSJOOw_oLVc6Nf-C0MY9715tZGuh69kR6-j_m8EJ-So"); // tss = target spreadsheet
var targetSheet = tss.getSheetByName("Test Sheet"); // ts = target sheet
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
tss.getRange(row, 1, 1, numColumns).copyTo(target);
}
}
This is my new code, still struggling:
function onEdit() {
var sss = SpreadsheetApp.openById('15RWoaW8tRLVGOTDrZvBLJwx0beWEsV3x8pfwGe2zMfc'); // sss = source spreadsheet
var ss = sss.getSheetByName('2018 2 Week Snapshot for Jim'); // ss = source sheet
var SRange = ss.getRange("C:K");
if(ss.getName() == "2018 2 Week Snapshot for Jim" && SRange.getColumn() == 9 && SRange.getValue() == "y") {
var row = SRange.getRow();
var numColumns = ss.getLastColumn();
var tss = SpreadsheetApp.openById('1dSJOOw_oLVc6Nf-C0MY9715tZGuh69kR6-j_m8EJ-So'); // tss = target spreadsheet
var ts = tss.getSheetByName('Test Sheet'); // ts = target sheet
var target = ts.getRange(ts.getLastRow() + 1, 1);
ss.getRange(row, 1, 1, numColumns).SetValues(target);
}
}
When users put y or Y to column K at the sheet of 2018 2 Week Snapshot for Jim on the active spreadsheet, you want to copy only the values of B:K to the last row at the sheet of "Test Sheet" on the spreadsheet of 1dSJOOw_oLVc6Nf-C0MY9715tZGuh69kR6-j_m8EJ-So.
Spreadsheet of 15RWoaW8tRLVGOTDrZvBLJwx0beWEsV3x8pfwGe2zMfc is the active spreadsheet.
If my understanding is correct, how about this modification?
Modification poonts:
set of setValues() is lower case.
values of setValues(values) is 2 dimentional array.
The range for setValues(values) is the range for putting the values.
When you use onEdit(), you can use an event object.
The script which reflected above is as follows.
Modified script:
function myFunction(e) {
var sourceSheetName = "2018 2 Week Snapshot for Jim";
var destinationSpreadsheetId = "1dSJOOw_oLVc6Nf-C0MY9715tZGuh69kR6-j_m8EJ-So";
var destinationSheetName = "Test Sheet";
if (e.source.getSheetName() == sourceSheetName && e.range.getA1Notation()[0] == "K" && e.value.toUpperCase() == "Y") {
var sourceValues = e.source.getRange("B:K").getValues().filter(function(e){return e.filter(String).length > 0});
var tss = SpreadsheetApp.openById(destinationSpreadsheetId);
var ts = tss.getSheetByName(destinationSheetName);
ts.getRange(ts.getLastRow() + 1, 1, sourceValues.length, sourceValues[0].length).setValues(sourceValues);
}
}
Note :
Before you use this script, please install myFunction() as an installable trigger.
References:
Event Objects
Installable Triggers
setValues()
If I misunderstand your situation, I'm sorry.