Google Sheets Script - save as PDF - Get Name from Cell - pdf

Ok, I'm 99% there thanks to a lot of other posts about how to do this.
What am I doing?
I have a google form. When that form is completed and the answers are in the respective google sheet I have another tab that has a template (with a bunch of formulas) that auto-populates pay rates for people. The first formula is the name and it is drive off of the Form Responses tab. The following script hides all other sheets, saves the one tab I want to a PDF, in the folder that I want (then unhides the other sheets).
The problem
When I run this as a test it works perfectly. The PDF that drops into the folder is named with the output from the cell E5 (which is a formula) pulling the person's name. However when I set the trigger to when a form answer comes in then everything is right (all the data on the sheet is right) just the name of the file is showing as "Yes". I'm so confused as to why it is "Yes". If I run the script right afterwards it is the name of the person from the cell E5..... Here is my code.
Is the trigger to fast to pull the response? I don't think it can be as the output on the PDF is right.
function topdf() {
var foldersave=DriveApp.getFolderById('1dSOK6bBCRyEO0_fTuuMFH9sNa4wAWYW8');
var d= new Date();
var request = {
"method": "GET",
"headers":{"Authorization": "Bearer "+ScriptApp.getOAuthToken()},
"muteHttpExceptions": true
};
var key='1-e8dhOOZ5zwfeIBSTSH7yFNKgxVTxwqZvqcTNtQUQrA';
var fetch='https://docs.google.com/spreadsheets/d/'+key+'/export?format=pdf&size=letter&portrait=false'
var ss= SpreadsheetApp.getActiveSpreadsheet();
var sheets=ss.getSheets()
var name=ss.getRange("E5").getValue()
sheets[0].hideSheet()
sheets[1].hideSheet()
sheets[2].hideSheet()
sheets[3].hideSheet()
sheets[4].hideSheet()
sheets[5].hideSheet()
sheets[6].hideSheet()
var pdf = UrlFetchApp.fetch(fetch, request);
pdf = pdf.getBlob().setName(name);
var file = foldersave.createFile(pdf)
sheets[0].showSheet()
sheets[1].showSheet()
sheets[2].showSheet()
sheets[3].showSheet()
sheets[4].showSheet()
sheets[5].showSheet()
sheets[6].showSheet()
}

You're calling getRange() E5 from Spreadsheet ss, which may or may not be the sheet you're looking to get the range from. E5 may be yes from an another sheet. Try
ss.getSheetByName('Sheet1').getRange('E5')

Related

Stop Google Sheets from creating link automatically

I am trying to write some text in Google Sheets, specifically some URLs. I need that because I am trying to explain to an agency the new tracking we are implementing.
I have the URL in a cell, and I went to have some caracters in red to highlight the changes, and leave the rest in black.
However, as soon as I modified my stuff in the formula bar, if I press enter or try to save the edit, Sheets automatically detects a link so it put everything in light blue and underlined, which is exactly what I don't want him to do.
I know there is a "stop detecting links automatically" thing in Microsoft Word and Google Doc but I can't find it in Sheets settings.
Any solution?
immediately after typing the link after its been cast to a hyperlink, if you then press backspace a single time the conversion to link will be undone
I've double checked the behavior of URLs in Google Sheets and I can see that even when you remove the hyperlink of a URL in a cell (via Remove link option), it will still automatically reappear once you edit the cell of that URL.
Recommendation:
According to an answer from this post How do I stop automatic hyperlinks in google sheets?, one of the community member have recommended to use a different format to the URLs to stop the cell from automatically creating hyperlinks. And this recommendation worked on my testing.
With that being said, I have crated a workaround using a custom bound script, where it will automatically format all URLs (it'll add "//" at the beginning of each URLs) on a sheet and then it will visually hide the format for a cleaner look for your convenience. After that, the hyperlinks will no longer be auto-created on the URLs. The catch on this method is that users will need to remove the "//" at the beginning of the URLs to access them.
Sample
Sample sheet with URLs on Column A:
Custom Bound Script:
function onOpen() { //Creates a custom menu called "Hyperlink" at the top right of your spreadsheet file where you can run this script
var ui = SpreadsheetApp.getUi();
ui.createMenu('Hyperlink')
.addItem('Remove Hyperlink', 'addFormat')
.addToUi();
}
function addFormat() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var range = sheet.getRange("A1:A").getValues(); //CHANGE THIS RANGE IF YOUR URLS ARE IN A DIFFERENT COLUMN
var text = "//";
for(var x=1; x<=range.length;x++){
if(range[x-1]=="" || x==1){ //If it is cell 1 (the title of the column) or if it is an empty cell, it will be skipped for formatting
}else{
if(range[x-1][0][0] == "/"){ //If a cell has been already formatted (//), it will be skipped
}else{ //Formats new URL on the cell of Column (e.g. A)
sheet.getRange(x,1).clearContent().setValue(text+range[x-1]).setFontColor("black");
Logger.log("Done with "+text+range[x-1]+" on row"+ x);
hideFormat(x); //function to visually hide the "//" on each URLs
}
}
}
}
function hideFormat(row){ //Function to visually hide the "//" format at the beginning by coloring it to white font color
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("A"+row); //CHANGE THIS COLUMN IF YOUR URLS ARE IN A DIFFERENT COLUMN
var hide = SpreadsheetApp.newTextStyle()
.setForegroundColor('white')
.build();
var richText = SpreadsheetApp.newRichTextValue()
.setText(sheet.getRange("A"+row).getValue()) //CHANGE THIS COLUMN IF YOUR URLS ARE IN A DIFFERENT COLUMN
.setTextStyle(0, 2, hide)
.build();
range.setRichTextValue(richText);
}
After saving & running the script, click the Hyperlink > Remove Hyperlink on your Spreadsheet:
Here's the result:
Then, you can make any changes on the URL cells without hyperlinks being auto-created:
None of the existing answers actually provide a solution to the exact issue mentioned in the question, which is "[when] I press enter or try to save the edit, Sheets automatically detects a link so it put everything in light blue and underlined"
Pressing backspace as per #rexfordkelly's answer is only valid when the link is created during editing of the cell.
Here, the issue is that the link will be created when saving the cell after edition.
The only way I found to prevent this is to put the cursor outside of the text of the link.
Example:
Let's say ^ represents our cursor, and let this be our cell content:
my link: https://mywebsite.com
If you have your cursor e.g. here:
my link: htt^ps://mywebsite.com
or here (etc...):
my link: https://mywebsite.com^
the link will inevitably be created when saving the cell (i.e. hitting Enter).
However, if you have your cursor here (or anywhere else not on the link itself):
my l^ink: https://mywebsite.com
the link won't be created when pressing Enter.

