I'm trying to fill cells with hyperlinks to ranges in Google Sheets app script with the same desired outcome I would get had I done it in GUI. I managed to create hyperlinks to sheet in the form of "gid=..." with the ... being a sheetID. But I struggle to get the rangeID that is used when generating the hyperlink in GUI e.g.
HYPERLINK("#rangeid=1420762593";"'List 4'!F2:F15")
Is it possible to create hyperlinks to ranges in app script?
Yes, you can do this in App Script. Here's a very simple implementation where the HYPERLINK function is built and appended to a cell:
function hyperlinkRange() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Sheet1");
var sheet2 = ss.getSheetByName("Sheet2").getSheetId();
sheet1.getRange("A1").setValue('=hyperlink("#gid='+sheet2+'&range='+sheet1.getRange('A1:A10').getA1Notation()+'", "Click to jump to Sheet 2")');
}
You can combine this with loops to set a value of links across multiple sheets.
Custom functions
Use in a formula.
Simple range:
=HYPERLINK(getLinkByRange("Sheet1","A1"), "Link to A1")
Named range:
=HYPERLINK(getLinkByNamedRange("NamedRange"), "Link to named range")
The code, insert into the script editor (Tools > Script Editor):
function getLinkByRange(sheetName, rangeA1, fileId)
{
// file + sheet
var file = getDafaultFile_(fileId);
var sheet = file.getSheetByName(sheetName);
return getCombinedLink_(rangeA1, sheet.getSheetId(), fileId, file)
}
function getLinkByNamedRange(name, fileId)
{
// file + range + sheet
var file = getDafaultFile_(fileId);
var range = file.getRangeByName(name);
var sheet = range.getSheet();
return getCombinedLink_(range.getA1Notation(), sheet.getSheetId(), fileId, file)
}
function getDafaultFile_(fileId)
{
// get file
var file;
if (fileId) { file = SpreadsheetApp.openById(fileId); }
else file = SpreadsheetApp.getActive();
return file;
}
function getCombinedLink_(rangeA1, sheetId, fileId, file)
{
var externalPart = '';
if (fileId) { externalPart = file.getUrl(); }
return externalPart + '#gid=' + sheetId + 'range=' + rangeA1;
}
Here is another example. Hopefully, it is clean and self-explanatory
function hyperlinkRange(shDest,rgDest,shSrc,rgSrc,linkText) {
// get the spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet()
// get the destination sheet id
var idDest = shDest.getSheetId()
// link the range
var formula = '=hyperlink("#gid='+idDest+'&range='+rgDest+'","'+linkText+'")'
shSrc.getRange(rgSrc).setValue(formula)
}
In case you want to create a link to another sheet which will open the sheet in the same browser tab here is what you want to do:
1. Get the id of the sheet. Check the link in your browser and you will see #gid=x where x is the sheet id
2. Then you want to set the formula (hyperlink) to the cell and make it show as a hyperlink
SpreadsheetApp.getActiveSheet().getRange("A1").setFormula('=HYPERLINK("#gid=X","test")').setShowHyperlink(true);
If you don't use setShowHyperlink(true) it will be shown as a regular text.
Related
I've searched extensively for an answer to this, but have not had much luck. I think it should be a fairly simple answer. Here's what I'm trying to do:
I have a list of (other) Google Sheets document URLs in a Google Sheet.
I'd like to have a simple function that loads the URL in each line and returns the file name.
To illustrate, if the URLs are in A2:A10, a user could input a custom function like =GetFileName(A2) and it would return the file name corresponding to the Google Sheet URL that is in A2.
Here's the code that I have thus far, but it's returning an error, " TypeError: SpreadsheetApp.openByURL is not a function (line 3)."
function getFileName(fileURL) {
var GetFile = SpreadsheetApp.openByURL(fileURL);
var GetName = GetFile.getName();
return GetName;
}
UPDATE *************
Here's the code that worked for me. Basically, it loops through the sheet with IDs to pull file names. Not the most efficient, but works for relatively short lists just fine.
function getFileName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// DocumentIDs are listed in the 'tool' sheet
var targetSheet = ss.getSheetByName("tool");
// Find the last row
var LastRow = targetSheet.getLastRow();
//Loop Begins
//Initializing variable assumes that the first valid Drive ID is in the 3rd row.
for(var i = 3; i < LastRow; i++) {
// Get the Document ID. This gets the Document ID
var LookupID = targetSheet.getRange(i,1).getValue();
// Get the Filename
var FileOpen = SpreadsheetApp.open(DriveApp.getFileById(LookupID));
var FileName = FileOpen.getName();
// Write the FileName in the second column
targetSheet.getRange(i,2).setValue(FileName);
Logger.log(i);
Logger.log(LookupID);
Logger.log(FileName);
}
}
Suggestion:
You can try this script together with using clickable image to act as a button for the function to run the script below:
function convertURLtoSheetName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var cell = ss.getActiveCell().getValue();
var getSheetName = SpreadsheetApp.openByUrl(cell).getName();
var seturl = SpreadsheetApp.newRichTextValue().setText(getSheetName).setLinkUrl(cell).build();
ss.getActiveCell().setRichTextValue(seturl);
}
Here is how you assign a script function to an image:
Custom Functions Cannot open other spreadsheets (SpreadsheetApp.openById() or SpreadsheetApp.openByUrl()).
reference
I have a Spreadsheet with a DASHBOARD + multiple (300+) sheets (within the same spreadsheet). Within the DASHBOARD I have a range column with the names of all sheets.
I'd like to automatically hyperlink all cells to sheet with corresponding name.
Example:
Try this:
function convertToLinks() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("DASHBOARD");
var range = sh.getRange("A11:A15");
var data = range.getValues();
var formulaArr = [];
data.forEach(sheet => {
var targetSheet = ss.getSheetByName(sheet[0]);
if(targetSheet){
var url = ss.getUrl() + '#gid=' + targetSheet.getSheetId();
formulaArr.push(['=HYPERLINK("'+ url +'","'+ sheet[0] +'")'])
}else{
formulaArr.push([sheet[0]]);
}
})
range.setValues(formulaArr);
}
This script above will convert cells A11:A15 to hyperlinks of the corresponding sheets.
Example:
Before:
After:
References:
Range.setValues()
Sheet.getSheetId()
Spreadsheet.getSheetByName()
You do not need hyperlinks to quickly jump to another sheet. Instead, use the name box. It is located in the formula bar to the left of the ƒ𝑥 symbol.
Click the name box and type part of a sheet name to quickly locate that sheet, then press Enter to go to the sheet.
Try this script, but also add search for the cell you need to go to (this can be done by a formula in column C) or filter based on some more info ...
function onEdit(event){
var sh = event.source.getActiveSheet();
var cel = event.source.getActiveRange();
if (sh.getName()=='DASHBOARD' && cel.getColumn()==2 && cel.getRow()>1 && cel.getValue()){
try {
cel.setValue(!cel.getValue())
// add the right destination in the targeted sheet ...
SpreadsheetApp.getActiveSpreadsheet().getSheetByName(cel.offset(0,-1).getValue()).activate()
}
catch(err){
}
}
}
I'm in a situation where I need to send data to specific tabs(sheet) in a google sheet file (basically it's a G.Sheet file with one sheet that is a "template").
two cases: a/ the needed sheet exists then just append the data in that one, if not then use a specific sheet (template) copy it to create the new sheet as a new tab and append in it the data sent.
Each new sheet get its name as a parameter in the flow of data to be appended.
I'm really confused and know where to start and hope I'm clear enough.
So far I have this little code (not including the copying of the template cuz I don't know how to do it).
// pseudo is the name of the sheet in the file
function doGet(e) {
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/IDXXX/edit#gid=0");
var sheet = ss.getSheetByName(e.pseudo);
addData(e,sheet);
}
function doPost(e) {
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/IDXXX/edit#gid=0");
var sheet = ss.getSheetByName(e.pseudo);
addData(e,sheet);
}
function addData(e,sheet) {
//some data to append in the e.pseudo sheet
var id = e.parameter.id ;
var date = e.parameter.date ;
var textRef = e.parameter.textRef ;
var niveau = e.parameter.niveau ;
var cycle = e.parameter.cycle ;
var vitesse = e.parameter.vitesse ;
var reference = e.parameter.reference ;
sheet.appendRow([id,date,textRef,niveau,cycle,vitesse,reference]);
}
I would have thought e.psuedo should have been e.parameter.psuedo
You can refer to this sample code on how to create a new sheet from a template sheet. Assuming your sheet name can be obtained in e.pseudo or in e.parameter.psuedo as what #Cooper advised.
// pseudo is the name of the sheet in the file
function doGet(e) {
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/IDXXX/edit#gid=0");
var sheet = ss.getSheetByName(e.pseudo);
// Sheet doesn't exit, create new sheet from a template
if (sheet == null) {
// Select "template" sheet and copy to the current Spreadsheet
sheet = ss.getSheetByName("template").copyTo(ss);
// Rename the copied template sheet
sheet.setName(e.pseudo);
}
addData(e,sheet);
}
What it does?
getSheetByName(name) will return null if the sheet name doesn't exist. Select your template sheet and use copyTo(spreadsheet) to create a copy in your destination spreadsheet.
rename the newly copied sheet based on your input sheet name using setName(name)
Note:
just replace the name of your template sheet
I'm trying to run a google apps script which takes a series of importrange functions and puts them into an arrayformula query. I've successfully created a cell which actively accumulates the correct links for use in the importrange and puts it into a cell as a string. All I need the script to do is to copy that string and paste it as a formula in another cell. I can do this manually pretty easily, but I'd like to be able to set it up on a timer so it does it automatically on a certain time period.
As far as I've gotten is below and it doesn't work at all:
function Update Import Ranges() {
var spreadsheet = SpreadsheetApp.getActive();
var source = spreadsheet.getRange('B2').activate();
spreadsheet.getCurrentCell('B3').setFormula(???);
spreadsheet.getRange('B3').activate();
};
accumulates the correct links for use in the importrange and puts it into a cell as a string
The importrange() function only accepts two parameters: one for the spreadsheet to read from, and another to specify which range in the spreadsheet to return. To read from several spreadsheets and/or ranges with importrange(), you will have to create several formulas.
Alternatively, use an Apps Script function that mimics importrange() but supports multiple spreadsheets and ranges, such as the ImportMultipleRanges() function. You could call it like this:
function updateDataFromOtherSpreadsheets() {
var rangeToUpdate = "All Data!A2";
var sourceSpreadsheetKeysRange = "Config!B2:B5";
var sourceSpreadsheetDataRange = "Config!C2:C5";
var add_spreadsheet_name_prefix = false;
var add_sheet_name_prefix = false;
var ignore_blank_rows = true;
var ss = SpreadsheetApp.getActive();
var spreadsheet_keys = ss.getRange(sourceSpreadsheetKeysRange).getValues();
var range_strings = ss.getRange(sourceSpreadsheetDataRange).getValues();
var data = ImportMultipleRanges(spreadsheet_keys, range_strings, add_spreadsheet_name_prefix, add_sheet_name_prefix, ignore_blank_rows);
ss.getRange(rangeToUpdate).offset(0, 0, data.length, data[0].length).setValues(data);
}
To answer your question, you can fix the syntax errors and semantics in your function like this:
function updateImportrangeFormula() {
const sheet = SpreadsheetApp.getActiveSheet();
const ssId = sheet.getRange('B2').getValue();
const rangeA1 = sheet.getRange('C2').getValue();
const formula = '=importrange("' + ssId + '", "' + rangeA1 + '")';
sheet.getRange('B3').setFormula(formula);
}
I am trying to create a Google Sheet template where a user can enter a value (Project URN) in a cell and run a script to save the template as a sheet, renamed with the Project URN.
I have created a test Google Sheet here https://docs.google.com/spreadsheets/d/1IPpQyYHl_TtNa1lGpmu4dlzwTFjOotV2OcnxFT84iUk/edit?usp=sharing
This sheet has the following script, but I cant get the renaming function to correctly work.
function saveAsSpreadsheet(){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var destFolder = DriveApp.getFolderById("0B7RrbZuJGLlha3NvM3ZqcTY3MDA");
DriveApp.getFileById(sheet.getId())
.(makeCopy(values = SpreadsheetApp.getActiveSheet()
.getRange(2, 2).getValues()), destFolder);
} //END function saveAsSpreadsheet
I did also find the following article but wasn't able to turn it to my use. However, the secret must be here somewhere! Rename worksheet to cell value keeping format
Kitten
You almost have it. Please try this:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // Get spreadsheet
var id = ss.getId(); // Get spreadsheet ID
var sstocopy = DriveApp.getFileById(id); //Get spreadsheet with DriveApp
var sheet = ss.getActiveSheet(); // Grab the sheet in order to find the name of the new spreadsheet to be created
var sheet_name = sheet.getRange("A1").getValue(); // Get the value, in this case: Project Urn
var folder = DriveApp.getFolderById("XXXX"); // Get the folder where the sheet needs to be placed.
sstocopy.makeCopy(sheet_name,folder); // Make the copy of the sheet in that folder.
}
Let me know if you have any questions.