Opening spreadsheet in google sheets - google-apps-script

I'm trying to automate the creation of a spreadsheet in Google. I'm able to create and edit the spreadsheet just fine. The problem I'm having is opening.
function CoS(){
var Sheet = SSheet.getActiveSheet();
var bill = Sheet.getActiveCell().getValues();
var nSheet = NewCoS(bill);
var file = DocsList.getFileById(nSheet.getId());
var ss = SpreadsheetApp.open(file); //Doesn't work the way I need it to
Browser.msgBox(ss.getName());
}
I've tryed .openByUrl and .openById. In the documentation I read that these are for opening in the background but .open seems to do the same thing. However the documentation doesn't state explicitly that that is what it's meant for. Browser.msgbox() works so it seems logical that the file is getting opened in the background. I also can't find anything like Spreadsheet.visiblity() or Spreadsheet.show() as I would expect in excel.
I've even looked in other libraries like Drive and DocsList.
Is there a way to open my spreadsheet through script so that the user can see it?

Opening a spreadsheet means "get read and write access to that sheet", it does not mean "show this spreadsheet in my browser".
If you need to get such a functionality then use a href link (in HTMLService) or an anchor widget (in UiApp) that will redirect you to another browser tab/window with that spreadsheet.
Note also that there is no SpreadsheetApp.open method, use the autocompletion in the script editor to be sure about available methods in Google Apps Script.

Related

Exception when openById of Spreadsheet in Google App

I implemented a Google Slide Add On which makes a copy of a linked spreadsheets and then opens it (to retrieve all charts in this sheet).
This is the code in question:
// id is the spreadsheet id
var sheetFile = DriveApp.getFileById(id);
var copy = sheetFile.makeCopy(sheetFile.getName() +'_'+ 'Copy');
Utilities.sleep(200);
// exception happens here
var sheet = SpreadsheetApp.openById(copy.getId());
Unfortunately this results for some sheets in the following error:
Exception: Service Spreadsheets failed while accessing document with id *************.
So I tried to find out why some spreadsheets work and some not and it lookls like that it does not work for not converted spreadsheets from excel. So I tested it by converting one of those excel sheets into a Google Sheet by Menu->File->Convert to Google Sheet.
This did not work... So I played around by replicated the Google Slide with the charts and I found out that I was not able to import the chart to a google slide from this converted spreadsheet. Even if I just create a new chart in this sheet everytime I go to the Slide App and try to insert the chart from this spreadsheet, no charts were displayed in the selection window.
It looks like that something went wrong when converting the excel to Google Sheets, I tried to do the conversion step multiple times... but no change.
[Edit]
I also tried to disabling V8 support.
[Edit2]
so for some reason I can now use SpreadsheetApp.openById(copy.getId()); when the spreadsheet was converted to google sheet. But as I mentioned before, it is still not possible to add any charts manually from this Google Sheet to presentation...
The error message Service Spreadsheets failed while accessing document with id ID you are receiving might in fact be related to this known issue on Google's side.
I suggest you star the issue here as all the updates regarding this will be posted there.
If it's a glitch I'd try to chain the commands this way:
var sheetFile = DriveApp.getFileById(id);
var copy_name = sheetFile.getName() +'_'+ 'Copy';
var sheet = SpreadsheetApp.openById(sheetFile.makeCopy(copy_name).getId());
This way the command openById won't fire before the file will be copied.

Google Apps Script Error: "You do not have permission to call openById"

I am trying to use a Google Script that I found on GitHub. (It is Posted Below.) It is supposed to merge data from Google sheets into a Google Doc. However, when I try to run the script I get an error: "You do not have permission to call openById". I have researched the problem and the information is conflicting. But, I have tried the following:
Manually run the function in script editor before adding the trigger to Google sheet.
Authorized the script to access my Google Docs data.
Set the triggers for the function to "On Form Submit"
Added the script to my Google Sheet and ran it from the menu as instructed: Merge --> Fill Template
I continue to get the error. I see that there are other people having the same problem, but the answers provided so far have not solved the issue. Any help would be greatly appreciated.
function doMerge() {
var selectedTemplateId = "1foobarfoobarfoobarfoobarfoobarfoobar";//Copy and paste the ID of the template document here (you can find this in the document's URL)
var templateFile = DriveApp.getFileById(selectedTemplateId);
var mergedFile = templateFile.makeCopy();//make a copy of the template file to use for the merged File.
mergedFile.setName("filled_"+templateFile.getName());//give a custom name to the new file (otherwise it is called "copy of ...")
var mergedDoc = DocumentApp.openById(mergedFile.getId());
var bodyElement = mergedDoc.getBody();//the body of the merged document, which is at this point the same as the template doc.
var bodyCopy = bodyElement.copy();//make a copy of the body
bodyElement.clear();//clear the body of the mergedDoc so that we can write the new data in it.

Publishing / sharing a Google Sheet via Github

I have a Google Sheet. It has a custom script (read: set of functions) associated with. I'd like to share this sheet template (i.e., tool), not with colleagues (i.e., adding them via email address as is a traditional Google drive share) but with anyone who would like a copy for themselves to use it for themselves (i.e., not my copy, their own copy). Ideally, I'd repo this project / tool on GitHub (or similar) and let them grab it there.
I can "Download As..." the sheet but the script doesn't stay "attached". Are such scripts now what Google considers Add-ons? If so, how to I keep the sheet + script as a "whole".
Also, as a temporary workaround, I tried to copy / paste the script from my working copy to another copy of the sheet (created via Download as and then opened again under a diff Google accnt). However, that didn't go as planned either. There's a function within my scrip that checks to make sure the sheet is on the first tab / sheet (i.e., getActiveSheet().getSheetId() == 0). This works on my dev / working copy. However once I copy / paste the SheetId return a 7 or 8 digit #. Is there a way to keep the SheetId relative to the sheet, and not all sheets (or whatever that Id represents.)
Note: I'm by no means a Google Sheets expert. This was just a side project for myself that I ended up building out to the point of wanting to share it with others. Please presume I know even less than you probably think I know. Thanks :)
To fix your problem with finding the first tab / sheet, use the sheet index instead of the sheet id. So instead of getActiveSheet().getSheetId() == 0, it'll be getActiveSheet().getIndex() == 0 instead.
As for downloading the script - it looks like you've created a container-bound script. There are two types of scripts that you can create, standalone and container-bound scripts. (See Google's explanation here). Standalone scripts are created by going directly to script.google.com, but I'm guessing (please correct me if I've assumed wrong) that you clicked Tools->Script editor, so that the script is locked to that specific spreadsheet. That's fine, but a) it means like you can't download it separately through Google Drive as I originally suggested, and b) when you're download the sheet, it downloads it as an Excel worksheet (which doesn't support Google App Script, so of course the script doesn't come with it).
Here's my suggestion for your use case:
Instead of downloading the spreadsheet, make a new copy of it named yourspreadsheet_public or something along those lines by going to File -> Make a Copy. (You can potentially skip this step if you just want to make your personal spreadsheet available to the world.)
Make the copy available to anyone to view by clicking Share -> Change -> Anyone with the Link (or Public on the Web) -> select "Can View" from the dropdown -> Save.
Now, you can distribute the link to whoever wants it. Anyone who has access to the file is able to make a copy in the same way you did in the first step to their own Google Drive, where they'll be able to edit their own private copy, including your script.
Let me know if that helps!
I don't understand why you want to use an external service to make copies of a spreadsheet. Since Google Scripts only run in Google spreadsheets I don't see any use case where it can be useful... but that's not the point, you do what you want.
That said, the easiest (and probably the only) one would be to share the document with someone and create an onOpen function that suggests to create a copy of it. This script should be executed after the required authorization and the copy will be their own copy, without any link to your G account anymore (which was the goal if I understood you well).
More simple and straightforward than that I can't imagine.
To avoid that their copy keeps the same onOpen behavior just setup a variable stored in userProperties so that when present this part of the onOpen doesn't execute.
This is a workflow I have already used and it works nicely.
edit :
I can suggest a completely different workflow to let other people get a personal copy of your SS.
Here is a test , give it a try and let me know if you're interested.
EDIT2 : since the other answer provides a similar workflow I decided to show the code I use in this answer to make that process more userfriendly.
I use 2 webApps :
one that runs as "me" that have access to my drive and runs without authorization for its user and that does nothing else than show a warning and a link.(accessible to anyone even anonymous)
And a second one that creates the copy and needs authorization to allow the SScopy creation in the user's own drive + a couple of links.(runs as the user accessing the app)
Code below (in 2 distinct projects of course) :
// APP 1 :
function doGet(){
var app = UiApp.createApplication().setTitle('Demo-App');
var link = app.createAnchor('Click this link to create your own copy <br>of my spreadsheet.<br>You will be asked for authorizations<br>tocreate a spreadsheet in your drive',true,'https://script.google.com/macros/s/AKfycbwQ5s_WWrsWXx_umZ1v91XGnm3RaO2Z7UQSXNiWFiaTwGuXIXqq/exec');
app.add(app.createVerticalPanel().setStyleAttribute('padding','50px').add(link));
return app;
}
// APP 2
function doGet(){
var ss = SpreadsheetApp.openById('0AnqSFd3iikE3dGNEUDdoLWhUZl9sZ3Z2Zm5XbjZzTkE');
var copy = ss.copy(ss.getName()); / the SS is shared to "anyone with the link can view"
var app = UiApp.createApplication().setTitle('SSCreate');
var panel = app.createVerticalPanel().setStyleAttribute('padding','50px');
panel.add(app.createHTML('A new spreadsheet has been created in your drive with name '+ss.getName()));
panel.add(app.createAnchor('Open it from <b>here</b>',true,copy.getUrl()));
panel.add(app.createAnchor('or from your own Drive','https://drive.google.com/?authuser=0#all'));
return app.add(panel);
}

How do I get a remote source to work with an autocomplete?

Is it possible to add an autocomplete in a google spreadsheet script with a remote source?
Below is one of my attempts to do so but I have no idea where to go from here (I am a newb to google scripts):
function my_autocomplete(){
var list = ['dog','doog'];
var app = UiApp.createApplication();
var suggestBox = SuggestBoxCreator.createSuggestBox(app,'autocompleter',200,list);
app.add(suggestBox);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
I've googled my heart out but can't find a single example of an autocomplete with a remote source that is compatible with Google Scripts...is it even possible?
(I don't have to use/modify the autocomplete example I have above, so if there's another approach I'm all ears! thx!)
Google suggestboxcreator and you will find this https://sites.google.com/site/scriptsexamples/learn-by-example/uiapp-examples-code-snippets/suggest-box. Use that library, thou it does the search server side. Make one with htmservice and do it client side so its faster. Write the selected value into the active cell of the active spreadsheet.

Creating a Mobile User Interface for Google Spreadsheet

Is it possible to make an HTML interface for a spreadsheet that doesn't run inside the spreadsheet? Basically I want to use the spreadsheet as a simple database.
I can't seem to find a way to do it in the documentation. I got this to work this way:
var ss = SpreadsheetApp.getActive();
function onOpen() {
var html = HtmlService.createHtmlOutputFromFile('index');
ss.show(html);
That opens my page automatically when I load the sheet, which is not a bad way to have it work, but I would rather run it from a separate page without having to know it is looking at a spreadsheet.
Also, this script doesn't work on mobile browsers which is an issue.
Is what I want to do possible currently? I have been looking at the documentation for a while without a clear answer.
I believe you will be wanting to deploy your script as a web app, rather than a "container-bound" script inside a spreadsheet.
As there will be no spreadsheet inherently associated with the web app, you would need to use the openById() method rather than getActive().