Use onFormSubmit on a sheet to log each form edit

I have a form that stores responses on a sheet. The form is set to allow edits.
I need to track each time a user updates their version/copy of the form.
I've tried the following code. I noticed that e.values only seems to contain the new updated values (and the timestamp). I need the 2nd column to also contain the "Forum Name" (column B) value, even if it hasn't updated.
function copyUpdate(e) {
// triggered onFormSubmit
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Log");
// force the 2nd column to always contain "Forum Name" value
var newValues = e.values;
newValues[1] = e.namedValues["Forum Name"][0];
// Output the timestamp, Forum Name & any changed values
sheet.appendRow(newValues);
}
I'm probably making a really basic mistake, but I'm just not seeing it.
Any help would be most appreciated
Be Well
Apparently, e.namedValues also only contains the new edited values.
I had to search the other sheet for a row that matched the timestamp, and then copy that row to the new sheet. :(
TTFN

Export Google sheet to pdf without notes

Generally, can you disable Notes in a Google sheet temporarily?
More detail:
I can use GAS to export sheets to PDF, no issue there. But I've added a timestamp function which adds a 'Note' to a cell when it is edited using the OnEdit built in trigger. This is great because I can see when each cell was edited last without messing with revision history.
Unfortunately when I print to PDF, manually or via GAS, I get this ugly last page that includes each comment listed numerically. Anyway around this besides deleting the notes when I want to export? number of pages will be variable so I can't try to remove all but the first page each time.
There's probably a better way, but I would copy the Spreadsheet, delete all notes, export to PDF and delete the copied Spreadsheet.
You can make sure that you add all your "comments" in the same column, and then hide that column(s) before downloading as PDF.
But the best advice is to use the "Comment" feature of Google Sheets, which allows you to add Comments linked to a cell or range, which are not visible when you download as a PDF. You can insert a "comment" by going to the desired cell and from the menu "Insert" choose the item "Comment", or simply right click the cell and choose "Insert Comment".
So, yes, there is not only a way, but multiple ways of doing this. (Sad to see people respond negatively, vaguely or inaccurately without proper knowledge or even trying to solve the problem, understanding the question or attempt an answer).
I Created a simple script to do it for me:
Go to tool->script editor to create it, then copy/paste the code.
After you add the Menu, you need to refresh to see it.
Use: Click on Custom Utilities->Copy No Notes then type in the name of the sheet, it will create "copy of sheet" that has no notes.
Warning: This script deletes a page named "Copy of [sheet]" where [sheet] is the name of the text you type in. (if it exists)
function onOpen(){
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Utilities').addItem('Copy No Notes', 'copyNoNotes').addToUi();
}
function copyNoNotes(){
var ui = SpreadsheetApp.getUi();
var response = ui.prompt('Copy Sheet', 'Source Sheet?', ui.ButtonSet.YES_NO);
if (response.getSelectedButton() == ui.Button.YES) {
var source = response.getResponseText();
var newSheet = SpreadsheetApp.getActive().getSheetByName("Copy of " + source);
if(newSheet != undefined){
SpreadsheetApp.getActive().deleteSheet(newSheet);
}
var sheet = SpreadsheetApp.getActive().getSheetByName(source);
newSheet = sheet.copyTo(SpreadsheetApp.getActive());
newSheet.clearNotes();
}
}

google spreadsheet feeds with multiple worksheets

How to get feeds from multiple sheets using google spreadsheet feeds api?
Below URL fetches the feeds from first sheet only. In my spreadsheet I have 3 work sheets and I want to fetch remaining sheets data as well.
https://spreadsheets.google.com/feeds/list/XXXXMYKEYXXXX/od6/public/values?alt=json-in-script
How to fetch them?
I tried below without success:
https://spreadsheets.google.com/feeds/list/XXXXMYKEYXXXX/od7/public/values?alt=json-in-script
Note od7 instead of od6
UPDATE
URL for the spreadsheet feed is
https://spreadsheets.google.com/feeds/list/1c53H0piyduOV6zRwS54A7MDZ3SooJOmj4O52Xd0dyIA/od6/public/values?alt=json-in-script
In the spreadsheet I have TopicA,TopicB,TopicC sheets. Feeds response contains TopicA information only.
It seems worksheet IDs are numbered from 1 to n and not like od6, od7.
Using below urls, I was able to get individual worksheet's data
https://spreadsheets.google.com/feeds/list/1c53H0piyduOV6zRwS54A7MDZ3SooJOmj4O52Xd0dyIA/1/public/values?alt=json fetches first worksheet
https://spreadsheets.google.com/feeds/list/1c53H0piyduOV6zRwS54A7MDZ3SooJOmj4O52Xd0dyIA/2/public/values?alt=json 2nd sheet
https://spreadsheets.google.com/feeds/list/1c53H0piyduOV6zRwS54A7MDZ3SooJOmj4O52Xd0dyIA/3/public/values?alt=json 3rd sheet and so on
Note the /1, /2 and /3 after the key (1c53H0piyduOV6zRwS54A7MDZ3SooJOmj4O52Xd0dyIA) in the url
Per the Google Spreadsheets API:
To determine the URL of a given spreadsheet's worksheets feed, find
that spreadsheet's entry in the spreadsheets feed, as described in the
previous section. Then examine the link element that has
rel="http://schemas.google.com/spreadsheets/2006#tablesfeed". That
element's href value provides the URL for that spreadsheet's
worksheets feed.
To request a list of worksheets in a given spreadsheet, issue a GET
request to that URL, with an appropriate authorization header:
GET https://spreadsheets.google.com/feeds/worksheets/key/private/full
The returned result contains a URL for each worksheet in that spreadsheet, which you can then query to pull information from each worksheet you want to get data from. So in your example, od6 is a valid worksheetId, but you must discern the other worksheetIds from the spreadsheet's feed.
Building on suman j's answer, here's a way to load multiple sheets, regardless of how many there are, using jQuery.
Load the spreadsheet's main JSON feed, find the url for each sheet in the JSON that's returned, tweak the url a bit, then load that one as well. Then use ajaxStop to take any action that needs to happen after they all finish loading.
$(function(){
var feedurl_start = "https://spreadsheets.google.com/feeds/";
var feedkey = "1c53H0piyduOV6zRwS54A7MDZ3SooJOmj4O52Xd0dyIA";
$.getJSON(feedurl_start+"worksheets/"+feedkey+"/public/basic?alt=json", function(sheetfeed) {
$.each(sheetfeed.feed.entry, function(k_sheet, v_sheet){
var sheeturl = v_sheet.link[0]["href"]+"?alt=json";
sheeturl = sheeturl.replace("basic", "values");
var sheet_title = v_sheet.content["$t"]; // to know which sheet you're dealing with
console.log(sheet_title);
$.getJSON(sheeturl, function(sheetjson){
console.log(sheetjson);
});
});
});
});
// Since you're making multiple AJAX calls, use ajaxStop
// to do whatever you need to do AFTER everything is loaded
$( document ).ajaxStop(function() {
// now all your data is loaded, so you can use it here.
});

I want to copy the format of one Spreadsheet in google docs do another spreadsheet. Is this possible?

I'm working on a feedback system for my math students and have a matrix that shows what points they have gotten on a test.
I have several sheets in this document with one sheet per student. I have also made one spreadsheet per student that i have put in a shared folder on Google Drive where the students only have viewing rights.
What I want to do is copy the entire sheet from my master document to the student's spreadsheet. This is all fine if I use the import range function however with that the formatting doesn't follow.
Is it possible to use a script with the commands getBackgroundColor() and setBackgroundColor() to transfer the backgroundcolors from the master sheet to the students sheet?
I started with something like this:
function getColor() {
var sheet = SpreadsheetApp.openById("0ApOkn5XcO_GDdFd4SDBaaFpLSEUxXy1vN2pnNHBpYnc");
var ss=sheet.getSheetByName("Student1");
var r=ss.getRange("A1:R34");
var color = ss.getBackgroundColors();
That's about as far as I get. Anyone have ideas?