Google Spreadsheet API Query Tabs - google-sheets-api

Can I query my spreadsheet tabs via tab index instead of the tab title or tab id?
https://sheets.googleapis.com/v4/spreadsheets/{my sheet id}/values/'Hero Video Copy Section'?key={secret code}
'Hero Video Copy Section' is the title of the tab, but I want to find the tab via index.

You may refer with this SO thread(quite old question). Given example is if the row number is in A1, and the column number is in A2:
=OFFSET(A1;A1-1;A2-1)
=INDIRECT("R"&A1&"C"&A2)
=INDEX(A1:400000;A1;A2)
Also, you can check this documentation about Google Apps Script which uses an array to log the name of the second sheet.
// The code below will log the name of the second sheet
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
if (sheets.length > 1) {
Logger.log(sheets[1].getName());
}

Related

Delete data from a sheet in google sheets with API - using Postman

I would like to erase all the data of a sheet in a google sheet
via the googlet sheets APIs: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/clear
Unfortunately I can not select the id of my sheet.
I used the proposed method: POST https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetid}/values/{range}: clear
but it only removes the data from my first sheet.
How can I put the id of my other leaves in the method?
My google sheets ID
My first sheets in my google sheets
ID of my second sheets
My second sheets in my google sheets
From your reply, the request of "Method: spreadsheets.values.clear" is as follows.
POST https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}:clear
spreadsheetId : The spreadsheet the updates were applied to.
range: The range (in A1 notation) that was cleared. (If the request was for an unbounded range or a ranger larger than the bounds of the sheet, this will be the actual range that was cleared, bounded to the sheet's limits.)
In this case, it is not required to use the sheet ID. The sheet name is used.
From your showing images, it seems that the sheet names of your 1st and 2nd sheet are Feuille 1 and Feuille 2, respectively. For example, when you want to clear 2nd sheet of Feuille 2, please use the following request.
POST https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/Feuille%202:clear
Note:
For example, when you want to retrieve the sheet names from a Google Spreadsheet, you can use "Method: spreadsheets.get". Ref
Reference:
Method: spreadsheets.values.clear

Is there a way to copy an entire Spreadsheet with only values and no formulas/links (Google Sheets)?

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.

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.

How to copy data validation in a relative way, specifically list from range (with or without scripts) Google Sheets

I have created a spread sheet to track appointments. Within this spread sheet I have dynamic dependent drop down lists, so the choice from list 1 will populate the options in list 2. This is as follows:
Cell C2: Client - Client 1 or Client 2. (this is for the use of the example, the actual lists will expand.)
If cell C2 = Client 1 then the address drop down is as below:
Cell C3: Address - Address 1 or Address 2.
If cell C2 = Client 2 then the address drop down is as below:
Cell C3: Address - Address 3 or Address 4.
The data validation for the client list is simple because this is constant and can be copied from column to column. The data validation for the dependent address list, however, can not be copied across multiple columns as it will always refer to column C and lose connection with the relative client list.
The actual data validation for the cell C3 (Address List) is below:
Cell Range = 'DIARY (V-2.1)'!C3
Criteria = 'DIARY (V-2.1)'!C53:C55
The cells C53:C55 are populated by a filter formula which will sort the relevant addresses dependent on the choice of client in cell C2, this in turn populates the address list in C3.
It may be worth noting that I have 10 sets of these appointment slots per column (10 per day) so I have used a filter function for each of these separate appointments so they work independently, but even this is tedious so my need is to be able to copy the column (or just the data validation) from column C onward and have it stay relative to the filter functions in that column.
Please see the below link to the example spreadsheet and this will all make sense! In the example I have copied column C to column D and the data validation for the address list has detached for all ten appointment slots. (permission is free for all to edit.)
https://docs.google.com/spreadsheets/d/1sOlQEzG1D29RaY86YeR1Da--c8t94J-ZAGjv52U4dsY/edit#gid=1950191921
Note: These cells must be drop down lists - list from range - for the functionality of this specific spreadsheet.
If anyone can help with this it would be MASSIVELY appreciated as I have diligently scoured the forums and cannot find a solution. I did see this video (which is way over my head) that seems to accomplish this using java script:
https://www.youtube.com/watch?v=ZiYnuZ8MwgM&feature=youtu.be
Google Sheets does not currently have a built-in solution for copying/filling data validation references or formulas relatively. But somebody already wrote a nice script in this Google Docs forum post. To avoid just a link as an answer, I'm going to copy in the script and instructions here. Credit to AD:AM from Google Docs forum.
How to use their script:
Select a range of cells across which you want to copy a data validation rule, relatively
From the Validation+ custom menu, select the appropriate option (all references relative, columns absolute, or rows absolute)
The validation of the upper-left cell will be copied to the rest of the range
Link to original solution's example Google Sheets with script already included - you can save your own copy and then start using.
Or to recreate from scratch, here is the script.
function onOpen()
{
SpreadsheetApp.getActiveSpreadsheet().addMenu
(
"Validation+",
[
{name: "Copy validation (all relative references)", functionName: "copyValidation"},
{name: "Copy validation (relative rows, absolute columns)", functionName: "copyValidationColumnsAbsolute"},
{name: "Copy validation (absolute rows, relative columns)", functionName: "copyValidationRowsAbsolute"}
]
);
}
function copyValidation(rowsAbsolute, columnsAbsolute)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var r = ss.getActiveRange();
var dv = r.getDataValidations();
var dvt = dv[0][0].getCriteriaType();
if (dvt != SpreadsheetApp.DataValidationCriteria.VALUE_IN_RANGE) return;
var dvv = dv[0][0].getCriteriaValues();
Logger.log(dvv);
for (var i = 0; i < dv.length; i++)
{
for (var j = i ? 0 : 1; j < dv[0].length; j++)
{
dv[i][j] = dv[0][0].copy().withCriteria(dvt, [dvv[0].offset(rowsAbsolute ? 0 : i, columnsAbsolute ? 0 : j), dvv[1]]).build();
}
}
r.setDataValidations(dv);
}
function copyValidationRowsAbsolute()
{
copyValidation(true, false);
}
function copyValidationColumnsAbsolute()
{
copyValidation(false, true);
}
If you only need the relative copy for a single sheet, you can produce an ods with OpenOffice or LibreOffice that has a relative validation. This is done by removing the $ signs. If you then open load that sheet to your google drive and allow it to be converted to a google sheet, data validation range will be relative if you copy it anywhere in the same sheet. It is not relative if you copied it to another sheet in the same workbook or other google spreadsheets.
For example, if you make the validation for A7 to be the three cells to the right, you'll have something like follows:
Once you save it without the $ it is relative. Then when you upload it you have a sheet with relative validations.

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.
});