Hide formula bar in google sheets - google-apps-script

I want to achieve the following:
I do not want other users of the sheet to access the formula bar for certain cells/sheets of the spreadsheet
I want to block them from accessing the script editor (do not want to show the code) used for this sheet

I do not want other users of the sheet to access the formula bar for certain cells/sheets of the spreadsheet
This is not possible.
You could publish your spreadsheet but this will not allow to edit any content, or to use Google Forms, but this will allow respondents only to submit data, not to view the result of calculations.
To securely hide the formulas they should be in another spreadsheet. You could use IMPORTRANGE or a script to import/export the calculations result. Bear in mind that IMPORTRANGE isn't recalculated immediately and that scripts could be slower than built-in functions.
An alternative is to create a web app that makes the calculations and call it from a custom function.
I want to block them from accessing the script editor (do not want to show the code) used for this sheet
It's not possible to block editors to access the Script editor. For details see
Scripts Bound to Google Sheets, Docs, or Forms. To prevent that viewers get access to the code, block the spreadsheet for making a copy. For details see Change your sharing settings

You can set permissions per cell:
- Click the cell
- Left-mouse click or Ctrl+click -> menu 'Protect range'
- Click 'Set Permissions' in sidebar
- Select Only You
Now the content is still visible.
There is a work-around for this, which is quite complicated.
- Create another sheet, called Formulas.
- Protect this sheet the same way above.
- In your main sheet you can refer to formulas in the other sheet: =Formulas!B1
- Now you can write the formula in this cell B1 in sheet Formulas
=Sheet1!B1+Sheet1!C1-Sheet1!D1 (where Sheet1 is the name of the first sheet)
- Now hide the Formulas sheet

Related

ActiveSheet().getName() returns different results. Could somebody explain why? [duplicate]

I guess this question is the most similar to my current question. But basically, I have a google sheets file that has several sheets along the bottom. I would like for the user to execute this script on whatever sheet they have open at the time.
And like the previous question said according to this documentation, the active sheet is the one that is being displayed in the spreadsheet UI. I assume this means if I have the google sheets file open in another tab, that the sheet currently selected and viewable by me is intended to be the active sheet.
However, the actual active sheet returned is always the leftmost sheet along the bottom tabs. I've confirmed it by switching the order of the sheets. So no matter what sheet I actually have open and visible in the UI, it always gets the leftmost sheet. Here is the line that gets it.
var Sheet = SpreadsheetApp.openById("redactedid").getActiveSheet()
Is this a known error with App Script? Or is the documentation wrong? If it is, is there a workaround for getting the currently open sheet in the UI? I don't want anyone to have to hardcode a sheetname in the code as the file is constantly changing and sheets are being added.
Notes:
To use getActiveSheet() or any active object, the calling
Script must be bound to the Spreadsheet
Script function should be invoked from menu or button or macro keyboard shortcuts and NOT from webapp or API( Script editor also works, but not preferred).
Spreadsheet must be open/visible in the user interface/browser preferably in the active/currently selected window.
All previous calls to get objects must have used active. For eg, To get active range, You should have first got active spreadsheet => active sheet => active range(the chain of active objects). If any of the calls is not to the active object(say if you used getSheetByName() instead of getActiveSheet() in the middle step), the final call is likely to default to the default object(First sheet A1).
Solution:
Here, To get Spreadsheet, use SpreadsheetApp.getActive() instead of SpreadsheetApp.openById(), So that getActiveSheet() will be under the chain of active objects.
Snippet:
const sheet = SpreadsheetApp.getActive().getActiveSheet();
It's known that the getActiveSheet method returns the first sheet when used with an spreadsheet that is not the active spreadsheet.
The active spreadsheet is retrieved by using getActiveSpreadsheet. I only works on scripts bounded to an spreadsheet and in G Suite Editors add-on for spreadsheets.
In the the same way, getCurrentCell and getActiveRange returns A1 when corresponding sheet is not an active sheet (meaning it's not a sheet from an active spreadsheet)
Resources
https://developers.google.com/apps-script/guides/sheets
Related
Google Apps Script, select a sheet - Sets values in first sheet tab - not a specific sheet tab
All the points in the accepted solution are all true, but sometimes your spreadsheet looses some connection to something on Google's back end or the cache gets corrupted, who knows. The fix is to close the all tabs for the worksheet, editor, triggers, executions -- whichever ones you have open for that spreadsheet, close them. Reopen the spreadsheet. Start again. It's fine now.

Can I use Google Apps Script to activate my spreadsheet?

I have an active spreadsheet, I want to select a cell in this spreadsheet and then bring me to another Spreadsheet. I used app.openByUrl to open the spreadsheet and then get my wanted sheet by name and then activate the cell by getRange, the script is finished but it didn't take me from the active spreadsheet to the other spreadsheet, the cursor remains in the cell of the active Spreadsheet. I use the following code. Does anyone has an idea?
app.openByUrl("https://docs.google.com/spreadsheets/d/1S9Kc6foLZ_bXqs4/edit#gid=502179704").getSheetByName("Verification Candidates").getRange('D4:F4').activate();
It's not possible to activate an external spreadsheet by solely using Google Apps Script as
Class Spreadsheet doesn't include like similar to Class Range activate
The Class Spreadsheet "open" methods open the spreadsheet on the server side, not on client side.
You might be able to do what you are looking by using other tools (i.e. a complex bookmarklet)

Google Sheets script general mechanics

I have put together a rather large script file that does a lot of math. It seems to me that if I place a script variable value on the spreadsheet (setValues()), the whole spreadsheet recalcs (i.e.; it takes awhile to refresh). Is that true?
What if I want to format a cell from script (e.g.; change a number cell to a percentage cell with 3 places)[FormattedSS.getRange(rangecoordinates).setNumberFormat("#.###%");]? When I set the format, does the whole spreadsheet recalculate?
I am new to Google Sheets. In Excel, I could set calculation off. Google sheets does not seem to have that option.
Google sheets has no manual calculation option. You would need to create a formula to check whether to run the rest of the formula. If the output is a single cell you can easily use a circular reference to retain the value.
When it comes to Google App Scripts every time you execute a script there will be an annoying delay, that is just how it works, the App Script should be avoided at all cost in a normal spreadsheet except for when actually necessary.
Google App Script Server -> Google Sheet (delay to send information back and forth)
Google Sheet always recalculates after any change

Google Apps Script - Is it possible to allow change to some cell in Sheets only through GoogleAppScript?

My making a catalog in Google SpreadSheet. My spreasheet has a table where the user can add information. This table is dynamically created through a Script that gets the data from the database sheet.
The user can edit some cells in the table and click on a button that saves the changes back into the database sheet.
I want to limit the cells he can edit manually, but I can´t protect theses cells, because there is a script that modifies it (since the table is dynamically generated through a script).
Is there a way to protect cells so that they can only be edit by a script?
I can not just protect some ranges, because it is the user that runs the script that modifies the cells. If I protect the ranges, the user can´t change the range either manually or using the script. I want a way to protect the range against manual input, but allow the script, that the user runs (not the spreadsheet owner), to change the cells.
Thank you
I have solved this issue by the following steps
printsht.getRange("A1:Q22").setDataValidation(null);
Do whatever processing in the range
printsht.getRange(1,1,22,17).setValues(prin);
After all the processing and setValues etc
// block editing after printing
var cell = printsht.getRange( "A1:Q22");
var rule = SpreadsheetApp.newDataValidation().requireTextEqualTo('$$').setAllowInvalid(false).setHelpText("Do not edit in print sheet").build();
cell.setDataValidation(rule);
Now no one can edit the range manually. All the formula etc will work normally.
But, if the user is having edit rights, he can easily remove the validation from the system menu. So, it is not foolproof.
Instead of using a bounded script use a stand alone script to create a web app that runs with the owner permissions. This because the bounded scripts runs this the permissions of the user that execute the script.
To help you user to execute the webapp, I think that you could create a user dialog or side panel that will display the link to the webapp.

Google script: unprotect a sheet through function when user has no right to do so

I have a spreadsheet with different sheets in Google sheet, 3 users can edit each one a sheet (protections are set, each user can edit only one sheet). They all can execute a google script function that writes what they edited in a summary sheet. I don't want anyone to be abble to edit the summary sheet, so I set myself as the only available editor.
So my problem is to authorize the 3 users, only through the google script function, to write in the summary sheet. I tried to use the following function :
var unprotected = summarySheet.getRange('G3:G10');
protection.setUnprotectedRanges([unprotected]);
but since the users are not allowed to edit the summary sheet, and since the function is run with the active user, so they can't give themselves the right to unprotect a range in the summary sheet... Do you know how to workaround this problem?
Thanks a lot!
I see two script-based choices, one easy and one quite hard, and one sheet-based choice, that is easiest:
Easy:
You run the "summarize" script instead of them or, you set the summarize script run on a trigger out of your account. Then you actually leave protections alone. You could set the summarize script to run on open with error catching if the user doesn't have the necessary authority to unprotect the summary sheet and/or write to the summary sheet.
Hard:
When they run the "summarize" script it calls a published standalone script that has been given the authorization to make the necessary protection changes. I'll be honest, I wouldn't be able to code this but have seen/heard of similar implementations.
Easiest:
Finally, I want to make sure you've considered having the summary sheet itself contain the necessary formulas, parsing, etc. to summarize data from the other sheets without any need of scripts for this aspect of the sheet. The sheet could call custom functions as needed if the parsing or other summarization functionality is beyond built-in functions' capabilities. The sheet could stay fully protected and update itself in real time as users enter data (no need for users to trigger the summary creation, unless spreadsheet settings have auto-recalculate turned off).
Edited to add: put in A1 of Summary sheet something like:
=summarize()
And have that custom function return a 2-dimensional array of the summarized data.