How to create a script to merge several sheets in another one? - google-apps-script

Sory for my English, this is not my strength!
I am working for a NGO that charges training sessions.
We have a google sheet that compiles datas about participants at each training days one by one in different spreadsheets.
So my yearly document is composed of something like 30 spreadsheets.
I would like to create one more spreadsheet that would merge all the data from other tabs in order to :
- be able to see quickly who has not payed yet his bill
- calculate the total amount made
I know I can do it by using the Filter function but it is really time-consuming for so many spreadsheets and if I add a training session I would have to change the formula. Moreover, I will be forced to do it each year.
So I would like to create a button to import all the data in a new spreadsheet.
You will find an example of the sheet with only 2 spreadsheets here :
https://docs.google.com/spreadsheets/d/1-RxzUGJFXnU3_mJ3Qj0MCTpwPTlnmgIT439AchyrRrE/edit?usp=sharing
I hope you would be able to help me!!
Thanks and happy new year :D

Merging Sheets in another sheet in same spreadsheet.
You will need the id for spreadsheet named 'CopiDdeFCCE' the other parameter will default to 'CopieDdeFCCE'.
function mergeSpreadsheet(ssid,shname){
var shname=shname || 'CopieDdeFCCE';
var ss=SpreadsheetApp.openById(ssid);//id of spreadsheet named 'CopieDdeFCCE' in your case
var sh=ss.getSheetByName(shname);//sheetname of sheet where other sheets are merged into again in your case its named 'CopieDdeFCCE'
if(!sht){ss.insertSheet(shname);}
var allshts=ss.getSheets();
for(var i=0;i<allshts.length;i++){
if(allshts[i].getName()!=shname){//do this for all sheets except shname
var shi=allshts[i];
var rg=shi.getDataRange();
var vA=rg.getValues();
shi.getRange(sh.getLastRow() + 1, 1,shi.getLastRow(),shi.getLastColumn()).setValues(vA);
}
}
}
Just to be clear.
What Google calls the spreadsheet is the file that contains all of the tabs (i.e. sheets).
In your first comment you said the following: I would like to merge all the 28 sheets of a file called "CopieDdeFCCE" to a new sheet of the same file.
But now in your question you say: I would like to create a button to import all the data in a new spreadsheet.
You stated in your last comment that your command looks like this: mergeSpreadsheet("1KC6kHcgtLZ93S4-r4wOwHFOG6Rq3mesGRKv26Ttnm9E","CopieDdeFFCE")
But clearly that's not the id of the example and the example does not have a sheet with that name.
So my question is: What exactly do you want?

Very sory I did not receive any notification of your reply because it was an edit and when I came to see if you wrote something I looked at the bottom of the site. :/
First of all, happy new year and thank you again for your help!!
Here are the precisions you asked :
1° Indeed, I would like to merge all the 28 sheets of a file called "CopieDdeFCCE" to a new sheet of the same file. To be more accurate, I give you the link of the exact location of the document with some examples of sheets: link.
2° Secondly, I will create a button to update all the data easily. But I think I know how to do that, so forget that question for now ;)
3° In the document I put enclosed, do we agree that the "id" is : 1KC6kHcgtLZ93S4-r4wOwHFOG6Rq3mesGRKv26Ttnm9E ??
Thanks again for all your time!

Related

Looking for a script that will add in a blank row after a new value is detected

