I have the following code that works perfect on the rest of my google sheet
but as people have started missing data when filling in the sheet i have made a google form for them to use when adding in the information
The only issue is that my "onedit" macro works on every tab except the "responses tab" from the google form
Is there any way to get this to work?
function onEdit(e) {
var row = e.range.getRow();
var col = e.range.getColumn();
var value = e.range.getValue();
var sheet = e.source.getActiveSheet().getName();
var destination = e.source.getActiveSheet().getRange(row,21);
var destination2 = e.source.getActiveSheet().getRange(row,22);
if(col === 1 && row > 1 && value === "NO" && destination.getValue() ===""){
e.source.getActiveSheet().getRange(row,21).setValue(new Date(new Date().setHours(0,0,0,0))).setNumberFormat('dd-MMM-yy');
}
if(col === 1 && row > 1 && value === "YES" && destination2.getValue() ===""){
e.source.getActiveSheet().getRange(row,22).setValue(new Date(new Date().setHours(0,0,0,0))).setNumberFormat('dd-MMM-yy');
}
}
function onEdit(e) {
const sh = e.range.getSheet();
const nd = new Date();
const dt = new Date(dt.getFullYear(), nd.getMonth(), nd.getDate());
if (e.range.columnStart == 1 && e.range.rowStart > 1 && e.value == "NO" && sh.getRange(e.range.rowStart, 21).getValue() == "") {
sh.getRange(e.range.rowStart, 21).setValue(nd).setNumberFormat('dd-MMM-yy');
}
if (e.range.columnStart == 1 && e.range.rowStrart > 1 && e.value === "YES" && sh.getRange(e.range.rowStart, 22).getValue() == "") {
sh.getRange(e.range.rowStart, 22).setValue(nd).setNumberFormat('dd-MMM-yy');
}
}
Related
here's my activesheet is "_input"
range F12:F21 checkboxes when it false then using default formula, when true then input normal number in offset(0,1) which is column G12:G21
range G24 is dropdown which will update offset(0,1) value, H24, when update.
here's my code
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('_input');
var range = sheet.getActiveCell();
var def = 6; // column A = 1, B = 2, etc.
var opt = false;
var row = 11;
if (range.getColumn() == def && range.getValue() == opt && range.getRow()> row && range.getRow()< 22) {
range.offset(0, 1).setValue('=IFERROR(VLOOKUP(inpItem,mstItem,2,0),0)');
}
}
function onEdit(evt) {
var sh = evt.source.getActiveSheet();
var rng = evt.source.getActiveRange("");
var tBat = rng.offset(0,1);
if (sh.getName() == '_input' && rng.getColumn() == 7 && rng.getRow() > 23 && rng.getValue() == "B1") {
tBat.setValue('09:00');
} else if (sh.getName() == '_input' && rng.getColumn() == 7 && rng.getRow() > 23 && rng.getValue() == "B2") {
tBat.setValue('15:00');
} else {
tBat.clearContent();
tBat.setNumberFormat("HH:mm");
}
}
but it doesn't work properly because when i change one of onEdit function to make another onEdit function running.
please advise for my mistake here.
When i change F12:F21 and run script to edit G12:G21 won't effect to G24 and H24.
I have a script that adds a timestamp to a cell when another cell in the row is initially filled in. What I would like to do is only timestamp when a cell contains the word "Completed". It doesn't seem to be working though.
var SHEET_NAME = 'Sheet 1';
var DATETIME_HEADER = 'datetime';
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());
//Here's the line where I added an "if the active cell is labelled completed then add a timestamp to the datetime column"
if (ss.getName() == SHEET_NAME && cell.getColumn() == 8 && !cell.isBlank() && datecell.isBlank() && cell.getValues == "Completed") {
datecell.setValue(new Date()).setNumberFormat("yyyy-MM-dd hh:mm");
}
}
;
Try it this way:
function onEdit(e) {
const sh = e.range.getSheet();
const col = sh.getRange(1,1,1,sh.getLastColumn()).getValues().flat().reduce((a,h,i)=> (a[h]=i+1,a),{});
const dateCell = sh.getRange(e.range.rowStart,col['datetime']);
if (sh.getName() == "SHEET_NAME" && e.range.columnStart == 8 && datecell.isBlank() && e.value == "Completed") {
datecell.setValue(new Date()).setNumberFormat("yyyy-MM-dd hh:mm");
}
}
I am trying to create radio checkboxes, i managed to make it work when the checkboxes are in vertical as shown in the exemple sheet bellow with the tab name 'Radio 1' but i have another tab 'Radio 2' where the checkboxes are aligned horizontally and are not aligned one after the other but after every 2 cells, the first Radio works with the following code
function onEdit(e) {
if (e.range.columnStart != 2 || e.range.rowStart == 1 || e.range.rowStart > 8 || e.value != "TRUE") return;
let r = SpreadsheetApp.getActive().getActiveSheet().getRange(2,2,7);
let checks = r.getValues();
for (let i in checks){
if(checks[i][0] == true && +i != e.range.rowStart - 2)
checks[i][0] = false;
}
r.setValues(checks);
}
but i cant make it to work when adapting to the second radio tab, any ideas?
sheet link
Try
function onEdit(e) {
var sh = e.source.getActiveSheet()
if (sh.getName() == 'Radio 1') {
if (e.range.columnStart != 2 || e.range.rowStart == 1 || e.range.rowStart > 8 || e.value != "TRUE") return;
let r = SpreadsheetApp.getActive().getActiveSheet().getRange(2, 2, 7);
let checks = r.getValues();
for (let i in checks) {
if (checks[i][0] == true && +i != e.range.rowStart - 2)
checks[i][0] = false;
}
r.setValues(checks);
}
else if (sh.getName() == 'Radio 2') {
var cel = e.source.getActiveRange()
if (cel.getRow() == 11 && cel.getValue() == true) {
var r = sh.getRange('H' + cel.getRow() + ':S' + cel.getRow())
var checks = r.getValues()
for (var i=0;i<checks[0].length;i+=2) {
if (checks[0][i] == true && i != cel.getColumn()-8)
if (checks[0][i]==true) {checks[0][i] = false};
}
r.setValues(checks);
}
}
}
If you want to apply to multi-rows, change this cel.getRow() == 11
In your situation, how about the following modification?
Modified script:
In this modification, the cell ranges of checkboxes are used.
function onEdit(e) {
// This is from your sample Spreadsheet.
// The cell ranges of checkboxes are set as A1Notation.
const obj = {
'Radio 1': ["B2", "B3", "B4", "B5", "B6", "B7", "B8"],
'Radio 2': ["H11", "J11", "L11", "N11", "P11", "R11"]
};
const sheet = e.source.getActiveSheet();
const sheetName = sheet.getSheetName();
const a1Notation = e.range.getA1Notation();
if (!obj[sheetName] || !obj[sheetName].includes(a1Notation) || e.range.getValue() === false) return;
sheet.getRangeList(obj[sheetName].filter(e => e != a1Notation)).uncheck();
}
When this script is run, when a checkbox is checked on "Radio 1" or "Radio 2", other checked checkboxes are unchecked.
If you want to add "Radio 3" and others, please add them to obj.
Note:
When you changed the checkboxes and the sheet names, please modify obj. Please be careful about this.
References:
filter()
uncheck() of Class RangeList
Good afternoon;
I am working on a google sheet with 2 columns "New Data" and "Completed". I have the New Data set with a check box that moves the row to the completed sheet once it is checked. Once on the completed sheet I would like to fill in a date and time stamp under comlumn E to show when it was moved to completed. What I have so far is listed below. Currently when it moves over from new data nothing happens. I also have a trigger set on addCompleteDate to work onEdit. Any help is appreciated.
function onEdit(e) {
const src = e.source.getActiveSheet();
const r = e.range;
if(src.getName() != "New Data" || r.columnStart != 6 || r.rowStart == 1) return;
const dest = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Completed");
src.getRange(r.rowStart, 1, 1 ,4).moveTo(dest.getRange(dest.getLastRow()+1,1,1,4));
src.deleteRow(r.rowStart);
}
function addCompleteDate(e){
const row = e.source.range.getRow();
const col = e.source.getSheetByName("Completed").columns[2];
if(col && col != "" && row > 1 ){
const currentDate = new Date();
e.source.getActiveSheet().getRange(row, 5).setValue(currentDate);
}
}
Just combine them together
function onEdit(e) {
const sh = e.range.getSheet();
if (sh.getName() == "New Data" && e.range.columnStart == 6 || e.range.rowStart > 1) {
const dsh = e.source.getSheetByName("Completed");
const dnr = dsh.getLastRow() + 1;
sh.getRange(e.range.rowStart, 1, 1, 4).moveTo(dsh.getRange(dnr, 1, 1, 4));
sh.deleteRow(e.range.rowStart);
dsh.getRange(dnr,5).setValue(new Date());
}
}
What do I add to the if statement to check if Column 5 in the applicable row contains a value and prevent the setValue() from overriding the old value?
function onEdit(e) {
var sheet = e.source.getActiveSheet();
var i = ['Sheet1', 'Sheet2'].indexOf(sheet.getName());
if (e.range.getValue() != '' && i > -1 && e.range.columnStart === 1) {
e.range.offset(0,4).setValue(Utilities.formatDate(new Date(), "GMT-8", "MM/dd/yyyy"));
}
}
Explanation:
Add a condition in the if statement for column 5 to be empty at row in order to fill it:
sheet.getRange(row,5).getValue()==''
Solution:
function onEdit(e) {
var sheet = e.source.getActiveSheet();
var row = e.range.getRow();
var i = ['Sheet1', 'Sheet2'].indexOf(sheet.getName());
if (e.range.getValue() != '' && i > -1 && e.range.columnStart === 1 && sheet.getRange(row,5).getValue()=='') {
e.range.offset(0,4).setValue(Utilities.formatDate(new Date(), "GMT-8", "MM/dd/yyyy"));
}
}
Or:
I formatted your code a little bit to make it more compact:
function onEdit(e) {
const sheet = e.source.getActiveSheet();
const row = e.range.getRow();
const col = e.range.getColumn();
const sheets = ['Sheet1', 'Sheet2'];
if (e.range.getValue() != '' && sheets.includes(sheet.getName())
&& col === 1 && sheet.getRange(row,5).getValue()==''){
e.range.offset(0,4).setValue(Utilities.formatDate(new Date(), "GMT-8", "MM/dd/yyyy"));
}
}