I have the script below where some cells are protected because they contain formula but I can script linked to buttons that when executed, it updates the cell values in these protected cells, this is fine if you are the sheet owner but if you are not you get a error saying 'You are editing protected cells....'
I have seen some solutions where the script has been deployed as a web app and then set so it always runs as the owner but can't get this working for my use case, I deployed and set as to always run as me but this only seems like half the solution?
My code is below:
//
// Save Data
function submitData() {
var SPREADSHEET_NAME = "Data";
var SEARCH_COL_IDX = 0;
var RETURN_COL_IDX = 0;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Tool"); //Form Sheet
var datasheet = ss.getSheetByName("Data"); //Data Sheet
var str = formSS.getRange("A10").getValue();
var values = ss.getSheetByName(SPREADSHEET_NAME).getDataRange().getValues();
for (var i = 0; i < values.length; i++) {
var row = values[i];
if (row[SEARCH_COL_IDX] != str ) {
//SpreadsheetApp.getUi().alert(' "Dmp #' + formSS.getRange("A4").getValue() + ' "');
// return row[RETURN_COL_IDX];
//} else {
//Input Values
var values1 = [[formSS.getRange("A10").getValue(),
formSS.getRange("B10").getValue(),
formSS.getRange("C10").getValue(),
formSS.getRange("D10").getValue(),
formSS.getRange("E10").getValue(),
formSS.getRange("F10").getValue(),
formSS.getRange("G10").getValue(),
formSS.getRange("H10").getValue(),
formSS.getRange("I10").getValue(),
formSS.getRange("J10").getValue(),
formSS.getRange("K10").getValue()]];
var values2 = [[formSS.getRange("A10").getValue(),
formSS.getRange("B10").getValue(),
formSS.getRange("C10").getValue(),
formSS.getRange("D10").getValue(),
formSS.getRange("E10").getValue(),
formSS.getRange("F10").getValue(),
formSS.getRange("G10").getValue(),
formSS.getRange("I10").getValue(),
formSS.getRange("J10").getValue(),
formSS.getRange("K10").getValue()]];
values2[0].forEach(function(val) {
if (val === "") {
throw new Error("Please fill in Project, Category, Subsystem, Description and Created By Fields.");
}
})
// Save New Data
datasheet.getRange(datasheet.getLastRow()+1, 1, 1, 11).setValues(values1);
SpreadsheetApp.getUi().alert(' New Record Created ');
formSS.getRange("D10").clearContent();
formSS.getRange("E10").clearContent();
formSS.getRange("F10").clearContent();
formSS.getRange("G10").clearContent();
formSS.getRange("H10").clearContent();
formSS.getRange("I10").clearContent();
formSS.getRange("J10").setValue(new Date())
return row[RETURN_COL_IDX];
}
}
}
//=========================================================
// Clear form
function clearCell() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Tool"); //Form Sheet
formSS.getRange("D10").clearContent();
formSS.getRange("E10").clearContent();
formSS.getRange("F10").clearContent();
formSS.getRange("G10").clearContent();
formSS.getRange("I10").clearContent();
formSS.getRange("J10").setValue(new Date())
return true ;
}
//=====================================================================
var SPREADSHEET_NAME = "Data";
var SEARCH_COL_IDX = 0;
var RETURN_COL_IDX = 0;
function searchStr() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Tool"); //Form Sheet
var str = formSS.getRange("F4").getValue();
var values = ss.getSheetByName(SPREADSHEET_NAME).getDataRange().getValues();
for (var i = 0; i < values.length; i++) {
var row = values[i];
if (row[SEARCH_COL_IDX] == str) {
formSS.getRange("A6").setValue(row[0]) ;
formSS.getRange("B6").setValue(row[1]);
formSS.getRange("C6").setValue(row[2]);
formSS.getRange("D6").setValue(row[3]);
formSS.getRange("E6").setValue(row[4]);
formSS.getRange("F6").setValue(row[5]);
formSS.getRange("G6").setValue(row[6]);
formSS.getRange("H6").setValue(row[7]);
formSS.getRange("I6").setValue(row[8]);
formSS.getRange("J6").setValue(row[9]);
return row[RETURN_COL_IDX];
}
}
}
//===================================================================
function rowDelete() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Tool"); //Form Sheet
var datasheet = ss.getSheetByName("Data"); //Data Sheet
var ui = SpreadsheetApp.getUi();
var response = ui.alert(
'Are you sure you want to delete this record?',
ui.ButtonSet.YES_NO);
// Process the user's response.
if (response == ui.Button.YES) {
var str = formSS.getRange("F4").getValue();
var values = ss.getSheetByName(SPREADSHEET_NAME).getDataRange().getValues();
for (var i = 0; i < values.length; i++) {
var row = values[i];
if (row[SEARCH_COL_IDX] == str) {
var INT_R = i+1
datasheet.deleteRow(INT_R) ;
formSS.getRange("A6").clearContent();
formSS.getRange("B6").clearContent();
formSS.getRange("C6").clearContent();
formSS.getRange("D6").clearContent();
formSS.getRange("E6").clearContent();
formSS.getRange("F6").clearContent();
formSS.getRange("G6").clearContent();
formSS.getRange("H6").clearContent();
formSS.getRange("I6").clearContent();
formSS.getRange("J6").clearContent();
return row[RETURN_COL_IDX];
}
}
}
}
//====================================================================
function updateData() {
var SPREADSHEET_NAME = "Data";
var SEARCH_COL_IDX = 0;
var RETURN_COL_IDX = 0;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Tool"); //Form Sheet
var datasheet = ss.getSheetByName("Data"); //Data Sheet
var str = formSS.getRange("A6").getValue();
var values = ss.getSheetByName(SPREADSHEET_NAME).getDataRange().getValues();
for (var i = 0; i < values.length; i++) {
var row = values[i];
if (row[SEARCH_COL_IDX] == str) {
var INT_R = i+1
formSS.getRange("J6").setValue(new Date())
var values1 = [[formSS.getRange("A6").getValue(),
formSS.getRange("B6").getValue(),
formSS.getRange("C6").getValue(),
formSS.getRange("D6").getValue(),
formSS.getRange("E6").getValue(),
formSS.getRange("F6").getValue(),
formSS.getRange("G6").getValue(),
formSS.getRange("H6").getValue(),
formSS.getRange("I6").getValue(),
formSS.getRange("J6").getValue()]];
var values2 = [[formSS.getRange("A6").getValue(),
formSS.getRange("B6").getValue(),
formSS.getRange("C6").getValue(),
formSS.getRange("D6").getValue(),
formSS.getRange("E6").getValue(),
formSS.getRange("F6").getValue(),
formSS.getRange("G6").getValue(),
formSS.getRange("I6").getValue(),
formSS.getRange("J6").getValue()]];
values2[0].forEach(function(val) {
if (val === "") {
throw new Error("Please fill in Revisions, Project, Category, Subsystem, Description and Updated By Fields.");
}
})
datasheet.getRange(INT_R, 1, 1, 10).setValues(values1);
formSS.getRange("A6").clearContent();
formSS.getRange("B6").clearContent();
formSS.getRange("C6").clearContent();
formSS.getRange("D6").clearContent();
formSS.getRange("E6").clearContent();
formSS.getRange("F6").clearContent();
formSS.getRange("G6").clearContent();
formSS.getRange("H6").clearContent();
formSS.getRange("I6").clearContent();
formSS.getRange("J6").clearContent();
formSS.getRange("E4").clearContent();
SpreadsheetApp.getUi().alert(' Record Updated ');
return row[RETURN_COL_IDX];
}
}
}
There are several posts about this, I'll paste a response from one from yesterday. What I recommend specifically in your case is to run the script when there's an edit bye the user in a certain cell. For example a Tickbox, or a Drop-down menu (in a cell) that allows the user to select which function to run:
If you already have an onEdit function working, that's a simple trigger run by whoever is editing the sheet. Meaning that if you protect column A, it won't be editable by that simple trigger because the user won't have permissions
In order to work this out, I encourage you to protect your column as explained here, change your name function or extract in a new function the part about this specific code you're talking about; and set an installable trigger that runs on event. This way it'll be run as you used to but as it came from your own account. As you have permissions for editing ColA the timestamp will be set by the installable trigger but the other user won't be able to edit it since he/she doesn't have the permissions. Try it and let me know!
everyone!
I'm trying to write a script where the cell G3 on the sheet 'ref view' will change to 'Yes' if the cell D9 on 'view' contains 'BP' when I run it. The problem is that the execution is completed without errors but when I try to test it nothing happens.
This is the code:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var sheetInfo = ss.getSheetByName('ref view')
var data = sheet.getDataRange().getValues();
var rangeView = ss.getRange('View!D9');
var cell = ss.getRange('ref view!G3');
var range = rangeView;
for(var i=0; i<data.length; i++) {
if(rangeView == 'BP') {
sheet.getRange(cell).clear().setValue('Yes');
}
}
} ```
Try it this way:
function one() {
var ss = SpreadsheetApp.getActive();
var sh1 = ss.getActiveSheet();
var vs1 = sh1.getDataRange().getValues();
var sh2 = ss.getSheetByName('ref view')
var sh3 = ss.getSheetByName('view');
var sh3D9v = sh3.getRange('D9').getValue();//value
var sh2G3r = sh2.getRange('G3');//Range
for(var i=0; i<vs1.length; i++) {
if(sh3D9v == 'BP') {
sh1.getRange(sh2G3r).setValue('Yes');
}
}
}
Be aware that a range does not return a value without the use of a getValue() or a getValues();
I have the below which hides all tabs but the current and exports to a pdf in a specified drive folder. Then unhides all, cycles to the next and repeats. Works fine but want to be able to scale the tab to fit to one page.
Other methods using URLfetchapp allow for scaling but it causes time outs by too many requests.
function Exportpdf() {
var spreadsheet = SpreadsheetApp.getActive();
nextSheet()
exportSheet()
if (SpreadsheetApp.getActiveSheet().getName()=='Data'){}
else {Exportpdf()}
};
function nextSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var numSheets = ss.getSheets().length; // number of sheets
var activeSheetIndex = ss.getActiveSheet().getIndex() - 1; // see below
var newSheetIndex = (activeSheetIndex + 1) % numSheets; // add 1; wrap around
ss.setActiveSheet(ss.getSheets()[newSheetIndex]);
}
function exportSheet() {
var actualSheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].getSheetName() !== actualSheetName) {
sheets[i].hideSheet()
}
}
var pdfName = (SpreadsheetApp.getActiveSpreadsheet().getName() + " - " + SpreadsheetApp.getActiveSheet().getName());
var newFile = DriveApp.createFile(ss.getBlob().getAs('application/pdf').setName(pdfName));
for (var i = 0; i < sheets.length; i++) {
sheets[i].showSheet()
}
newFile.moveTo(DriveApp.getFolderById("11ZLhYZgpLuq5VWB90TdGbDrOUzP2SUlr"));
}
I am working on merging multiple tabs on a google sheet and creating one master sheet.
function combinesheets()
{
var doc = SpreadsheetApp.getActiveSpreadsheet();
var sheets = doc.getSheets();
var outSheet = doc.getSheetByName("combinesheets");
for (i in sheets){
if (sheets[i].getSheetName() == "sheet1") or (sheets[i].getSheetName() == "sheet2")
{
var data = getRowsData(sheets[i]);
insertData(outSheet, data);
}
}
}
Using the above script I am getting ReferenceError: getRowsData is not defined.
A line is in the wrong place there Cooper, it won't work.
Try this:
function combinesheets()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var allsheets = ss.getSheets();
var combineSht = ss.getSheetByName("combinesheets");
for (var i=0; i<allsheets.length; i++)
{
var shtName = allsheets[i].getName();
if (shtName != 'combinesheets')
{
var sht = ss.getSheetByName(shtName);
var shtrng = sht.getDataRange();
var shtrngA = shtrng.getValues();
for(var j=0;j<shtrngA.length;j++)
{
combineSht.appendRow(shtrngA[j]);
}
}
}
SpreadsheetApp.flush();
}
I rewrote the function for you and it works on my spreadsheet. It's a little slow but it gets the job done.
function combinesheets()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var allsheets = ss.getSheets();
var combineSht = ss.getSheetByName("combinesheets");
for (var i=0; i<allsheets.length; i++)
{
if (shtName != 'combinesheets')
{
var shtName = allsheets[i].getName();
var sht = ss.getSheetByName(shtName);
var shtrng = sht.getDataRange();
var shtrngA = shtrng.getValues();
for(var j=0;j<shtrngA.length;j++)
{
combineSht.appendRow(shtrngA[j]);
}
}
}
SpreadsheetApp.flush();
}
I want to identify equal rows in two different sheets on same spreadsheet. I tried below code, it doesn't work.
function getMyEqualRows()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheets()[0];
var sheet2 = ss.getSheets()[1];
var sheetOneValues = sheet1.getRange('A1:G20').getValues();
var sheetTwoValues = sheet2.getRange('A1:G20').getValues();
var equalRows = [];
for (var i = 0; i <= sheetOneValues.length; i++) {
for(var j = 0; j <= sheetTwoValues.length; j++){
if(sheetOneValues[i] == sheetTwoValues[j]) {
equalRows.push(sheetOneValues[i]);
}
}
return equalRows;
}
}
You can't compare two arrays for equality with ==. Instead you can use .join() method. It concatenates all elements in these arrays to a string. This check string arrays for equality. I'm not sure if this is the best way.
function getMyEqualRows()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheets()[0];
var sheet2 = ss.getSheets()[1];
var sheetOneValues = sheet1.getRange('A1:G20').getValues();
var sheetTwoValues = sheet2.getRange('A1:G20').getValues();
var equalRows = [];
for(var i in sheetOneValues)
{
var anEqualRow = false;
for(var j in sheetTwoValues)
{
if(sheetOneValues[i].join() == sheetTwoValues[j].join()){
anEqualRow = true;
}
}
if(anEqualRow){
equalRows.push(sheetOneValues[i]);
}
}
return equalRows;
}
Hope this would work!