Google Spreadsheet, Checking the name of the sheet with a cell in a sheet - google-apps-script

I have a Google spreadsheet with 3 sheets.
In the first sheet I have a resume of the two other sheet. This sheet has a column "C" where the name of the sheet corresponding to the resume is written.
Now I want a script that checks the name of the sheets and color the corresponding cell in column "C" into red if the name matches with the one in column "C".
I have written this code but doesn't seem to be working!
function myFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
var ss = SpreadsheetApp.getActiveSpreadsheet();
var columnC = sheet.getRange (1, 3, sheet.getLastRow(), 1);
var Cvalues = columnC.getValues();
var allSheets = ss.getSheets();
var allSheetNames = new Array();
for (var i = 0; i < allSheets.length; i++)
{
allSheetNames.push(allSheets[i].getName());
}
for (var j=0 ; j < Cvalues.length; j++)
{
if (Cvalues[j][0] == allSheets) {
sheet.getRange( j, 1, 1, 1).setBackgroundColor('red');}
}
}

Problem here:
if (Cvalues[j][0] == allSheets) {
Your allSheets is an array, so the value in Cvalues[j][0] can never be equal to it. What you probably want it to determine if Cvalues[j][0] appears anywhere in allSheets. Here's how you'd do that:
if (allSheets.indexOf(Cvalues[j][0]) !== -1) {
...

Related

Linked List of Sheets

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:

Google Sheets - Two-way lookup pulling data from multiple sheet tabs

I've been working on a sheet where I want to have and input tab and output tab.
The input tab is basically a table and the output tab will be a calendar (of sorts).
In my example:
Sheet1 = input tab
Sheet2 = output tab
I wish to have a vlookup that will pull its search_key from Sheet2 (output) and search it against a range in Sheet1.
I've been messing around with the following (green cell Sheet2 in example):
=IFERROR(VLOOKUP(A2,Sheet1!$A$2:$C$7,MATCH(B1,Sheet1!$A$2:$C$7,0),False))
I had also tried a variation of this using hlookup instead of MATCH but didn't have much luck with it.
The problem I have is that I no longer know where to place my column index. In my example sheet I have it working with a one way vlookup (blue cell Sheet2) that returns the desired value from Sheet1 (Length Column) using this index. Is it not possible to do so in the two way lookup??
Here's a link to the example:
https://docs.google.com/spreadsheets/d/1_nqH-XOxNhQAUVJzesNBZeMci7AV9RowSQUnptAruPc/edit?usp=sharing
Try running this function in Apps Script:
function myFunction() {
var ss = SpreadsheetApp.getActive();
var sheet1 = ss.getSheetByName('Sheet1');
var sheet2 = ss.getSheetByName('Sheet2');
var firstRow = 2;
var numRows = sheet1.getLastRow() - 1;
var firstCol = 1;
var numCols = sheet1.getLastColumn();
var inputData = sheet1.getRange(firstRow, firstCol, numRows, numCols).getValues();
var numBrands = sheet2.getLastRow();
var outputRange = sheet2.getDataRange();
var outputData = outputRange.getValues();
// Iterating through each row in Sheet1 data:
for(var i = 0; i < numRows; i++) {
// Iterating through each row in Sheet2:
for(var j = 1; j < outputData.length; j++) {
// Iterates through each cell for each row in Sheet2.
for(var k = 1; k < outputData[0].length; k++) {
var inputBrand = inputData[i][0];
var outputBrand = outputData[j][0];
var inputDate = inputData[i][1];
var outputDate = outputData[0][k];
// It checks whether the date and brand corresponding to each cell
// (same row or column) matches the date and brand in the current
// row in Sheet1
if(inputBrand == outputBrand && inputDate.toString() == outputDate.toString()) {
var inputLength = inputData[i][2];
sheet2.getRange(j+1, k+1, 1, 1).setValue(inputLength);
}
}
}
}
}

SORT script works for owner but not editors

I've written script to sort a google sheet by column A, and then take you to the cell next to the one you just edited, and I have it working perfectly for me the owner, but for editors, nothing seems to work starting from the "sort" function.
I assume this means some part of it is an installable trigger? but as far as I can tell I've made it all with simple triggers.
function onEdit(e) {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getActiveSheet();
var cell = sheet.getActiveCell();
var NEXTcell = sheet.getActiveRange().offset(0,1);
var range = e.range;
var columnOfCellEdited = range.getColumn();
var sheet = spreadsheet.getActiveSheet();
// When Column A edited
if (columnOfCellEdited === 1) {// Column 1 is Column A
//Set marker
NEXTcell.setValue('sorting');
// Sort whole sheet excluding first 2 rows by Column A.
sheet.getRange(1, 1, sheet.getMaxRows(), sheet.getMaxColumns()).activate();
spreadsheet.getActiveRange().offset(2, 0, spreadsheet.getActiveRange().getNumRows() - 2).sort({column: 1, ascending: true});
// Find original cell after sorting
var rowoffset = 3;
var rng = sheet.getRange(rowoffset, 2, 600);
var data = rng.getValues();
var search = "sorting";
for (var i=0; i < data.length; i++) {
if (data[i][0] == search) {
data[i][0] = "";
rng.setValues(data);
var foundcell = sheet.getRange((i+rowoffset), 2);
foundcell.activate();
break;
}
}
}
}
So Stackdriver logs for-the-win.
Turns out protections I hadn't considered are the culprit.

Merging google sheets: match with specific col values and merge data in 2 different sheets

I would like to ask if there is any possible way to set up a simple version of app script that is similar to the below add-ons.
https://chrome.google.com/webstore/detail/merge-sheets/gdmgbiccnalapanbededmeiadjfbfhkl?utm_source=ablebits
Basically, I've got sheet 1 and sheet 3, both sheets will have a common key column with specific values in each cell, and I would like to map both sheets with the data in that column then update the whole row data in the other sheets (For example, if i updated the sheet 3 then it map that col value in sheet 1, then paste the data in the corresponding row)
I have came up with a code that runs but no changes have been made, could anyone please advise how can I modify it to a simple version similar to the above add-ons? Thanks in advance.
I would like to populate the date from sheet 3 to sheet 1 after the code run, while the data from col C is matched in both sheets, please see example below, thanks!
For example, the data in sheet 1 highlighted row is having its key col with col C for common lookup value with sheet 3 while the row sequence is diff with sheet 3 (Please see the next photo, thanks!)
As you can see in sheet 3, the data of the whole row is inserted to the correct row according to the col C key col value which matched with sheet 1.
function myFunction2(){
// Get your spreadsheet and the sheets "TB" and "2"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Sheet 1");
var sheet3 = ss.getSheetByName("Sheet 3");
// Get the range on sheet "TB"
var tabsheet1 = sheet1.getRange(2, 2, sheet1.getLastRow(),
sheet1.getLastColumn());
// Get the values to compare
var datasheet1 = tabsheet1.getValues();
var datasheet3 = sheet3.getRange(2, 2, sheet3.getLastRow(), sheet3.getLastColumn());
for(var i = 0; i < datasheet1.length; i++){
for(var j = 0; j < datasheet3.length; j++){
// Compare data: if they're the same, put the value
if(datasheet1[i][0]=(datasheet3[j][0]) == 0){
//if(datasheet1[i][0].localeCompare(datasheet3[j][0]) == 0){
datasheet1[i][1] = datasheet3[j][1];
}
}
}
// Take the modified tab and put it on the spreadsheet
tabsheet1.setValues(datasheet1);
}
You want to copy the data of sheet 3 to sheet 1. For this situation, when the values of column C of sheet 3 and sheet 1 is the same, you want to copy the row of sheet 3 to sheet 1, because the order of rows for sheet 3 and sheet 1 are different. If my understanding is correct, how about this modification?
Modification points :
In order to retrieve the values from column C to last column, it uses getRange(2, 3, sheet1.getLastRow(), sheet1.getLastColumn()).
In your script, datasheet3 is the range.
About if(datasheet1[i][0]=(datasheet3[j][0]) == 0){, in order to comare the date, I used getDisplayValues().
By this, the values retrieved as a string are compared.
Modified script :
function myFunction2(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Sheet 1");
var sheet3 = ss.getSheetByName("Sheet 3");
var tabsheet1 = sheet1.getRange(2, 3, sheet1.getLastRow(), sheet1.getLastColumn());
var datasheet1 = tabsheet1.getValues();
var datasheet1d = tabsheet1.getDisplayValues(); // Added
var tabsheet3 = sheet3.getRange(2, 3, sheet3.getLastRow(), sheet3.getLastColumn()); // Added
var datasheet3 = tabsheet3.getValues(); // Modified
var datasheet3d = tabsheet3.getDisplayValues(); // Added
for (var i = 0; i < datasheet1.length; i++) {
for (var j = 0; j < datasheet3.length; j++) {
if (datasheet1d[i][0] == datasheet3d[j][0]) { // Modified
datasheet1[i] = datasheet3[j]; // Modified
}
}
}
tabsheet1.setValues(datasheet1);
}
Reference :
getDisplayValues()
If I misunderstand your question, please tell me. I would like to modify it. At that time, in order to modify, can you share the sample sheet? Of course, please remove your private information from it.
Edit 1 :
function myFunction2(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Sheet 1");
var sheet3 = ss.getSheetByName("Sheet 3");
var tabsheet1 = sheet1.getRange(2, 3, sheet1.getLastRow() - 1, sheet1.getLastColumn() - 2); // Modified
var datasheet1 = tabsheet1.getValues();
var datasheet1d = tabsheet1.getDisplayValues(); // Added
var tabsheet3 = sheet3.getRange(2, 3, sheet3.getLastRow() - 1, sheet3.getLastColumn() - 2); // Added
var datasheet3 = tabsheet3.getValues(); // Modified
var datasheet3d = tabsheet3.getDisplayValues(); // Added
for (var i = 0; i < datasheet1.length; i++) {
for (var j = 0; j < datasheet3.length; j++) {
if (datasheet1d[i][0] == datasheet3d[j][0]) { // Modified
datasheet3[j].push(""); // Modified
datasheet1[i] = datasheet3[j]; // Modified
}
}
}
tabsheet1.setValues(datasheet1);
}
Edit 2 :
function myFunction2(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("comment_log");
var sheet3 = ss.getSheetByName("CM");
var tabsheet1 = sheet1.getRange(2, 3, sheet1.getLastRow() - 1, sheet1.getLastColumn() - 2); // Modified
var datasheet1 = tabsheet1.getValues();
var datasheet1d = tabsheet1.getDisplayValues(); // Added
var tabsheet3 = sheet3.getRange(2, 3, sheet3.getLastRow() - 1, sheet3.getLastColumn() - 2); // Added
var datasheet3 = tabsheet3.getValues(); // Modified
var datasheet3d = tabsheet3.getDisplayValues(); // Added
for (var i = 0; i < datasheet1.length; i++) {
for (var j = 0; j < datasheet3.length; j++) {
if (datasheet1d[i][0] == datasheet3d[j][0]) { // Modified
if (datasheet1[i].length != datasheet3[j].length) {
for (var k = 0; k < datasheet1[i].length - datasheet3[j].length; k++) {
datasheet3[j].push(datasheet1[i][datasheet1[i].length - 1]);
}
}
datasheet1[i] = datasheet3[j]
}
}
}
tabsheet1.setValues(datasheet1);
}

Hide Row in Google Sheets if Cell Contains "no" - Multiple Sheets

I'm running 1 Master spreadsheet, with 4 product specific spreadsheets pulling info from it. If no relevant info is pulled, the smaller spreadsheets will display "no" in all cells. I want rows with "no" to be hidden.
I've sort of hacked together something, that sort of works. But I can't get it to work on all 4 sheets. I've tried getSheets(), I've tried getSheetByName(name) and naming all 4 sheets...it doesn't work.
Here's what I have so far:
function onOpen() {
var ss = SpreadsheetApp.getActive();
var sheets = ss.getSheets(); // array of all sheet objects in ss
var numSheets = ss.getNumSheets(); // count of sheets
//show all the rows
sheet.showRows(1, maxRows);
//get data from clumn C
var data = sheet.getRange('C:C').getValues();
//iterate over all rows
for(var i=0; i< data.length; i++){
//compare column, if no, then hide row
if(data[i][0] == 'no'){
sheet.hideRows(i+1);
}
}
}
Try: (edited)
function onOpen() {
var ss = SpreadsheetApp.getActive();
var sheets = ss.getSheets(); // array of all sheet objects in ss
var numSheets = ss.getNumSheets(); // count of sheets
for(sheet in sheets) {
if(sheets[sheet].getSheetName() == "Master") continue;
//show all the rows
sheets[sheet].showRows(1, sheets[sheet].getMaxRows());
//get data from clumn C
var data = sheets[sheet].getRange('C:C').getValues();
//iterate over all rows
for(var i=0; i< data.length; i++){
//compare column, if no, then hide row
if(data[i][0] == 'no'){
sheets[sheet].hideRows(i+1);
}
}
}
}