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();
}
}
Related
The issue I am facing is trying to automate my weekly occurrence of coping an entire Spreadsheet to make a copy of it. Each week I need to hit "File --> Make a copy --> share with same people" and after doing so on the copy I need to hit "Allow Access" multiple times for each table that requires access, if I do not do this, there is no data displayed.
So I am wondering if there is a way to create a copy of a Spreadsheet where the copy contains entirely plain text and no formulas or links that way all the data can be read as soon as a copy is made.
This could be a separate question, but if anyone also knows how to automate hitting the "allow access" button for multiple tables in the copy that would also be helpful.
*To give an idea of the layout, essentially I have a main Spreadsheet (the one I make a copy of) that references data from other Spreadsheets (that are linked to google forms), and then I make a copy of the main Spreadsheet, and in making this copy is where I am required to hit the access button for each table.
Answer:
You can do this with Apps Script.
Code Example:
function duplicateSpreadsheet() {
const idOfSheetToCopy = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
var file = DriveApp.getFileById(ifOfSheetToCopy).next()
const newFile = file.makeCopy()
SpreadsheetApp.openById(newFile.getId()).getSheets().forEach(function(sheet) {
sheet.getDataRange().setValues(sheet.getDataRange().getDisplayValues())
})
}
Code Rundown:
Define Template Sheet ID
Make a copy of the sheet using DriveApp
Get the ID of the newly created sheet and open it with SpreadsheetApp
Loop through all sheets in the new copy and replace all cell values for the cell's display value
Instead of pasting with "Ctrl+V" use "Ctrl+Shift+V" for pasting without formatting. This will ignore things like links, font, and font size.
Not sure about the allow access button.
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.
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')
I add rows to a Google Sheet via the API. For this, I use C# Google.API.Sheets.v4 NuGet package. I pretty much calculate the cells where I want to write in myself.
My problem is that when I reach the end of the worksheet, I don't know this in my application. There doesn't seem to be an error or anything. Data is just lost!
When I use my sheet without the API I would notice and just press this button:
I want to either add 1 row before writing one row in my application or recognize that the end of the worksheet is reached.
The code looks pretty much like the update code provided here:
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/update
I use the spreadsheets.values.update functionality and write into a bottom row that doesn't yet exist
So again in short: I need the "more rows at bottom" functionality somehow in my application
Bonus Question: I lost some data because of this problem. Any ideas on how to recover it?
I found a sattisfying workaround. Instead of using the spreadsheets.values.update functionality I use the spreadsheets.values.append functionality as shown here.
It is important to set it to InsertDataOptionEnum.OVERWRITE to mimic the behaviour or you'll end up having each new cell in a separate row.
OLD ( uses .Update() )
SpreadsheetsResource.ValuesResource.UpdateRequest request = sheetsService.Spreadsheets.Values.Update(valueRange, spreadsheetId, range);
request.ValueInputOption = SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.USERENTERED;
NEW ( uses .Append() )
//use AppendRequest instead of UpdateRequest to avoid lost lines on end of sheet
SpreadsheetsResource.ValuesResource.AppendRequest request = sheetsService.Spreadsheets.Values.Append(valueRange, spreadsheetId, range);
request.ValueInputOption = SpreadsheetsResource.ValuesResource.AppendRequest.ValueInputOptionEnum.USERENTERED;
request.InsertDataOption = SpreadsheetsResource.ValuesResource.AppendRequest.InsertDataOptionEnum.OVERWRITE; //overwrite when writing cells or it will be new line per cell
I have been writing a code to build a custom document for weekly reporting. I had it set to create a new doc, build the tables, format everything, insert a logo, etc., and I hit a wall when Word crashed every time I tried to resize the logo through VBA. It then occurred to me that I was doing this the wrong way anyway, and that I should build a template, have the code open that template, and then insert the changes directly into that document.
When I add text to the range I need, everything below is deleted. I have three lines of a header; the third line is variable and will change each week. Below that I have three tables, some cells of which will be updated each week. Right now I am just stuck at the third line of the document.
Here is an example of what I have. It is extremely short because I started anew and hit a dead end immediately.
Dim Template as Document
Set Template = ThisDocument
Dim InsertSpot as Range
Set InsertSpot = Template.Range(46)
InsertSpot.Text = "Hello"
When I run that, everything is deleted below "Hello".
I tried some different things, such as:
Set InsertSpot = Template.Range(46,50)
InsertSpot.InsertAfter "Hello"
That doesn't work; it just adds "Hello" to the first cell of the first table.
I feel silly being stuck at such an elementary part, but I honestly have no idea what to do here. Everything I looked at online talked about how to insert text at a bookmark without deleting the bookmark. I just want to enter text, period.
Any thoughts?
I found the answer. I did the following:
Dim Template as Document
Set Template = ThisDocument
Dim InsertSpot as Range
Set InsertSpot = Template.Range(46, 46)
InsertSpot.Text = "Hello"
I had to list both the starting AND the ending character so that the inserted text would not bleed over into the rest of the page. Hope I helped someone else who is having a similar problem. Unfortunately Word VBA is pretty lacking in support and clear explanations.
other alternatives can be
ThisDocument.Range(46).InsertBefore "Hello"
ThisDocument.Tables(1).Range.InsertBefore "Hello"
ThisDocument.Paragraphs(3).Range.InsertAfter "Hello"