Permission Issue when moving data from one spreadsheet to another - google-apps-script

I'm trying to write a script that moves a range of data from one spreadsheet to another. I'm running into a permission issue when I try to open the destination spreadsheet, I keep getting the error "You do not have permission to call open." I've tried open(file), openByUrl(url), and openById(id), and all three methods raise that same error.
I am the owner of the destination spreadsheet, so I don't understand why I don't have permission. I am also the owner of the script, and I have read/write access to the source spreadsheet (although I am not the owner).
Thanks for your help.
Here's my code:
function moveData() {
var source = SpreadsheetApp.getActiveSheet();
var destination = SpreadsheetApp.openById("1kfELXf9WxcZGsUO0piCjEXC_-ZR57GvbFzx1UPw89K4");
...
}

Unfortunately this behaviour is prohibited by Google: Following an update to Apps Script rolled out last June, custom functions are permitted to read data only from the current spreadsheet.
Their recommendation is to use the IMPORTRANGE formula instead.

Related

How to request or get the permission of google spread sheet access in the apps script of other sheet?

I am writing apps script of A spread sheet for my custom functions and trying to get values in B spread sheet from there using openUrl()
However, I got ERROR in A spreadsheet when I use the custom function..
in Google Document, it says
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.
ref: https://developers.google.com/apps-script/guides/sheets/functions
However, it doesn't say anything how to get the permission..
I tried with sharable link to everyone but it didn't work.
I tried with url&scope=https://www.googleapis.com/auth/spreadsheets
Both way didn't work. How can I solve this problem?
Unfortunately, what you're asking for cannot be done directly. In the same documentation, please scroll all the way down to sharing; that's -
Custom Functions in Google Sheets > Advanced > Sharing.
Here, you'll see the following -
Custom functions start out bound to the spreadsheet they were created in. This means that a custom function written in one spreadsheet can't be used in other spreadsheets unless...
If it suits you, you can make use of the 3 methods that they've listed there to overcome this problem.
Hope this helps!
Here's how I solved:
You can't access other spreadsheet files, which means you can't use openById() or openByUrl(). So, there is only one method you can achieve this - using getActiveSpreadSheet() which is the current spreadsheet that the app script belongs to.
If you wanted to hide the original file, then you can consider making a reference file that is sharable for anyone. And your original file is private.
So, You need to make it one more file to share.
original file (private)
Use getactiveSpreadSheet() instead of openById() or openByUrl(). And implement your custom functions. You won't have any problem with accessing the current spreadsheet in this way.
function YOUR_CUSTOM_FUNCTION(val1, val2, ...){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("YOUR_SHEET_NAME");
return getMyValue(val1, val2, ...);
}
function getMyValue(val1, val2, ...){
var result = 0;
// TODO: calculate values as you want.
return result;
}
Use your custom function in the file like this:
=YOUR_CUSTOM_FUNCTION(E5, F6, ...)
You won't get any ERROR.
reference file (sharable)
You can make a reference sheet with using:
=IMPORTRANGE("spread sheet link","sheet_name!range")
This will show access button to get authorization. Once you click, it will make a reference from your original sheet.
*range is something like A:C or A1:Z55.

Google Sheet Scripts to Import Range: Error "You do not have permission to access it."

TLDR: I need to import a range of cells from a separate google sheet using a scsript, but am being told I do not have access to the other sheet(I'm sure the ID is right). I don't know why I don't have access to the other sheet. If anyone knows a simple script to do this that would be great. Please help!
Hi everyone, I had been using importrange to pull data from other google sheets into my master sheet, but was experiencing the never-ending loading times that others have previously complained about. I've never used scripts before and so don't really know what I'm doing.
Within the destination google sheet, I created the following script but get this error: "No item with the given ID could be found, or you do not have permission to access it."
function UpdateRange(ID, source_sheet, source_range, destination_sheet_name) {
var values = SpreadsheetApp.open(DriveApp.getFileById(ID))
.getSheetByName(source_sheet)
.getRange(source_range)
.getValues();
return SpreadsheetApp.getActive()
.getSheetByName(destination_sheet_name)
.getRange(1, 22, values.length, values[0].length)
.setValues(values);
}
UpdateRange("1Rt***_tRbs", "Revenue By Category", "E2:M9", "Sheet33");
***used to anonymize origin sheet ID
I don't understand how I don't have access to the sheet even though I'm the one who created it in the first place. How do I get access to the sheet or what else I can do to import this range. Help is very much appreciated!
At a quick glance, you could try simplifying:
SpreadsheetApp.open(DriveApp.getFileById(ID))...
to just:
SpreadsheetApp.openById(ID)...
Both approaches should work fine, but then you avoid using the DriveApp API which might require some different permissions than just the Spreadsheet one.

Identifying the spreadsheet to use in Google Script Editor

I am trying to automate a google spreadsheet on google script editor. However, when I try to identify the spreadsheet and select as the one that we are working on, it is written in the documentation cited below (openById) that scripts that use this method require authorization with one or more of the following scopes:
--> https://www.googleapis.com/auth/spreadsheets.currentonly
--> https://www.googleapis.com/auth/spreadsheets
When I add these scopes, my function doesn't run. It only runs when those scopes are not added. Either way, I am met with the error msg that reads: "We are sorry, a server error occurred. Please wait a bit and try again."
https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app#openbyidid
I tried various methods include OpenByUrl and getActiveSpreadsheet...
function automatedInvoiceEmailing() {
var people = [];
// selecting the spreadsheet (without the bottom line, the function works just fine)
var ss = SpreadsheetApp.openById("1jdn3S1Iv2zDAqF6Hyy3fybKARZJYmg-LJVdUWJJS3LA");
}
Either way, I am met with the error msg that reads: "We are sorry, a server error occurred. Please wait a bit and try again."
I expected the sheet to have been selected
Edit: hmm, when I copied the google sheets and saved the new code, it runs properly!! :)
Since you are working with a bounded script (bound to the sheet you’re working with), the way to get a reference to the sheet is with var ss = SpreadsheetApp.getActiveSheet();, this will provide a reference to the bound document. You would use openById() to access another file.
As for scopes, they are added automatically when you run the script for the first time, it will ask for your permission to access your data, and when you accept, google adds them to the script project automatically.
Here are some quick-start examples on working with sheets and apps script

