简体   繁体   中英

Google Sheets App Script Edit Protected Cell or Object Error

I have a Google Sheets script that I've been using for the past 2+ years that grabs a chunk of data and transcribes it into a pair of tally sheets, then clears the cells that had been filled creating said chunk of data so the process can be started over. This is used for an inventory calculation system. The script has reliably worked up until roughly 3 weeks ago, but I now encounter an edit protection error when users with limited access to the sheet attempt to run the script. None of the editable cells/ranges reference in the script are locked to any user, but the sheet does have protection on cells I do not want anybody to make inadvertent changes to.

The script is:

function CopyErADD() {
 var sss=SpreadsheetApp.getActiveSpreadsheet();
 var sheet = sss.getSheetByName('ADDER'); //Entry Sheet
 var rangeIn = sheet.getRange('B32:N45'); //Range to copy into "Incoming" sheet
 var dataIn = rangeIn.getValues();
 var ts = sss.getSheetByName('Incoming'); //Tally sheet in
 
  ts.getRange(ts.getLastRow()+1, 1, dataIn.length, dataIn[0].length).setValues(dataIn);

 var rangeOut = sheet.getRange('B48:O54'); //Range to copy into "Outgoing" sheet
 var dataOut = rangeOut.getValues();
 var tss = sss.getSheetByName('Outgoing'); //Tally sheet out
 
  tss.getRange(tss.getLastRow()+1, 1, dataOut.length, dataOut[0].length).setValues(dataOut);

   SpreadsheetApp.flush() // NEWLY ADDED PER METAMAN'S SUGGESTION

  sheet.getRange('E2:E5').clearContent();
  sheet.getRange('B7:B20').clearContent();
  sheet.getRange('E7:H20').clearContent();
  sheet.getRange('I7:I20').setValue('kg');
  sheet.getRange('L7:L20').clearContent();
  sheet.getRange('B24:B29').clearContent();
  sheet.getRange('J24:J29').clearContent();
}

I also have an "erase only" script that runs the second second part of the script only (if data has been entered incorrectly) that executes perfectly fine. It is only when coupled with the copy/transcribe portion of the script that the protection error occurs.

function ErADD() {
 var sss=SpreadsheetApp.getActiveSpreadsheet();
 var sheet = sss.getSheetByName('ADDER');
  
  sheet.getRange('E2:E5').clearContent();
  sheet.getRange('B7:B20').clearContent();
  sheet.getRange('E7:H20').clearContent();
  sheet.getRange('I7:I20').setValue('kg');
  sheet.getRange('L7:L20').clearContent();
  sheet.getRange('B24:B29').clearContent();
  sheet.getRange('J24:J29').clearContent();
}

Commenting out the sheet.getRange.... etc clearContent and setValue portion of the first script allows it to complete successfully, so I attempted to create a master function that calls the CopyErAdd script (sans clear portion) and then calls the ErADD script, and I encounter the same error. Both script can be run on their own successfully, but when combined the erase portion encounters the error.

Does anybody see any issues that I am missing, or did something occur over the past few weeks that I'm not aware of that could cause this protection error?

I appreciate any ideas anybody might have.

Edit - Thank you MetaMan for the tips for making the script more efficient.

As for the protection, "Incoming" and "Outgoing" copy destination sheets are completely open, no protection at all. "ADDER" sheet is protected except certain cells that are edited by user, and are referenced in the script. E2:E5 (actually E2:I5 open, since the macro button sits on top of the F2:I5 range), B7:B20, E7:I20, L7:L20, B24:B29, J24:J29, All unprotected.

Adding the line

SpreadsheetApp.flush()

in between the copy section and clearing section of the code worked (as shown in the updated code snippet). I'm no longer encountering a range protection error.

I really appreciate the fix, but I'm boggled over why I've never needed that line until recently. I guess you don't need flush() until you do.

You could replace this:

  sheet.getRange('I7').setValue('kg');
  sheet.getRange('I8').setValue('kg');
  sheet.getRange('I9').setValue('kg');
  sheet.getRange('I10').setValue('kg');
  sheet.getRange('I11').setValue('kg');
  sheet.getRange('I12').setValue('kg');
  sheet.getRange('I13').setValue('kg');
  sheet.getRange('I14').setValue('kg');
  sheet.getRange('I15').setValue('kg');
  sheet.getRange('I16').setValue('kg');
  sheet.getRange('I17').setValue('kg');
  sheet.getRange('I18').setValue('kg');
  sheet.getRange('I19').setValue('kg');
  sheet.getRange('I20').setValue('kg');

with this:

  sheet.getRange('I7:I20).setValue('kg');

also replace this:

 var ss = sss.getSheetByName('ADDER'); //Entry sheet
 var sheet = SpreadsheetApp.getActive().getSheetByName('ADDER');

with this:

 var sheet = sss.getSheetByName('ADDER);

If you are doing anything immediate after this function with the data then you might wish to add SpreadsheetApp.flush()

I can't comment on the protection since none of that information was provided.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM