Running Script in Other Spreadsheet from Current Spreadsheet - google-apps-script

I have two different Spreadsheets with their own script projects. I have created a library from SpreadsheetA and linked the same to SpreadsheetB. Now when I call the function of SpreadsheetA from the script of SpreadsheetB it runs the same in the current active sheet of SpreadsheetB while I want to run the function on selected sheet of SpreadsheetA.
function createDO() {
var ss = SpreadsheetApp.getActive(); //SpreadsheetB
var cell = ss.getActiveCell().getRowIndex();
var spreadSheetAURL = "URL"; //SpreadsheetA
var spreadSheetsInA = SpreadsheetApp.openByUrl(spreadSheetAURL).getSheetByName("name");
spreadSheetsInA.activate()
Sheetname.Project(); //script in SpreadsheetA
};
I need to run the Sheetname.Protect() function for SpreadsheetA from the current SpreadsheetB.

Possible Solution:
Firstly, it is worth noting that libraries do not work like this. As Oleg Valter has stated, libraries are by nature utility scripts which are not bound to any one specific script/class/project.
As a workaround, however, you can set up a web app which can be called from one project to another, running code inside a doGet() function on the respective Spreadsheet.
A structure would look something like this:
In Spreadsheet A:
function doGet(e) {
var sheetName = e.parameter.sheetName
var sheet = SpreadsheetApp.getActiveSpreadheet.getSheetByName(sheetName);
sheet.activate();
// I am not how this works, but I have extrapolated from your question
Sheetname.Project();
}
Then deploy this as a Web App from the Publish > Deploy as web app... menu item. The settings should be Execute the app as: me and Who has access to the app: Anyone (even anonymous).
Then, getting the Web App URL from the dialog, in Spreadsheet B:
function createDO() {
var ss = SpreadsheetApp.getActive(); //SpreadsheetB
var cell = ss.getActiveCell().getRowIndex();
var webAppUrl = "URL"; //SpreadsheetA
UrlFetchApp.fetch(webAppUrl + "?sheetName=name");
};
The ?sheetName=name parameter is a URL query string which would be passed to the web app's doGet(e)'s event object. This is what is accessed with e.parameter.sheetName.
The string on the right-hand-side of the = in the query string needs to be the sheet name you were trying to activate originally.
References:
Web Apps | Apps Script | Google Developers
Query string - Wikipedia
Simple Triggers - doGet(e) and doPost(e) | Apps Script | Google Developers
Event Objects | Apps Script | Google Developers

Related

Find Replace google spread sheet app script

I have this very small issue and I was hoping someone could help me solve it.
This is the code.
function textFinder() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var range = sheet.getActiveRange();
var textFinder = range.createTextFinder('=');
var firstOccurrence = textFinder.findNext();
var numOccurrencesReplaced = firstOccurrence.replaceWith("=");
}
When the code runs I get
Error
TypeError: Cannot read property 'replaceWith' of null
textFinder # findReplace.gs:11
I am trying to find the = in a function that is in A1 B1 D1
I believe your goal is as follows.
You want to refresh all functions in a sheet using Google Apps Script.
In the case of refreshing the functions on Google Spreadsheet using TextFinder, I thought that these samples are useful. Ref1 Ref2 Ref3 But, in this case, I'm worried that in order to refresh all functions in a sheet, it might be a bit difficult. So, in this answer, I would like to propose a sample script for refreshing all functions in a sheet using Google Apps Script.
Sample script:
function myFunction() {
const sheet = SpreadsheetApp.getActiveSheet();
const refresh = (a, b) => sheet.createTextFinder(a).matchFormulaText(true).useRegularExpression(true).replaceAllWith(b);
refresh("^=(.+)$", "==$1");
refresh("^==(.+)$", "=$1");
}
If you want to refresh all functions in all sheets of a Google Spreadsheet, please modify SpreadsheetApp.getActiveSheet(); to SpreadsheetApp.getActiveSpreadsheet();.
References:
Class TextFinder
Related threads
Custom function won't refresh as inputs are changed
Google Sheets Function to Actively Check Cell
Refresh data retrieved by a custom function in Google Sheet

Another user should be able to update the protected range in google spreadsheet using google app script

I have shared a sheet with protected range with another user and wants them to submit data such as the invoice copy or data from a specific range of cells of one sheet to another, using a SUBMIT button to which the respective script is assigned.
Scenario:
Two spreadsheets namely S1 and S2, of which S2 is protected and another user wants to submit data from S1 to S2 after he/she presses the submit button.
function testing() {
var ss = SpreadsheetApp.getActive();
var s1 = ss.getSheetByName('S1');
var s2 = ss.getSheetByName('S2');
s1.getRange("A1:G1").copyTo(s2.getRange("A1:G1"));
}
Also, I have read that this can be done by deploying the script as the web app. I tried that by going into "Deploy as web app" and setting the script to run as admin(me) and accessible to anonymous. But still no positive result.
Did put something like this for web app deployment:
function doGet(e){
return testing(e);
}
function testing() {
var ss = SpreadsheetApp.getActive();
var s1 = ss.getSheetByName('S1');
var s2 = ss.getSheetByName('S2');
s1.getRange("A1:G1").copyTo(s2.getRange("A1:G1"));
}
Error Says:
You are trying to edit a protected cell or object. Please contact the spreadsheet owner to remove protection if you need to edit.
Can someone walk me through the process or tell me where I am going wrong with it?
When you run the code like that you are calling the testing() function as is using whatever account and permissions the current user has.
What you need to do is use the UrlFetchApp to call the doGet() this will run the script as the user who published the app:
1: Copy and paste the code
function copyRange() {
UrlFetchApp.fetch("--- Copy this URL from step 3 ---");
}
function doGet(e) {
var ss = SpreadsheetApp.getActive();
var s1 = ss.getSheetByName('Sheet1');
var s2 = ss.getSheetByName('Sheet2');
s1.getRange("A1").copyTo(s2.getRange("A1"));
}
2: Click 'Publish' - 'Deploy' set new project version to execute as Me and allow anyone as you did in your test. Click 'Update'
3: Copy the Current web app URL and paste it into the fetch() save the script.
Now any user should be able to run the function or going to the URL from step 3 will trigger the function.

