This question already has answers here:
Running onEdit trigger when sheet is updated by Zapier
(2 answers)
Closed 1 year ago.
I am currently working on an Apps Script on a google sheet file. I made a script that sends mail to contacts. In my sheet the contacts are in the form of a line which is automatically added with a zapier. I have installed an onChange trigger but I would like it to act only when a new row is added to my sheet, I have looked everywhere but no solutions work or correspond to my problem. So if anybody have an idea to solve it, it would be helpfull
(I put you a copy of my script below)
thanks in advance
'
function envoie_mail (){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1=ss.getSheetByName('testmail');
var lr = sheet1.getLastRow();
var eligible = sheet1.getRange(lr,4).getValue();
var emailadresse = sheet1.getRange(lr,1).getValue();
var subject = sheet1.getRange(lr,2).getValue();
if (eligible === "non"){
var htmlTemplate = HtmlService.createTemplateFromFile("body.html");
var modele = htmlTemplate.evaluate().getContent();
var reference = sheet1.getRange(lr,3).getValue();
modele = modele.replace("<ref>",reference).replace("<ref2>",reference);
MailApp.sendEmail({
to: emailadresse,
subject: subject,
htmlBody: modele
});
}
}
I don't know how zapier works, howerver try to put an indicator and test as follows
function createSpreadsheetChangeTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('onChange')
.forSpreadsheet(ss)
.onChange()
.create();
}
function onChange(e) {
var f = SpreadsheetApp.getActiveSheet()
var data = f.getRange(1,f.getLastColumn(),f.getLastRow(),1).getValues().join().split(',')
for (var i=0;i<data.length;i++){
if (data[i]=='') {
Browser.msgBox('envoi mail ligne ' + (i+1))
f.getRange((i+1),f.getLastColumn()).setValue('ok')
}
}
}
https://docs.google.com/spreadsheets/d/1TEWS1e3uOnYybgbuScWb9plA9J7rgVjt16g9Ucg0x3M/copy
Related
I have created a data entry form in google sheets, now I am having trouble saving said entry to an external sheet so far this is what I have, I do not know if I am using the right method to reference sheet.
please look at comments, thank you
Everytime I am trying to submit the form it is giving lastRow Null
function submitData() {
//variable declaration for referenceing the active google sheet
var myGoogleSheet = SpreadsheetApp.getActiveSpreadsheet();
var shUserForm = myGoogleSheet.getSheetByName('MasterSheet');
//open external sheet
var extSS = SpreadsheetApp.openById("1U9SmfPCH9v8maqh6XL0dmRL85TJZfckUV7SAEGM3pQo");
var datasheet= extSS.getSheetByName("Mastersheet");
var srcData = shUserForm.getDataRange().getValues();
//to create the instance of the ui environment to use the alert features
var ui = SpreadsheetApp.getUi();
var response = ui.alert("Submit", "Do you want to submit the data?", ui.ButtonSet.YES_NO);
//checking the user response
if ( response == ui.NO) {
return; // to ext from this function
}
if ( validateEntry()== true) {
var blankRow =datasheet.getLastRow() + 1; //identify the next blank row
//'code to update the database sheet ( write data entry to DB sheet)
datasheet.getRange(blankRow,1).setValue(srcData.getRange("C7").getValue()); //input number
datasheet.getRange(blankRow,2).setValue(srcData.getRange("C9").getValue()); //Department
datasheet.getRange(blankRow,3).setValue(srcData.getRange("C11").getValue()); //Agent Name
datasheet.getRange(blankRow,4).setValue(srcData.getRange("C13").getValue()); //Hub location
datasheet.getRange(blankRow,9).setValue(srcData.getRange("C15").getValue()); //order ID
datasheet.getRange(blankRow,10).setValue(srcData.getRange("C20").getValue()); //type of entry
datasheet.getRange(blankRow,5).setValue(Session.getActiveUser().getEmail()); //Submitted By, this will automatically get user email
datasheet.getRange(blankRow,7).setValue(new Date()).setNumberFormat('yyyy-mm-dd h:mm:');
datasheet.getRange(blankRow,8).setValue(new Date()).setNumberFormat('yyyy-mm-dd h:mm:');
datasheet.getRange(blankRow,6).setValue(srcData.getRange("C17").getValue()); //comments
ui.alert(' "New Data Saved - Input #' + shUserForm.getRange("C7").getValue() + '"');
shUserForm.getRange("C7").clear();
shUserForm.getRange("C9").clear();
shUserForm.getRange("C11").clear();
shUserForm.getRange("C13").clear();
shUserForm.getRange("C15").clear();
shUserForm.getRange("C17").clear();
}
}
To save data to another Spreadsheet, You need to open it first by using either openById("insert sheet id here") or openByUrl("insert sheet URL here"). This will return a Spreadsheet class which has getSheetByName("sheet name") method you can use to access the Sheet.
ID of the spreadsheet can be found in the url. This can be found after /d/ or before /edit
Example ID:
https://docs.google.com/spreadsheets/d/12345/edit#gid=0
12345 is the Spreadsheet ID
Example:
Code:
function saveData() {
//open current sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("Sheet1");
//open external sheet
var extSS = SpreadsheetApp.openById("Insert External Spreadsheet ID here");
var extSH = extSS.getSheetByName("Sheet1 External");
//get data from current Sheet.
var srcData = sh.getDataRange().getValues();
//write to external sheet
extSH.getRange(extSH.getLastRow()+1, 1, srcData.length, srcData[0].length).setValues(srcData);
}
This script will paste the values from Sheet1 to Sheet2
Before:
Sheet1 Data:
Sheet2 Data:
After:
Sheet1 Data:
Sheet2 Data:
SpreadsheetApp.openByID()
SpreadsheetApp.openByURL()
Spreadsheet.getSheetByName()
Class Sheet
Class Range
I'm totally lost here!
My spreadsheet has one sheet " Product Master Record" with a table containing three columns: Product ID (numerical) | Product Description | Product Status.
Each product has its own sheet within the spreadsheet.
The name of each sheet depends on the product status:
- "Active" product: sheet name = product name --> Sheet is visible
- "Inactive" product: sheet name = product ID --> Sheet is hidden
So I'm trying to write a macro which hide/shows sheets depending on the condition:
Product status (active/inactive)
Sheet name (if name contains text or not)
I don't need to write both conditions; only the easiest one to code.
Any ideas??
Thank you!
Here the sample for your purpose, ProdMaster, row 1 header [ProdId,Desc,Status], and rows afterward are data, and Status will be Inactive and Active:
function HideSheets() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName('ProdMaster');
var lrow = sheet.getLastRow();
var myValue = sheet.getRange("A2:C" + lrow).getValues();
for (a=1; a<myValue.length+1; a++)
{
var target = myValue[a-1];
var tsheet = spreadsheet.getSheetByName(target[0]);
if(tsheet==null) spreadsheet.insertSheet(target[0]);
if(target[2]=='Active') tsheet.showSheet();
if(target[2]=='Inactive') tsheet.hideSheet();
}
};
As a way for solving your problem you could do the following, instead of using "Active" or "Inactive" as checkers for validating a boolean condition, in your "Product Master Record" you could set the status using the functions TRUE and FALSE, in that way you could decouple hardcoded text from your code and avoid the trouble from someone misspelling the words "Active" or "Inactive".
function HideSheets() {
// Get the active sheet and range of rows you want
var spreadSheet = SpreadsheetApp.getActive();
var mainSheet = spreadSheet.getSheetByName('Product Master Record');
var rows = mainSheet.getRange("A2:C" + mainSheet.getLastRow()).getValues();
// Iterate over all rows
for(row in rows){
// Get the sheets from their names and check if not null
var secondarySheet = spreadSheet.getSheetByName(rows[row][0]);
if(secondarySheet){
if(rows[row][2]) secondarySheet.showSheet(); // show the sheet if value is true
if(!rows[row][2]) secondarySheet.hideSheet(); // hide sheet if value is false
}
}
};
Docs
I can see your new in this wonderful world. I will give you some docs to help you in your path of learning:
Google Apps Script Reference
Overview of Google Apps Script
Class Sheet
Thank you all!
Finally I found help with a colleague and it works. This is the code in case someone finds useful:
function updateSheetFromIndex(index)
{
var app = SpreadsheetApp;
var ss = app.getActiveSpreadsheet();
var activeSheet = ss.getSheetByName(sheetNameOfTheMenu);
var cell = activeSheet.getRange(index, 5);
var formula = cell.getFormula();
var regExpr = /\#gid=([0-9]*)"/;
var result = regExpr.exec(formula);
var cellStatus = activeSheet.getRange(index, 4);
Logger.log(index)
if (result != null) {
var gid = result[1];
for each (var sheet in SpreadsheetApp.getActive().getSheets()) {
if(sheet.getSheetId()==gid){
if (cellStatus.getValue() == "Activo") {
Logger.log("Activo---");
sheet.showSheet();
}
if (cellStatus.getValue() == "Inactivo") {
Logger.log("Inactivo---");
sheet.hideSheet();
}
break;
}
}
} else {
Logger.log("+++ No pattern matches");
Logger.log("Formula");
Logger.log(formula);
}
}
This question already has answers here:
How to convert VBA script to Google Apps Script automatically?
(3 answers)
Closed 1 year ago.
Have the below VBA and i need to insert it into a Google Sheet,
Can somebody help with the conversion?
Sub Activate_Sheet()
Sheets(Sheets("Main").Range("A1").Value).Activate
End Sub
Thanks,
This script gets the value in cell A1 in sheet()[0], and then moves to that sheet number.
function so_53361440() {
// set up spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// set sheet 0 as the active sheet
var sheet = ss.getSheets()[0];
// get the value in cell A1
var cell = sheet.getRange("A1").getValue();
// Logger.log("value of cell = "+cell);// DEBUG
// Convert number to string
var sheetname = ""+ cell;
// Logger.log("sheetname = "+sheetname);// DEBUG
// set sheet by name and move to new sheet
var mysheet = ss.getSheetByName(sheetname);
ss.setActiveSheet(mysheet);
}
Variation on a theme
With 300 sheets, going back to sheet()[0] will get frustrating. So this small variation is designed to create a custom menu that will request the sheet number in an inputbox. The rest of the code is the same
function so_53361440_01() {
// setup ui
var ui = SpreadsheetApp.getUi();
var result = ui.prompt(
'What sheet do you want?',
'Please enter a number:',
ui.ButtonSet.OK_CANCEL);
// Process the user's response.
var button = result.getSelectedButton();
var text = result.getResponseText();
if (button == ui.Button.OK) {
// User clicked "OK".
//ui.alert('Sheet is ' + text + '.');
} else if (button == ui.Button.CANCEL) {
// User clicked "Cancel".
ui.alert('Operation Cancelled.');
} else if (button == ui.Button.CLOSE) {
// User clicked X in the title bar.
ui.alert('Input Box closed - no action taken.');
}
// set up spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// assign the UI value to a variable
var cell = text;
// Logger.log("value of cell = "+cell);//DEBUG
// convert the variable to a string
var sheetname = ""+ cell;
// Logger.log("sheetname = "+sheetname);// DEBUG
// set the sheetname to the variable and goto that sheet
var mysheet = ss.getSheetByName(sheetname);
ss.setActiveSheet(mysheet);
}
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('Change Sheet')
.addItem('Pick a sheet', 'so_53361440_01')
.addToUi();
}
Right now, my code is sending my entire Google Sheet file as a PDF attachment. I am needing it, though, to only send my one tab entitled "PO Template". Let me know if you can help:
function emailGoogleSpreadsheetAsPDF() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var email = ss.getRange("A19").getValue();
var PO = ss.getRange("N3").getValue();
var subject = "PO No. " + PO;
var blob =
DriveApp.getFileById(shs.getId()).getAs("Application/pdf");
var body = "Install the <a href='http://www.labnol.org/email-
sheet'>Email Spreadsheet add-on</a> for one-click conversion.";
blob.setName(ss.getName()+".pdf");
if(MailApp.getRemainingDailyQuota()>0)
GmailApp.sendEmail(email, subject, body, {
htmlBody: body,
attachments:[blob]
});
}
Don't think there's an adhoc method to do this. You'll have to resort to a workaround as suggested by this github tutorial:
// Create a new Spreadsheet and copy the current sheet into it.
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export");
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var projectname = SpreadsheetApp.getActiveSpreadsheet();
sheet = originalSpreadsheet.getActiveSheet();
sheet.copyTo(newSpreadsheet);
// Find and delete the default "Sheet 1", after the copy to avoid triggering an apocalypse
newSpreadsheet.getSheetByName('Sheet1').activate();
newSpreadsheet.deleteActiveSheet();
I am using Google Scripts UiApp in order to gather availability information. I want to send this information to a spreadsheet. I have used the example here: http://www.googleappsscript.org/advanced-examples/insert-data-in-sheet-using-ui-forms
to get me started in the right direction.
The Web App looks good and when clicking submit, the appropriate message displays. However, the values that are transferred to the spreadsheet say "undefined" for all of the entries.
How can I convince it to link the textbox entered data to the variables so that I can transfer to the spreadsheet?
Thanks!!
Here is some code:
var submissioSSKey = // Key removed
function doGet() {
var rows = 15
var columns = 15
var mygrid = UiApp.createApplication().setTitle("MLC Walk Ins Scheduling")
var panel = mygrid.createSimplePanel();
// Define the grid layout
var grid = mygrid.createGrid(rows, columns).setCellPadding(2).setCellSpacing(8)
// Create the text at the top
var Title = mygrid.createLabel("Walk-In Scheduling")
grid.setWidget(1, 1, Title)
(snip) - creating various checkboxes and textboxes
var text1 = mygrid.createTextBox().setName('name1')
grid.setWidget(3,9,text1)
var text6 = mygrid.createTextBox().setName('message1')
grid.setWidget(4,9,text6)
// Create the "submit" button
var submit_button = mygrid.createButton("Submit")
grid.setWidget(12,9,submit_button)
var infoLabel = mygrid.createLabel('Availability inserted successfully.').setVisible(false).setId('info');
grid.setWidget(13,9,infoLabel)
var handler = mygrid.createServerClickHandler('insertInSS');
handler.addCallbackElement(panel);
submit_button.addClickHandler(handler);
panel.add(grid);
mygrid.add(panel);
mygrid.add(grid);
return mygrid
}
Then the function call for the button:
//Function to insert data in the sheet on clicking the submit button
function insertInSS(e){
var mygrid = UiApp.getActiveApplication()
var name1 = e.parameter.name1
var message1 = e.parameter.message1
mygrid.getElementById('info').setVisible(true).setStyleAttribute('color','blue')
var sheet = SpreadsheetApp.openById(submissioSSKey).getActiveSheet()
var lastRow = sheet.getLastRow()
var targetRange = sheet.getRange(lastRow+1, 1, 1, 2).setValues([[name1,message1]])
return mygrid
}
Ahh! A simple fix for a big headache.
I had an extra line:
mygrid.add(grid);
that was breaking it.