Apps Script libraries permission

When I create an Apps Script library that accesses a spreadsheet and use it in a script then I get a permission error (for setValue in the following example).
If I call the same spreadsheet function in the script once (and then remove it) and then call the library function I will never get the permission error again (It's reproducible).
Have you ever experienced such behavior and if yes how did you solve this problem?
Thanks
The library
function addRecord(ss, sheetName) {
var sheet = ss.getSheetByName(sheetName);
sheet.getRange("A1:A1").setValue("Hello World!");
}
The script
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
MyLib.addRecord(ss, "Sheet1");
}
The error message
"You don’t have the required permission to call setValue"
Your script must have the same authorizations than the libraries need to have : if you know that the library reads/writes a spreadsheet or a calendar (or whatever) you have to authorize the script for these services.
You can do that quite easily with some (even dummy ) function that will tell the system to call the authorization process for the required services. From what you describe I guess the system doesn't check what is inside the library when you save you script so it's kind of a 'surprise' for the script to write to the spreadsheet without authorization. If you include the (dummy) calls I mentioned before the script will know what you are going to do and ask for authorization on the first run attempt.
Hoping I'm clear enough.
To close this - the issue reported by Stefan has been confirmed as an issue. We are looking into this. Permissions to a passed in spreadsheet are not being correctly absorbed by a library.
Stefan - please feel free to create a report on issue tracker if you prefer.

How to access data on different Google Spreadsheet through Google Apps Script?

I'm writing a Google Apps Script on my Google Site and am trying to use data that is provides on 2 different tabs in a Google Spreadsheet. From what I thought I understood from the documentation I could use all available methods in the SpreadsheetApp class on a Sites script by just using the openById() method.
Anyway here is what I tried to do
function doGet(e) {
var doc = SpreadsheetApp.openById(SPREADSHEET_ID_GOES_HERE).getActiveSheet();
SpreadsheetApp.setActiveSheet(doc.getSheetId()[1]);
//....
}
I get the error
Cannot find method setActiveSheet(. (line 4)
I'm pulling my work off this link: Storing Data in Google Spreadsheets and also the Ui Service section listed under Building User Interfaces.
Anybody seeing what I'm doing wrong in these two lines?
setActiveSheet should be used only with the spreadsheet displayed by the UI, a sheet in a spreadsheet you have opened in your browser.
With SpreadsheetApp.openById you are opening a spreadsheet to access its data, but it doesn't open in your browser. It hasn't an UI.
I found this comments in https://developers.google.com/apps-script/class_spreadsheetapp?hl=es-ES#openById :
// The code below opens a spreadsheet using it's ID and gets the name for it.
// Note that the spreadsheet is NOT physically opened on the client side.
// It is opened on the server only (for modification by the script).
var ss = SpreadsheetApp.openById("abc1234567");
Some examples assume your script is running into your spreadsheet. It's not your case, because you are running a script as a service, which should have its own User Interface.
I think #megabyte1024 addresses the syntax errors, but in answer to your comment to #YoArgentina:
Do you happen to know of a way to access data on different tabs then
through a service not running inside the Spreadsheet?
Does this sort of help?
var ss = SpreadsheetApp.openById(SPREADSHEET_ID_GOES_HERE);
var sheets = ss.getSheets();
// the variable sheets is an array of Sheet objects
var sheet1A1 = sheets[0].getRange('A1').getValue();
var sheet2A1 = sheets[1].getRange('A1').getValue();
You need to access each sheet separately.
var ss = SpreadsheetApp.openById(SPREADSHEET_ID_GOES_HERE);
var sheet = ss.getSheets()[0]; // "access data on different tabs"
ss.setActiveSheet(sheet);
There is at least one problem in these two lines. The 1st one is that the setActiveSheet method parameters is a Sheet class object and the getSheetId method returns an integer value. By the way this method (getSheetId) is not documented. The 2nd problem can happen if the SpreadsheetApp has no active spreadsheet. In this case there is the "Please select an active spreadsheet first." error. Use the SpreadsheetApp.setActiveSpreadsheet method to set an active spreadsheet.