Call to insertSheet works in Google Script Editor and was authorised but dosent work when calling from the spreadsheet

I have written a custom function that calls the code below to create a temporary sheet. When I ran it in Google Editor I was asked for authorisation and granted access.
My custom function runs well in Google Editor but doesnt work in the spreadsheet and I get the error "You do not have the permission to call insertSheet".
I created the spreadsheet and custom function so I own (have access) to everything.
var tempSheetName = "temp";
var sp = SpreadsheetApp.getActiveSpreadsheet();
var activeCell = sp.getActiveCell();
sp.insertSheet(tempSheetName);
From Google Apps Guide : Link
If your custom function throws the error message You do not have
permission to call X service., the service requires user authorization
and thus cannot be used in a custom function.
You may have your reasons, why you want to accomplish it in this way. But I'm really not sure if a custom function in a cell is the right place to create a new tab. You usually do calculations within a cell not document manipulations.
What, if you'd create a menu entry for the function like this and call it from there?
function onOpen() {
// instantiate UI object
var ui = SpreadsheetApp.getUi();
// create the menu
ui.createMenu("Functions")
.addItem("Create Sheet", "createSheet")
.addToUi();
}
function createSheet() {
// get active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet(),
sheetName = 'mySheet',
sheet = ss.getSheetByName(sheetName);
// delete sheet if it already exists
if (sheet) ss.deleteSheet(sheet);
// insert sheet
ss.insertSheet(sheetName, 0);
}
Do you still get an error? Just curious...

Find the ID of the attached spreadsheet from doGet function

I am looking to have 'openById' find the ID of the spreadsheet it is attached to automatically, if this is possible?
Currently I am pulling cells from a spreadsheet into an HTML template which populates the design with the cell data.
If a user 'makes a copy' of the spreadsheet, the ID (which I have entered manually) is still that of the original spreadsheet I am using, not the new spreadsheet ID of the one they are using.
Would it be possible to get the ID of the spreadsheet that the script is attached with dynamically?
// code.gs
function doGet() {
var template = HtmlService.createTemplateFromFile('index.html')
template.sheet = SpreadsheetApp.openById('THE SPREADSHEET ID');
// returning .evaluate() (an HtmlOutput object) will allow you to display this in a web app.
// to get the string HTML content, use .getContent() on the HtmlOutput
return template
.evaluate();
}
The method openById requires an Id, it does not return it. One can get an id with getId called on a spreadsheet object. However, doGet and doPost functions don't have a concept of active spreadsheet; the method SpreadsheetApp.getActiveSpreadsheet() returns null when called from them. It seems that Web Apps are never considered bound to a spreadsheet, as documentation hints at when listing triggers.
So, there is no direct way to achieve what you want. But there is a workaround: instruct the user to execute a function capturing Id and storing it in ScriptProperties (they'll need to authorize this, so onOpen won't do). Example:
function recordId() {
var ssId = SpreadsheetApp.getActiveSpreadsheet().getId();
PropertiesService.getScriptProperties().setProperty('id', ssId);
}
function doGet(e) {
var id = PropertiesService.getScriptProperties().getProperty('id');
var ss = SpreadsheetApp.openById(id); // have access to spreadsheet
return ContentService.createTextOutput(id); // confirms that id is known to the script
}
You can make the process easier by using onOpen to create a menu item that will launch recordId.

Access to spreadsheet in deployed web app

I am trying to access a Google spreadsheet via a Google script, that is published as a web app.
How I created the script:
from the spreadsheet, Tools/Script editor..., Spreadsheet project
and it asked for access to the spreadsheets in GDrive, so overall I assume it is attached to the spreadsheet.
The script:
function doGet() {
var ss = SpreadsheetApp.getActive();
// alternative, doesn't work either
// var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/abcdef/edit");
var sheets = ss.getSheets();
var text = ... loop over sheets and do some stuff to get the data ...
return ContentService.createTextOutput(text);
}
The error message when calling the web app:
TypeError: Cannot call method "getSheets" of null.
The function works (minus the ContentService.createTextOutput of course) when run in the editor.
You can't use the getActive() method unless the script is bound to a spreadsheet (ie script was created within the spreadsheet).
In your example with openByUrl() I would check your URL and the permissions to that sheet. Here is working example of what you were trying to do.
function doGet(){
var ss= SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1XLOVvEo2nzLARwRhsiWUrFMtF0LnofC1PQoWIeLmwgQ/edit#gid=0');
return ContentService.createTextOutput(ss.getSheets()[0].getName()).setMimeType(ContentService.MimeType.TEXT);
}