I want to apply script to multiple subsheet in one Sheet - javascript

I followed youtube instruction and copied this script
var SHEET_NAME = 'Sheet1';
var DATETIME_HEADER = '입력일시';
function getDatetimeCol(){
var headers = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME).getDataRange().getValues().shift();
var colindex = headers.indexOf(DATETIME_HEADER);
return colindex+1;
}
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSheet();
var cell = ss.getActiveCell();
var datecell = ss.getRange(cell.getRowIndex(), getDatetimeCol());
if (ss.getName() == SHEET_NAME && cell.getColumn() == 1 && !cell.isBlank() && datecell.isBlank()) {
datecell.setValue(new Date()).setNumberFormat("yyyy-MM-dd hh:mm:ss");
}
};
I want to apply this script to all subsheet in the file.
so I tried to add more sheet name like
var SHEET_NAME = 'Sheet1'; => var SHEET_NAME = ['Sheet1','Sheet2','Sheet3',]
or
var SHEET_NAME = 'Sheet1';
var SHEET_NAME = 'Sheet2';
var SHEET_NAME = 'Sheet3';
and they didn' work.
I don't have any, even rudimentary knowledge to this area, could you teach me how can I apply this script on whole subsheet, please?

I have changed your code slightly according to the task at hand:
SHEET_NAMES = ['Sheet1','Sheet2','Sheet3'];
DATETIME_HEADER = '입력일시';
function onEdit(e) {
let range = e.range,
sheet = range.getSheet();
if (SHEET_NAMES.includes(sheet.getName()) && range.rowStart > 1 && range.columnStart == 1 && !e.value == '') {
let colindex = sheet.getDataRange().getValues().shift().indexOf(DATETIME_HEADER)+1,
datecell = sheet.getRange(range.rowStart,colindex);
if (datecell.isBlank()) datecell.setValue(new Date()).setNumberFormat("yyyy-MM-dd hh:mm:ss");
}
};
I don't think it's a good idea to run getDatetimeCol() every time you make a change in the table - it's better to do it only when the changes occur in the right sheets and cells

Related

How to make a loop script for Google sheet?

I wanted to have a script that will change text to a hyperlink using script. I have column D in Google sheet from D1:D, for example:
12346
34566
23456
23455... and so on...
Currently, I'm using this script, this is for a specific tab named Sheet1 only.
function makeLink() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var aCell = ss.getRange("D1"), value = aCell.getValue();
aCell.setValue('=HYPERLINK("https://sellercentral.amazon.com/hzefad/orders/&orderId='+value+'","'+value+'")');
var aCell = ss.getRange("D2"), value = aCell.getValue();
aCell.setValue('=HYPERLINK("https://sellercentral.amazon.com/hzefad/orders/&orderId='+value+'","'+value+'")');
var aCell = ss.getRange("D3"), value = aCell.getValue();
aCell.setValue('=HYPERLINK("https://sellercentral.amazon.com/hzefad/orders/&orderId='+value+'","'+value+'")');
var aCell = ss.getRange("D4"), value = aCell.getValue();
aCell.setValue('=HYPERLINK("https://sellercentral.amazon.com/hzefad/orders/&orderId='+value+'","'+value+'")');
var aCell = ss.getRange("D5"), value = aCell.getValue();
}
Is there a way to to use looping for me to shorten my script?
You can use something like this:
i = 1
while (true) {
var range = ss.getRange("D" + i);
var value = range.getValue();
if(value == "") {
break;
}
range.setValue('=HYPERLINK("https://sellercentral.amazon.com/hzefad/orders/&orderId='+value+'","'+value+'")');
i++;
}

Prevent google script from duplicating protected ranges

