Google sheets How do I get a sheet name from a cell value - tabs

I have a google sheet with 52 Tabs each has the date as its name. This is the same as B2 cell value on each sheet which contains 7 days across the top with the date at the top of each column.
The dates are linked from the previous sheet. Which allows me to alter the first date on the first sheet and that updates all the other dates in the whole workbook.
Problem I have is currently I have to alter each tab name by hand.
I have done this in Excel using VBA without an issue but it will not work if I open the workbook in sheets.
Thanks in advance for any help you can give me.
Tony

Try
function renameTabs() {
// except these sheets
const excludeSheetnames = ["Form Responses 1", "Summary"];
const ss = SpreadsheetApp.getActiveSpreadsheet();
// temporary name to prevent error
ss.getSheets().forEach((s, i) => {
if (!excludeSheetnames.includes(s.getName())) s.setName('temporary name ' + i)
})
ss.getSheets().forEach(s => {
if (!excludeSheetnames.includes(s.getName())) s.setName(s.getRange('B2').getDisplayValue())
})
}
setName()
forEach()
includes()
getDisplayValue()

Related

Find recently changed cell data and write it into another cell. Google Sheets

I have a simple spreadsheet two columns A,B. ColumnSpreadsheet B is populated by a (SPC Micrometer) decmil input, the timestamp shows up in column A after the data is input into column B. I need to have a separate cell on the sheet that updates with the last cell change, i.e. the machinist checks a part and it updates the next cell in column B and whatever the last measurement was is reported to a single cell that updates every time a new measurement is taken. I still want a running log of all of the measurements that were taken. I will use the data in the "last measurement cell" to report out to a gage chart on a separate sheet Gage Chart.
Any help will be helpful!!
I am using an apps script for the date stamp. I was thinking that the last measurement cell could be looking for a "NOW" cell and report the cell to the right which is the measurement taken at that time, because the B column data is in the spreadsheet before the A column cell is time stamped.
I don't have programming experience, but I have tried to use a script from gethub to look at column B and find a cell change then report the changed cell data to the last measurement cell but unsurprisingly it didn't function correctly. Also posted a similar request for information to the Google Sheets reddit.
Try this:
function dupeSheets() {
const ss = SpreadsheetApp.getActive();
const dts = Utilities.formatDate(new Date(),ss.getSpreadsheetTimeZone(),"dd/MM/yyyy HH:ss");//date string for new sheet name
const shts = ss.getSheets().filter((sh => {
if(!~sh.getName().indexOf('---')) {
return true;//use sheets that don't have ---
} else {
return false;
}
})).filter(e => e).forEach(sh => {
let vs = sh.getDataRange().getDisplayValues();//get data
let ns = ss.insertSheet(`${sh.getName()} --- ${dts}` );//insert and name new sheet
ns.getRange(1,1,vs.length,vs[0].length).setValues(vs);//copy data to new sheet
});
}
You can use this to create the trigger or do it manually
function createTrigger() {
if(ScriptApp.getProjectTriggers().filter(t => t.getHandlerFunction() == "dupeSheets").length ==0 ) {
ScriptApp.newTrigger("dupeSheets").timeBased().everyDays(1).atHour(23).create();
}
}
Please note I have not actually tested this so some modifications or adjustments may be necessary.

Google sheets - Search for a date in a range and return value underneath?

I'm trying to search for a specific date and use the whole sheet as a range, and return the value underneath (the checkbox), which is either True (if ticked) or False (if not ticked). The numbers on the sheet are actually dates, i've just formatted them to look this way.
So for example, let's say that today i want to search for the date 2022-03-30 (the marked number on the picture below) and retrieve the value underneath to see if the checkbox is ticked or not, how would I go about this?
Picture below:
Google sheet url that you guys can view/edit: https://docs.google.com/spreadsheets/d/1poFFukwrPZFLynt1SmDaNcELZlbPFfEibOWAwRNsafI/edit?usp=sharing
If anyone has any idea on how to make this work, maybe we can insert the formula inside "Sheet1"?
Thanks alot in advance, any tips are appreciated.
I believe your goal is as follows.
In your showing sample Spreadsheet, you want to know whether the checkbox is checked or unchecked.
From let's say that today i want to search for the date 2022-03-30 (the marked number on the picture below) and retrieve the value underneath to see if the checkbox is ticked or not,, in this case, you want to check whether the checkbox of "T12" is checked.
You want to achieve this using Google Apps Script.
In this case, how about the following sample script?
Sample script:
Please copy and paste the following script to the script editor of Spreadsheet. And, please set the sheet name, and save the script.
function myFunction() {
const sheetName = "Sheet1"; // Please set your sheet name.
const oneMonth = { cols: 7, rows: 14 }; // Number of columns and rows of 1 month.
const calendar = { cols: 4, rows: 3 }; // Order of months in your calendar.
const spaceCol = 1; // I found an empty column between each month.
const today = new Date(); // This is today date.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
const months = [...Array(calendar.rows)].flatMap((_, i) => [...Array(calendar.cols)].map((_, j) => sheet.getRange(i * oneMonth.rows + 1, j * oneMonth.cols + 1 + j * spaceCol, oneMonth.rows, oneMonth.cols)));
const res = months[today.getMonth()].createTextFinder(today.getDate()).findNext().offset(1, 0).isChecked();
console.log(res) // You can see "true" or "false" in the log.
}
When this script is run, in the case of today (2022-07-05), the checkbox of "S20" is retrieved.
In order to search the day in a month, I used TextFinder.
Note:
This sample script is for your provided Spreadsheet. So, when you change your Spreadsheet, this script might not be able to be used. Please be careful about this.
Reference:
Class TextFinder