I work for a small business selling hot wheels and other diecast related products, and we are constantly needing to create lists in google sheets for pre-ordered products. I am looking for a script that will insert a blank row between every customer.
I have already automated everything to organize the data when importing a .CSV file using scripts I've found here, but manually inserting a blank row between each customer is what takes the most time. If more information is needed, just please let me know.
I found a script here that allowed me to auto fill the customers names into the empty cells below until it detects a new value. (when importing .csv, if the customer has multiple items in an order, it doesn't put their name in all cells of the customer column, only the first cell)
I'm probably wrong on this, but it seems like I might be able to adapt this script to recognize when a value is different from the one above, then add a blank row.
I am new to google sheets and scripting. So if possible, please try to explain as simply as you can. Thanks!
Edit:
Link to spreadsheet with data: https://docs.google.com/spreadsheets/d/1W8peYL9kZhtQWdeCPP2uDkmsqy3nL1kVPmgJJq4T_80/edit#gid=2100307022
Edit:
Updated spreadsheet to show input/output examples and added more information to main post
Insert a row into sheet when a new value appears during an edit
function onEdit(e) {
Logger.log(JSON.stringify(e));
e.source.toast('Entry');//debug
const sh = e.range.getSheet();
if(sh.getName() == 'Sheet name' && e.value) {
sh.insertRows(e.range.rowStart);
}
}
onEdit

How to create a function that triggers whenever a new sheet is created? [duplicate]

This question already has an answer here:
How to set sheet create event as a trigger in apps script
(1 answer)
Closed 1 year ago.
I have a spreadsheet with a sheet of modification times for each of my other sheets. For example, I have a 'Signing' and 'Profile' sheet, and in my modifications times sheet I have:
Sheet Name
Modification Time
Signing
1639335205000
Profile
1639335207338
I want to create a function that, whenever I create another sheet, automatically adds it to the modifications times sheet as a new row.
I have looked at ScriptApp triggers and events but haven't found anything that is related(onEdit for example might be useful if there was a way to know if the edit was creating a sheet (if it even catches those events) but would also be triggered all the time).
I've actually wondered this myself and I hope someone can post a better answer than my method.
First, I create a named range that's going to store the number of sheets in the workbook (in below code I used sheetCount). Make sure this is at the workbook level (which by default google does).
Then leverage onEdit with this:
function onEdit(e) {
//var range = e.range;
const ss = SpreadsheetApp.getActiveSpreadsheet();
const storedSheetCount = ss.getRange("sheetCount")//<-- need to setup named range
var sCount = ss.getNumSheets();
if(storedSheetCount.getValue()!=sCount){
if(storedSheetCount.getValue()<sCount){
// more
Browser.msgBox("You addeded a spreadsheet!")
}else{
//for less
Browser.msgBox("you took one away")
}
//both cases update the value
storedSheetCount.setValue(sCount); //<--- updates stored count
}
}
I am well aware that this is not ideal for a variety of reasons including:
No code is executed until an edit ACTUALLY happens.
Stated differently, adding a sheet is not an edit event, so a user must then click into a cell or delete a blank one to kickoff the procedure.
Takes up space on the spreadsheet front end.
I hate helper columns/cells. Names is one area that Excel definitely crushes GoogleShhets as it allows direct references to values. Thus with Excel, I could avoid cluttering a spreadsheet by setting a named rage to the sheetCount (ie. refersTo:=3). One alternative to this would be to use the spreadsheet's file description, but this requires granting permissions to Drive Service which opens up all kinds of security risks for such a trivial request.
If anyone can do better, please share.

dynamic values in websites and docs

Let's say my company has a website and it includes various text. One of the texts it includes is the name of my Director of HR. His/her name could appear 20 or 30 times in various pages and documents on our website. And, should there be a change and I hire a new Director of HR, someone'd have to do manually change those 20 or 30 values.
There's got to be a better way to do that. One option is a scrub the website of personal data in all instances but one, "Contact the Director of HR," and then have the one value "the director of HR is..." and hyperlink all the instances of the Director of HR to the Staff page. But I'm interested in dynamic values.
To begin with, let's say I have this Google Doc and this Google Sheet. How would I get the value on the Google Doc to change when I change the value on the Google Sheet?
You can generate a Doc from a Sheet using apps script.
You'll go to Tools -> Script Editor in your Sheet.
Every time you run this script it will generate a new Doc with the value present in your sheet.
function myFunction() {
var doc = DocumentApp.create('HR Sheet');
var data = SpreadsheetApp.getActive().getDataRange().getValues()
var body = doc.getBody();
body.appendParagraph(data[1][1]);
}
If you run this script it will generate a new sheet and put the name of the HR Director on the sheet.
Helpful Link:
Google Docs documentation with scripting
You want to do the following:
Get a list of ROLES and NAMES from a Sheet.
For each ROLE/NAME pair, look for a specific value in a Google Doc, and replace that value with the corresponding NAME.
You can use replaceText(searchPattern, replacement) to achieve this. It could be something like this:
function findAndReplace() {
// Get "Sheet1", where data is:
var sheet = SpreadsheetApp.openById("your-spreadsheet-id").getSheetByName("Sheet1");
// Get the document body:
var doc = DocumentApp.openById("your-doc-id").getBody();
// Get the "ROLE/NAME" values:
var values = sheet.getRange(2, 1, sheet.getLastRow() - 1, 2).getValues();
// For each "ROLE/NAME" pair, replace text:
values.forEach(row => body.replaceText("{{" + row[0] + "}}", row[1]));
}
Note:
In this sample, the values to look for in the Doc are built using each corresponding role, with this pattern: {{your-role-name}}. [ is a special character for regex, so I think using {{ is more appropriate for this situation.
Reference:
Body.replaceText(searchPattern, replacement)
These answers were great re: Google Docs (which was the question I asked). But re: Website, I found this really useful plugin, TablePress, and the extension, Single Cell Content Shortcode. Populating my Director of HR in a Wordpress Page is as easy as using the shortcode [table-cell id=1 cell=C3 /].
I'm playing with autorefresh now, which'd repopulate the uploaded Sheet from the URL regularly, so I couldn't have to reupload the Google Sheet every time.
Looks like it'll work 100% for my purposes of populating Google Sheet values on Wordpress pages.

Carry out equations using Google Sheet Script to update database values

So I'm trying to create a simple Elo model for our table tennis league at work, I'm using the spreadsheet to generate match ups and then depending upon the winner going in and manually updating the rankings.
I attempted to try and do this (As seen below) but I was blissfully unaware that set.formula was definitely not the correct coding to be using.
Is there a way for me to carry out what I've outlined below, I essentially want to be able to click a button for Player A or Player B and have their Elo rank update on the back end and then generate a new match combination? Also how do I update the record based on a variable? Everyone has a unique player number but is there a function similar to VLOOKUP that will let me find a record and perform a formula?
I've put as many sheet callouts in the code below as I can:
var sheet =SpreadsheetApp.getActive().getSheetByName("Data");
var cell = sheet.getRange("=VLOOKUP("!MatchC18,A:C,3,False")
cell.setFormula ("=SUM(VLOOKUP(!MatchC18,A:C,3,FALSE)+!MatchA6*(1-E$4))");
cell.setFormula ("=SUM(VLOOKUP(!MatchE18,A:C,3,FALSE)+!MatchA7*(0-F$4))");
var sheet =SpreadsheetApp.getActive().getSheetByName('Match');
var cell = sheet.getRange ("C18");
cell.setFormula("=TRUNC(RANDBETWEEN(100,632))");
var sheet =SpreadsheetApp.getActive().getSheetByName('Match');
var cell = sheet.getRange ("E18");
cell.setFormula("=TRUNC(RANDBETWEEN(100,632))");
Any help will be massively appreciated!
Thanks!
As commented, your post is too broad.
Anyhow, to help you in any ways, you may use the following as additional references.
There's already an existing issue 456 in google-apps-script-issues tracker on using bulk methods such as setValues, setFormulas, etc.
and based from the thread, this issue hasn't been totally fixed yet. You may, however, try to use the given work around.
For the usage of VLOOKUP in Google Spreadsheets, more information can be found in Find Data in Google Spreadsheets with VLOOKUP.

Google spreadhseet EVAL function

I have a google spreadsheet with different sheets, each one representing a different week.
For example:
1/12 - 1/16
1/19 - 1/23
I want to do a chart based on the content of those sheets. Is there any way I can make a formula and extract the name of the sheet from a content of a cell?
For example something like "=EVAL(A1)!$B$4", then I would have the content from "1/12 - 1/16"!$B$4 instead of having to go through each one of the weeks of the year manually.
Thanks for the help!
There’s no need to use AppScript, INDIRECT is enough to read a sheet name from a cell:
=INDIRECT(A1 & "!$B$4")
However, it looks like Andy’s answer is the way to go if you want to get the sheet name from its index rather than from a cell.
It'd be best to use AppScript. In Tools -> Script Editor make a new AppScript script:
function getSheetName(i) {
var s = SpreadsheetApp.getActiveSpreadsheet().getSheets()
return s[i].getName();
}
With that in your script, you can then use the custom function =getSheetName(<SHEETNUMBER>) and it will retrieve the sheet name based what sheet number it is (starting from 0). From there, just incorporate it into your formulas. You may need to use INDIRECT.
Example: =INDIRECT(getSheetName(1)&"!A1") to get cell A1 in the second sheet.