I have this script that I am using to copy over (convert formulas to values) and then protect the range when a user enters a value "Burned" in to a certain cell (A2, A6, etc) at the end of each month (can't make it triggered by date as users may be completing data entry on slightly different dates). The spreadsheet needs users to lock the data every month, so the script is set up for converting and protecting data each month as the user enters "Burned" into each month. The script is working well to convert formulas to values and it is also working to protect the range. However, every time I edit the sheet, it creates duplicate protected ranges so I end up with multiple protected ranges called January Burned, February Burned, etc. Is there any way to prevent the script from duplicating the protected ranges? Any help is greatly appreciated.
function onEdit(e)
//January
{
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckA = sheet.getRange("A2").getValue();
var rangeA = sheet.getRange("A2:AZ5");
{
if(valueToCheckA == "Burned")
{
rangeA.copyTo(rangeA, {contentsOnly:true});
var protection = rangeA.protect().setWarningOnly(true).setDescription('January Burned');
}
}
}
//February
{
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckB = sheet.getRange("A6").getValue();
var rangeB = sheet.getRange("A6:AZ9");
{
if(valueToCheckB == "Burned")
{
rangeB.copyTo(rangeB, {contentsOnly:true});
var protection = rangeB.protect().setWarningOnly(true).setDescription('February Burned');
}
}
}
//March
{
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckC = sheet.getRange("A10").getValue();
var rangeC = sheet.getRange("A10:AZ13");
{
if(valueToCheckC == "Burned")
{
rangeC.copyTo(rangeC, {contentsOnly:true});
var protection = rangeC.protect().setWarningOnly(true).setDescription('March Burned');
}
}
}
You had some weird things going on in your code. So I'd reformat it like this:
//January
function onEdit(e)
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckA = sheet.getRange("A2").getValue();
var rangeA = sheet.getRange("A2:AZ5");
if(valueToCheckA == "Burned")
{
rangeA.copyTo(rangeA, {contentsOnly:true});
var protection = rangeA.protect().setWarningOnly(true).setDescription('January Burned');
}
}
Try it again and let me know if anything has changed.
After looking over you code again. I grabbed entire code and took a close look at it and I made an interesting discovery. Several of your sections of code are not within the function onEdit so they run every time you access your scripts even when onEdit is not called. In fact, when I think about it, I believe you just run this once a month so why not just put it in a separate function and call once a month and forget the onEdit trigger.
function onEdit(e)
{
var ss = SpreadsheetApp.getActive();//January
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckA = sheet.getRange("A2").getValue();
var rangeA = sheet.getRange("A2:AZ5");
if(valueToCheckA == "Burned")
{
rangeA.copyTo(rangeA, {contentsOnly:true});
var protection = rangeA.protect().setWarningOnly(true).setDescription('January Burned');
}
}
// This section is not in the onEdit function so it's run every time you come to this page
var ss = SpreadsheetApp.getActive();//February
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckB = sheet.getRange("A6").getValue();
var rangeB = sheet.getRange("A6:AZ9");
if(valueToCheckB == "Burned")
{
rangeB.copyTo(rangeB, {contentsOnly:true});
var protection = rangeB.protect().setWarningOnly(true).setDescription('February Burned');
}
// This section is not in the onEdit function so it's run every time you come to this page
var ss = SpreadsheetApp.getActive();//March
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckC = sheet.getRange("A10").getValue();
var rangeC = sheet.getRange("A10:AZ13");
if(valueToCheckC == "Burned")
{
rangeC.copyTo(rangeC, {contentsOnly:true});
var protection = rangeC.protect().setWarningOnly(true).setDescription('March Burned');
}
So here's a rough start of a function that could do the job for you and you can just run it once a month. I haven't tested it and it most likely has some mistakes in it so check it out.
function monthlyBurn()
{
var ui = SpreadsheetApp.getUi();
var response = ui.prompt('Enter checkCell,protectRange,description all separate by commas', ui.ButtonSet.OK);
var t = response.getResponseText().split(',');
if(t.length !== 3)
{
ui.alert('Invalid input. Your missing a parameter')
return;
}
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Caseload");
var valueToCheckC = sheet.getRange(t[0]).getValue();
var rangeC = sheet.getRange(t[1]);
if(valueToCheckC == "Burned")
{
rangeC.copyTo(rangeC, {contentsOnly:true});
var protection = rangeC.protect().setWarningOnly(true).setDescription(t[2]);
}
}
Thanks for all the input and assistance, I have spoken with a colleague who was able to write this script which is working great.
function onEdit(e)
{
var sheet = e.range.getSheet();
if (sheet.getName() != "Caseload" || e.value != "Burned") return;
var moment = Moment.load();
var date = moment.utc(e.range.offset(0, 1).getValue());
if (!date.isValid()) return;
var month = date.format('MMMM');
var range = sheet.getRange(e.range.getRow(), e.range.getColumn(), 4, 26*2); // 4 rows and 26*2 columns (AZ)
range.copyTo(range, {contentsOnly: true});
range.protect().setWarningOnly(true).setDescription(month + ' Burned');

sending data from a google spreadsheet program to google calender

Here is my case.
A user fills a form for event booking, the submitted form is stored in a google spreadsheet which I have synced to a google calender so that it automatically sends the data to it.
Everything is working fine apart from the fact that event times could clash.
When customers book an event centre for let's say on 13/3/2015 T 10:00AM, if another user enters the same date and time, the entry should not be accepted.
To summarise it, I want to avoid a clash of events booking. Thank you all.
here is my script.
var calendarId = "mycalenderid";
//below are the column ids of that represents the values used in the spreadsheet (these are non zero indexed)
var startDtId = 9;
var endDtId = 10;
var titleId = 6;
var descId = 11;
var formTimeStampId = 1;
function getLatestAndSubmitToCalendar() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var lr = rows.getLastRow();
var startDt = sheet.getRange(lr,startDtId,1,1).getValue();
//set to first hour and minute of the day.
//startDt.setHours(0);
//startDt.setMinutes(00);
var endDt = sheet.getRange(lr,endDtId,1,1).getValue();
//set endDt to last hour and minute of the day
//endDt.setHours(23);
//endDt.setMinutes(59);
var subOn = "Submitted on:"+sheet.getRange(lr,formTimeStampId,1,1).getValue();
var desc = "Added by :"+sheet.getRange(lr,descId,1,1).getValue()+"\n"+subOn;
var title = sheet.getRange(lr,titleId,1,1).getValue()+"DIA";
createEvent(calendarId,title,startDt,endDt,desc);
}
function createEvent(calendarId,title,startDt,endDt,desc) {
var cal = CalendarApp.getCalendarById(calendarId);
var start = new Date(startDt);
var end = new Date(endDt);
var loc = 'Script Center';
var event = cal.createEvent(title, start, end, {
description : desc,
location : loc
});
};
Here's a pseudocode of what you're trying to do:
function findEvent(desiredDateTime)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var range = sheet.getDataRange();
var data = range.getValues();
var lRow = range.getLastRow();
var flag = true;
var count = 0;
while (flag == true || count < lRow)
{
if (desiredDateTime >= data[count][startDtId] && desiredDateTime <= data[count][endDtId])
{
flag = false;
}
else
{
count++;
}
}
if (flag == true)
{
//Call function to add event
}else{
//Tell user desired date-time is not available.
//If you're asking for user's email address,
//simplest approach would be to send an email.
}
}
You might have to modify other bits and pieces of your code as well to accommodate this but it shouldn't be too hard. Hope this provides you with a certain direction to follow through.