Use Conditional formatting for whole Google Sheet Workbook to search for duplicates

Use Conditional formatting for whole Google Sheet Workbook
Currently I am using the single color CONDITIONAL FORMATTING for two columns in every worksheet that looks at the column and if there is a similar match with the single worksheet within that column it will highlight the column in yellow.
APPLY TO RANGE:
C1:C1000
FORMAT RULES
Format cells if ...
=if(C1<>"",Countif(C:C,left(C1,18)& "*") > 1)
Formatting Style
I selected yellow
And I do exactly the same thing for Column D
Now that I have over 10 worksheets and it is growing week by week I am finding that there are duplicates happening between the sheets, as conditional formatting only works per sheet.
So is there a way for me to do have Google Sheet conditionally format the entire workbook by looking at column C and column D and if there is a match that it highlights it in yellow.
If there is a script or macro that someone can actually code for me (as I don't know how to do it) I would really appreciate. Alternatively if anyone knows an easy way to do what I need done, I would be most grateful.
As an example here is a workbook to show you what I mean.
In the google workbook, in Sheet labelled "Visual Test Current" this is what I have been able to currently setup as described. It works perfectly.
In the sheet labelled "Visual Test Sheet 1" it works fine on the individual sheet itself, however it does not look at "Visual Test Current" and if there is a match based on the formula "=if(D1<>"",Countif(D:D,left(D1,18)& "") > 1)"
AND
=if(E1<>"",Countif(E:E,left(E1,18)& "") > 1)
It does not format the cell to tell me that there is a duplicate match in a previous sheet. That is what I am trying to figure out how to do.
How do I get/create a formula that looks at these two columns through every sheet in Google Workbook and if there is a match based on the parameters of Countif it formats the cell to yellow, highlighting to me that there is a duplicate of that cell somewhere in a sheet in Google Workbook.
Here is the link to the shared Test document to help you visual what I am trying to do.
https://docs.google.com/spreadsheets/d/e/2PACX-1vQryGa9Z325XMv1mU5hq0AhaO3uWbzZ7MSxfY7U4EcPS7hGg281wogKJE98IQjriR4cPIXTCatd-Y8d/pubhtml
Solution:
Return all sheets via Spreadsheet.getSheets() and iterate through them.
For each sheet, create the conditional formatting rule for columns C and D, using ConditionalFormatRuleBuilder.
Add the conditional format rules via Sheet.setConditionalFormatRules.
Code sample:
const EXCLUDED_SHEETS = ["Sheets that won't be updated"];
function updateAllSheets() {
const ss = SpreadsheetApp.getActive();
const sheets = ss.getSheets().filter(sheet => !EXCLUDED_SHEETS.includes(sheet.getName()));
const [cFormula, dFormula] = ["C","D"].map(column => sheets.reduce((acc, sheet, i) => {
const sheetName = sheet.getSheetName();
return acc + (i!=0 ? "+" : "") + `Countif(INDIRECT("'${sheetName}'!${column}:${column}"),left(${column}1,18)&\"*\")`;
}, `=if(${column}1<>\"\",`) + "> 1)");
sheets.forEach(sheet => {
const cRange = sheet.getRange("C1:C" + sheet.getLastRow());
const cRule = SpreadsheetApp.newConditionalFormatRule()
.whenFormulaSatisfied(cFormula)
.setBackground("yellow")
.setRanges([cRange])
.build();
const dRange = sheet.getRange("D1:D" + sheet.getLastRow());
const dRule = SpreadsheetApp.newConditionalFormatRule()
.whenFormulaSatisfied(dFormula)
.setBackground("yellow")
.setRanges([dRange])
.build();
sheet.setConditionalFormatRules([cRule,dRule]);
});
}
Execute automatically:
If you want to execute this automatically, you should use a trigger. Here, I see two main options:
onEdit trigger. With this trigger, your function will execute every time a user edits the spreadsheet. To have this trigger, just rename your function updateAllSheets to onEdit.
Time-driven trigger. This kind of trigger would execute periodically (for example, every hour). In contrast with onEdit, to use this trigger you have to install it first. To install this, either follow these steps or execute a function like this once (the example below refers to a trigger that executes hourly, check this to see all the alternatives at your disposal):
function createTimeDrivenTrigger() {
// Trigger every 1 hour.
ScriptApp.newTrigger('updateAllSheets')
.timeBased()
.everyHours(1)
.create();

Google Sheets - sum a cell from a dynamic list of sheets with vlookup

I have a Google Sheet that I update with a new sheet every two days or so and title the name of the sheet the date that it is created. For organizational reasons, I do not want to combine all of the information into one sheet and parse it elsewhere, even though it would make this so much simpler.
I'd like to provide a named range of different sheet names, and have a script, function, etc go to each sheet, grab the contents of a cell and sum them. Bonus points if vlookup can be integrated to ensure that the right cell is being referenced.
So, for example:
named range = '7/3/21','7/1/21'
=sum('7/3/21'!B12,'7/1/21'!B12)
This is simple enough, but I don't want to alter this every time a new sheet is added to reference the new sheet.
In my mind it would look something like:
=sum(vlookup(A1(INDIRECT(NamedRange1&"!c1"))
where:
A1 = the name I want to lookup on the other sheets
NamedRange1 = range of cells that correspond to all of the different sheets
C1 = the cell that I want to add across all the other sheets.
function sumacellfromlistofsheets(obj) {
const listofsheets = obj.list;
const ss = SpreadsheetApp.getActive();
const shts = ss.getSheets().filter(sh => ~obj.list.indexOf(sh.getName()));
let sum = 0;
shts.forEach( sh => {
sum += sh.getRange(obj.cellinA1Notation).getValue();
});
}

Nightly Script that Inserts values into different sheet based on date - Google Sheets

I have a sheet "Sheet1" where a user inputs data in cells A3:E3. The goal is to then move that data into "Sheet2" where column A4:A34 is a numeric value for the day of the month. I want to move the data inputted on "Sheet1" into "Sheet2" on the row that corresponds with the current day of the month. Then "Sheet1" would clear itself for the next day ahead.
I'll be honest I'm not great with functions and I'm mainly looking for help on where to look to find a solution. I've tried different code that I do know how to use like Query but the issue is it doesn't lock the value in place and as soon as the values are wiped in Sheet1 they are then removed via the query.
You will need to run a function on a time-driven trigger. The function can use Range.getValues() to read the data, get the current date's day number with const dayNumber = new Date().getDate(), look up the day number in Sheet2 with Range.getValues().flat().indexOf(dayNumber), write the data with Range.setValues() and finally clear the source range with Range.clearContent().
It is unclear what the purpose the day numbers in Sheet2 serve, because the data would in any case be written once a day. It would seem simpler to always append the most recent data at the first available row and include a timestamp.
For an example of how to do this, see the appendRowsToArchiveSheet script.
Since the task is rather simple, here is the code that does the work:
// add menu Scripts
function onOpen() {
SpreadsheetApp.getUi().createMenu('🔨 Scripts')
.addItem('✅ Copy to archive', 'copy_range_to_archive')
.addItem('❌ Erase', 'erase_range')
.addToUi();
}
// erase the range A3:E3
function erase_range() {
SpreadsheetApp.getActiveSpreadsheet()
.getSheets()[0]
.getRange("A3:E3")
.clearContent();
}
// copy the range A3:E3 to Sheet 2
function copy_range_to_archive() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const src_range = ss.getSheets()[0].getRange("A3:E3");
const data = src_range.getValues();
const dest_sheet = ss.getSheets()[1];
const today = new Date().getDate();
const dest_range = dest_sheet.getRange(3 + today, 2, 1, data[0].length);
dest_range.clearContent();
dest_range.setValues(data);
}
It makes the menu 'Scripts' and two command 'Copy to archive' (the range A3:E3) and 'Erase' (the same range).