/** * Protect all formulas - free script from formulalock.com * Adds Google Sheets' own protection to every cell that holds a formula. * Paste into Extensions > Apps Script, save, reload the sheet, use the "Protect formulas" menu. * @OnlyCurrentDoc */ const ALL_TABS = true; // true = every tab, false = only the tab you are on const WARNING_ONLY = true; // true = editors see a warning but can still edit; false = only you can edit const TAG = 'Formula (auto-protected)'; function onOpen() { SpreadsheetApp.getUi().createMenu('Protect formulas') .addItem('Protect all formula cells', 'protectAllFormulas') .addItem('Remove these protections', 'removeFormulaProtections') .addToUi(); } function protectAllFormulas() { const ss = SpreadsheetApp.getActive(); const sheets = ALL_TABS ? ss.getSheets() : [ss.getActiveSheet()]; const me = Session.getEffectiveUser(); let n = 0; sheets.forEach(function (sh) { const r = sh.getDataRange(); const f = r.getFormulas(); for (let i = 0; i < f.length; i++) { let j = 0; while (j < f[i].length) { if (!f[i][j]) { j++; continue; } let k = j; while (k + 1 < f[i].length && f[i][k + 1]) k++; const p = sh.getRange(r.getRow() + i, r.getColumn() + j, 1, k - j + 1).protect().setDescription(TAG); if (WARNING_ONLY) { p.setWarningOnly(true); } else { p.addEditor(me); p.removeEditors(p.getEditors().filter(function (e) { return e.getEmail() !== me.getEmail(); })); if (p.canDomainEdit()) p.setDomainEdit(false); } n++; j = k + 1; } } }); SpreadsheetApp.getUi().alert('Protected ' + n + ' formula range(s). New formulas you add later are not covered: run this again.'); } function removeFormulaProtections() { let n = 0; SpreadsheetApp.getActive().getSheets().forEach(function (sh) { sh.getProtections(SpreadsheetApp.ProtectionType.RANGE).forEach(function (p) { if (p.getDescription() === TAG && p.canEdit()) { p.remove(); n++; } }); }); SpreadsheetApp.getUi().alert('Removed ' + n + ' protection(s).'); }