Advertisement
Guest User

Untitled

a guest
Jun 16th, 2019
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.20 KB | None | 0 0
  1. function onEdit() {
  2. // Re: /docs/forum/AAAABuH1jm0gnrD6_XtZT0/discussion
  3. //
  4. // This script prevents cells from being updated. When a user edits a cell on any sheet,
  5. // it is checked against the same cell on a helper sheet, and:
  6. //
  7. // - if the value on the helper sheet is empty, the new value is stored on both sheets
  8. // - if the value on the helper sheet is not empty, it is copied back to the cell on
  9. // the source sheet, undoing the change
  10. //
  11. // This in effect protects sheets in a "write once" manner, albeit with lots of limitations.
  12. // The script does *not* provide protection against edits by a determined user.
  13. // For example, selecting all cells and pressing Delete lets any user erase many cells at once.
  14. // The values that were deleted from the cells will however be preserved on the helper sheet
  15. // and will reappear when an individual cell is edited again.
  16. //
  17. // Helper sheets are created automatically when an edit is first made, one helper sheet
  18. // per source sheet. For a source sheet named "Sheet1", the helper sheet is "Sheet1_helper".
  19. // Helper sheets are automatically hidden when created to not clutter the display, but
  20. // they can be uhidden by any user with "can edit" rights to the spreadsheet.
  21. // Users with edit rights can also disable this script at will.
  22. //
  23. // To change a value that was entered previously, empty the corresponding cell on the helper sheet,
  24. // then edit the cell on the source sheet.
  25. // When you rename a source sheet, remember to rename the helper sheet as well.
  26. // Choose "View > Hidden sheets" to show the helper sheet, then rename it using the pop-up
  27. // menu at the sheet's tab at the tab bar at bottom of the browser window.
  28. //
  29. // To take this script into use:
  30. //
  31. // - take a backup of your spreadsheet through File > Make a copy
  32. // - select all the text in this script, starting at the "function onEdit()" line and ending at the last "}"
  33. // - copy the script to the clipboard with Control+C
  34. // - open the spreadsheet where you want to use the function
  35. // - choose Tools > Script editor > Blank (this opens a new tab in the browser)
  36. // - press Control+A followed by Control+V to paste the script in
  37. // - press Control+S to save the script
  38. // - close the script editor tab and go back to the spreadsheet tab
  39. //
  40. // The script will from then on watch updates on all the sheets and only allow edits
  41. // when the cell is empty to start with.
  42. //
  43. // Note that the script only protects _values_ rather than _formulas_.
  44. // To protect formulas, use Data > Named and protected ranges.
  45. //
  46. // If your sheets that you would like to protect already have data on them, create helper
  47. // sheets manually by choosing the Duplicate command from the sheet's tab menu at the tab bar
  48. // at the bottom of the browser window. Rename the new sheet so that "Copy of Sheet1" becomes
  49. // "Sheet1_helper".
  50. //
  51. // The range where edits are of this "write once" type can be limited by changing the values
  52. // assigned to the firstDataRow, lastDataRow, firstDataColumn and lastDataColumn variables below.
  53. // The range defined by these values is global and will apply to all the sheets the same.
  54. //
  55. // You can exclude some sheets from being watched by putting them on the freeToEditSheetNames
  56. // list. See below for more info.
  57.  
  58.  
  59. // modify these variables per your requirements
  60.  
  61. // define the range where edits are "write once"
  62. // to watch only the range A1:D100, define rows as 1,100 and columns as 1,4
  63. // to watch only the range M20:V30, define rows as 20,30 and columns as 13,22
  64. var firstDataRow = 1; // only take into account edits on or below this row
  65. var lastDataRow = 999; // only take into account edits on or above this row
  66. var firstDataColumn = 1; // only take into account edits on or to the right of this column
  67. var lastDataColumn = 999; // only take into account edits on or to the left of this column
  68.  
  69. // naming pattern for sheets where values are copied for later checking
  70. var helperSheetNameSuffix = "_helper";
  71.  
  72. // sheets that are free to edit with no protection
  73. var freeToEditSheetNames = ["Free to edit 1", "Free to edit 2", helperSheetNameSuffix + "$"];
  74. // You can use regular expressions in sheet names. The match is not case-sensitive,
  75. // so "free.*edit" will match "free to edit", "Free Editing for Everyone",
  76. // "Sheet (free to edit)" and "Free edit playground".
  77. // Leave the last entry, helperSheetNameSuffix + "$", as it is to ensure that changes to a
  78. // helper sheet do not trigger the creation of another _helper_helper sheet.
  79. // See these sites for more info:
  80. // - http://en.wikipedia.org/wiki/Regular_expression
  81. // - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
  82.  
  83.  
  84. var ss = SpreadsheetApp.getActiveSpreadsheet();
  85. var masterSheet = ss.getActiveSheet();
  86. var masterSheetName = masterSheet.getName();
  87. var masterCell = masterSheet.getActiveCell();
  88. var sheetNameRegExp;
  89.  
  90. // do not record edits on free to edit sheets
  91. for (var sheet in freeToEditSheetNames) {
  92. sheetNameRegExp = new RegExp(freeToEditSheetNames[sheet], "i");
  93. if (sheetNameRegExp.test(masterSheetName)) return;
  94. }
  95.  
  96. // find helper sheet
  97. var helperSheetName = masterSheetName + helperSheetNameSuffix;
  98. var helperSheet = ss.getSheetByName(helperSheetName);
  99. if (helperSheet == null) { // helper sheet does not exist yet, create it as the last sheet in the spreadsheet
  100. helperSheet = ss.insertSheet(helperSheetName, ss.getNumSheets());
  101. Utilities.sleep(2000); // give time for the new sheet to render before going back
  102. ss.setActiveSheet(masterSheet);
  103. helperSheet.hideSheet();
  104. ss.setActiveRange(masterCell);
  105. }
  106.  
  107. if (masterCell.getRow() < firstDataRow || masterCell.getColumn() < firstDataColumn ||
  108. masterCell.getRow() > lastDataRow || masterCell.getColumn() > lastDataColumn) return;
  109.  
  110. var helperCell = helperSheet.getRange(masterCell.getA1Notation());
  111. var newValue = masterCell.getValue();
  112. var oldValue = helperCell.getValue();
  113.  
  114. if (oldValue == "") {
  115. helperCell.setValue(newValue);
  116. } else {
  117. masterCell.setValue(oldValue);
  118. }
  119. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement