I found this function at How to get all tab names/gid:
function GetTabs() {
var app = SpreadsheetApp;
var ss = app.openById('1e4zL13L2b8Hs8sJcBw-3_pGjQBecZv_QO_LuSLUrieA');
var name = ss.getName();
Logger.log(name);
var tabs = new Array()
var sheets = ss.getSheets();
for (var i = 0; i < sheets.length; i++) tabs.push([sheets[i].getSheetId()])
//return tabs
Logger.log(tabs)
}
It lets me print the GID number of tabs in a spreadsheet to the console. How do I put these GIDs on Sheet2 of the active spreadsheet instead?
Use Sheet.appendRow(), like this:
function appendSheetIdsToSheet2() {
const sheetToPrintTo = SpreadsheetApp.getActive().getSheetByName('Sheet 2');
const ss = SpreadsheetApp.openById('1e4zL13L2b8Hs8sJcBw-3_pGjQBecZv_QO_LuSLUrieA');
sheetToPrintTo.appendRow([ss.getName()]);
ss.getSheets().forEach(sheet => sheetToPrintTo.appendRow([sheet.getSheetId()]));
}
Related
everyone!
I'm trying to write a script where the cell G3 on the sheet 'ref view' will change to 'Yes' if the cell D9 on 'view' contains 'BP' when I run it. The problem is that the execution is completed without errors but when I try to test it nothing happens.
This is the code:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var sheetInfo = ss.getSheetByName('ref view')
var data = sheet.getDataRange().getValues();
var rangeView = ss.getRange('View!D9');
var cell = ss.getRange('ref view!G3');
var range = rangeView;
for(var i=0; i<data.length; i++) {
if(rangeView == 'BP') {
sheet.getRange(cell).clear().setValue('Yes');
}
}
} ```
Try it this way:
function one() {
var ss = SpreadsheetApp.getActive();
var sh1 = ss.getActiveSheet();
var vs1 = sh1.getDataRange().getValues();
var sh2 = ss.getSheetByName('ref view')
var sh3 = ss.getSheetByName('view');
var sh3D9v = sh3.getRange('D9').getValue();//value
var sh2G3r = sh2.getRange('G3');//Range
for(var i=0; i<vs1.length; i++) {
if(sh3D9v == 'BP') {
sh1.getRange(sh2G3r).setValue('Yes');
}
}
}
Be aware that a range does not return a value without the use of a getValue() or a getValues();
I have two functions I'm looking to join together and I'm struggling with it. The first function lists all of the tabs I have in the sheet (on the actual doc I'm working on this is just over 100 tabs and growing).
function listsheets() {
var out = new Array()
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
for (var i=0 ; i<sheets.length ; i++) out.push( [ sheets[i].getName() ] )
return out
}
The second function links cells based on there text; i.e., if there is a "data" cell, it would link to the "data" tab in my workbook.
function linkRange() {
const startRow = 2,
column = 1;
const spreadsheet = SpreadsheetApp.getActive(),
sheet = spreadsheet.getSheetByName("List of Sheets"),
lastRow = sheet.getLastRow();
for (let row = startRow; row <= lastRow; row++) {
const range = sheet.getRange(row, column),
richTextValue = range.getRichTextValue(),
targetSheet = spreadsheet.getSheetByName(richTextValue.getText());
if (targetSheet !== null) {
const sheetId = targetSheet.getSheetId(),
builder = richTextValue.copy().setLinkUrl(`#gid=${sheetId}`);
range.setRichTextValue(builder.build());
}
}
}
What I am ultimately looking for is a way to automatically link this list of sheets, so the custom function would essentially read as "linkRange(listsheets())".
Sorry if misunderstood your goal. From your code I suspect you need this:
function build_list_of_sheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var list = [];
for (var sheet of sheets) {
var value = SpreadsheetApp.newRichTextValue()
.setText(sheet.getName())
.setLinkUrl('#gid=' + sheet.getSheetId())
.build();
list.push([value]);
}
var sh = ss.getSheetByName('List of Sheets');
sh.getRange(2,1,list.length,1).setRichTextValues(list);
}
It takes the names all sheets and put them into column A of the sheet 'List of Sheets' as a list of links:
I keep getting "Exception: Service Spreadsheets failed while accessing document with id " while trying to run moveActiveSheet to move a sheet in tab with index 4 to index 1. This just happened very lately. I had been using my code for months before this happened. Does any body is facing the same thing?
My code is below
var ss = SpreadsheetApp.getActiveSpreadsheet();
//==========================================
//Arrange the Sheet
// Store all the worksheets in this array
var sheetNameArray = [];
var sheets = ss.getSheets();
for (var i = 0; i < sheets.length; i++) {
sheetNameArray.push(sheets[i].getName());
};
sheetNameArray.sort();
var sheetName = sheetNameArray[0]; //This tab is currently at index 4
var getSheet = ss.getSheetByName(sheetName);
Logger.log(getSheet.getIndex());
ss.setActiveSheet(getSheet);
ss.moveActiveSheet(1); //Trying to move it to index 1 but exception was thrown
Here is a work-around that worked for me, I loop through the sorted array. I used .batchUpdate from Sheets API. You have to enable it from advanced services first: Resources > Advanced Google Services
function move_sheet_func(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
//==========================================
//Arrange the Sheet
// Store all the worksheets in this array
var sheetNameArray = [];
var sheets = ss.getSheets();
for (var i = 0; i < sheets.length; i++) {
sheetNameArray.push(sheets[i].getName());
};
sheetNameArray.sort();
var sheetName = sheetNameArray[0]; //This tab is currently at index 4
var getSheet = ss.getSheetByName(sheetName);
var sheetsreq = [];
//create requests for each sheet to be moved to its index as sorted
sheetNameArray.forEach(function (name, indx) {
sheetsreq.push({ updateSheetProperties: {
fields: "index, title",
properties: {
index: indx,
title: name,
sheetId: ss.getSheetByName(name).getSheetId()
}
} });
});
var req = { "requests": sheetsreq };
console.log(JSON.stringify(req));
Sheets.Spreadsheets.batchUpdate(req, ss.getId());
}
I would like to be able to export a single specific sheet from a large workbook without having to hide the unrequired sheets. Is that actually possible with Google Scripts?
At the moment I am looping through a list of products, updating a query for each one and then exporting each result to an individual PDF. Basically creating a product "Printout" page for many products.
The code below works quite nicely but it starts by hiding all sheets other than my Printout page. That would be fine except some of the other sheets are protected and not all users that would be using my export functionality have the right to hide sheets.
I've considered adding an unprotect/protect function to my macro but it would be good to know if exporting a single sheet was an option before i went down this route?
The hiding sheets trick was from this post Export Single Sheet to PDF in Apps Script
function exportLoopedSheet(firstRow, lastRow) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetName = 'Printout'; // update for print sheet name
var productSheetName = 'ProductList'; // update for final product list
var folderName = 'productPDFs';
var main = ss.getSheetByName(sheetName);
var sheets = ss.getSheets();
var productList = ss.getSheetByName(productSheetName);
var lastProductRow = lastRow;
var firstProductRow = firstRow;
// Hide all sheets other than the Print Sheet
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].getSheetName() !== sheetName) {
sheets[i].hideSheet();
}
}
for (var prodNo = firstProductRow; prodNo < lastProductRow + 1; prodNo ++) {
var currentProduct = productList.getRange('A'+ prodNo).getValue();
main.getRange('B9').setValue(currentProduct);
// Ensure all changes are updated
SpreadsheetApp.flush();
// call the export sheet function
exportSheet();
}
// Unhide the sheets
for (i = 0; i < sheets.length; i++) {
sheets[i].showSheet();
}
}
function exportSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetName = 'Printout';
var main = ss.getSheetByName(sheetName);
var sheets = ss.getSheets();
//Hide All Empty Rows in the Print Sheet
var maxRows = main.getMaxRows();
var lastRow = main.getLastRow();
if (maxRows-lastRow != 0){
main.hideRows(lastRow+1, maxRows-lastRow);
}
// Save pdf version
var folder = 'productPDF';
var parentFolder = DriveApp.getFolderById('1234'); //add this line...
var folder, folders = DriveApp.getFoldersByName(folder);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = parentFolder.createFolder(folder);
}
var name = main.getRange("B8").getValue();
folder.createFile(ss.getBlob().setName(name));
// Unhide the rows again
var fullSheetRange = main.getRange(1,1,main.getMaxRows(), main.getMaxColumns());
main.unhideRow(fullSheetRange);
}
I'm brand new to Google Apps Script, and I'm trying to create a simple spreadsheet that will allow me to share files by user email through a single spreadsheet.
I have written the following script, which will allow me to add editors and viewers, but not commenters.
I keep getting an error that states that the function addCommenter cannot be found in object spreadsheet.
function shareSheet () {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.toast('Updating access level...');
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var range1 = sheet.getRange (3,1, lastRow,9);
var data = range1.getValues();
for (var i= 0; i < data.length; i++) {
var row = data [i];
var accessLevel = row [5];
var values = row [8];
var ss2 = SpreadsheetApp.openById(values);
var values2 = row [4];
// Add new editor
if (accessLevel == 'Edit') {
var addEditors = ss2.addEditor(values2);
}
// Add new viewer
if (accessLevel == 'View'){
var addViewers = ss2.addViewer(values2);
}
// Add new commenter
if (accessLevel == 'Comment') {
var addCommenters = ss2.addCommenter(values2);
}
}
}
The Spreadsheet object does not support the addCommentor() method. You should use DriveApp service instead.
DriveApp.getFileById(id).addCommenter(emailAddress)