google apps script doGet

I'm having problems with this code. Google deprecated several pieces that were working. Now when making a new sheet and trying to use the old code, I get errors and can't find the way to make changes with the documentation at google.
function doGet(e) {
//This is not working?
if (typeof e.parameter.id == 'undefined'){
return no_id(e) // The URL doesn't have an ?id=345 on the end!
}
var id = parseInt( e.parameter.id ) // This is the id of the row in the spreadsheet.
//Script properties is changed and I think it is now: PropertyService.getScriptProperties() // Get the data from the spreadsheet and get the row that matches the id
var this_spreadsheet_id = ScriptProperties.getProperty('this_spreadsheet_id')
var ss = SpreadsheetApp.openById(this_spreadsheet_id)
var sheet = ss.getSheetByName("Sheet1")
var range = sheet.getDataRange()
var last_row = range.getLastRow()
var last_column = range.getLastColumn()
for(i = 2; i <= last_row ; i++){
var this_row = sheet.getRange(i,1 , 1, last_column)
var values = this_row.getValues()[0]
var row_id = parseInt( values[0] )
//row id == id is not working either
if ( row_id == id){
var title = values[5]
var details = values[8]
var status_txt = values[7]
Logger.log( "STATUS: " + status )
var image_url = values[4]
}
}
}
Any idea's would be great!
Thanks,
"ReferenceError: "id" is not defined. (line 23, file "Code")"
You have a return in an if statement before the id is defined. So if it is not being defined then the if statement is being triggered. Move your variable definitions to the top.
var id = parseInt( e.parameter.id ) // This is the id of the row in the spreadsheet.
//Script properties is changed and I think it is now: PropertyService.getScriptProperties() // Get the data from the spreadsheet and get the row that matches the id
var this_spreadsheet_id = ScriptProperties.getProperty('this_spreadsheet_id')
var ss = SpreadsheetApp.openById(this_spreadsheet_id)
var sheet = ss.getSheetByName("Sheet1")
var range = sheet.getDataRange()
var last_row = range.getLastRow()
var last_column = range.getLastColumn()
if (typeof e.parameter.id == 'undefined'){
return no_id(e) // The URL doesn't have an ?id=345 on the end!
}

How to move individual cells in Google Sheets

Would anyone happen to know of a quick way to move the contents of one cell into another in Google Sheets. All of the cells will remain static, so I don't have to worry about additional rows or columns being added to my sheet.
I have tried to getCell(), just like the getLastColumn() function, but getCell() doesn't seem to be a valid function.
Code that I currently have:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Sheet4" && r.getColumn() == 15 && r.getValue() == "GO" ) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Sheet4");
ss.getSheets()[1].getRange("A48:A48").copyTo(ss.getSheets()[2].getRange("A3:A3"),{contentsOnly:true});
Something like this should work:
function CopyTo() {
var ss = SpreadsheetApp.getActive().getSheetByName('Sheet4');
var s = ss.getRange('H48');
s.copyTo(ss.getRange('D13'), {contentsOnly: true});
s.clear ();
}
Var source = ss.getRange ("Sheet4!H48:H48");
var targetSheet = ss.getSheetByName("Sheet4");
var targetRange = targetSheet.getRange("D13:D13");
source.copyTo(targetRange, {contentsOnly: true});
source.clear ();

Categories

Resources