I have three dropdown boxes that are dependent on each other. The code works fine but is really slow, 3 seconds to update the next box. I'm used to VBA and this is no problem in Excel, but it's really show in Google Sheets. I added a Browser.msgBox("here"); to the first line of the code and from changing the dropdown it takes 2 seconds to display it. This can't be normal?
Here's the code: (The list options are stored in Named Ranges, the correct name is generated and stored in the optName below )
function onEdit(event) {
if (!event) return;
//SETTINGS
var ss = event.source;
var sheet = event.source.getActiveSheet();
var r = event.source.getActiveRange();
var sheetName = sheet.getName()
if(sheet.getName() == 'Damages & Repairs July 2018') {
var lcol = 3; // leftmost column number you are monitoring
var rcol =6; // rightmost column number you are monitoring
}else{
var lcol = 4; // leftmost column number you are monitoring
var rcol =7; // rightmost column number you are monitorin
}
//
if (sheetName == 'Refunds July 2018' || sheetName == 'Exchanges July 2018'|| sheetName == 'Damages & Repairs July 2018') {
var sourceCol = r.getColumn();
var sourceRow = r.getRow();
var ss = SpreadsheetApp.getActiveSpreadsheet();
if(sheetName == 'Damages & Repairs July 2018') {
if(sourceCol == 4) {
var optName = sheet.getRange(sourceRow, lcol ).getValue() + sheet.getRange(sourceRow, lcol + 1).getValue();
} else if ( sourceCol == 5) {
var optName = sheet.getRange(sourceRow, lcol + 1).getValue();
} else {
var optName = sheet.getRange(sourceRow, sourceCol).getValue();
}
} else {
if(sourceCol == 5) {
var optName = sheet.getRange(sourceRow, lcol ).getValue() + sheet.getRange(sourceRow, lcol + 1).getValue();
} else if ( sourceCol == 6) {
var optName = sheet.getRange(sourceRow, lcol + 1).getValue();
} else {
var optName = sheet.getRange(sourceRow, sourceCol).getValue();
}
}
var optName = optName.replace(/\s/g, "");
var tableRange = ss.getRangeByName(optName).getValues();
var optList = "";
if (sourceCol >= lcol && sourceCol <= rcol) {
// define the dropdown/validation rules
var rangeRule = SpreadsheetApp.newDataValidation().requireValueInList(tableRange);
// Clear the validation
//sheet.getRange(sourceRow, sourceCol + 1).clearDataValidations()
//sheet.getRange(sourceRow, sourceCol + 1).clearContent()
// set the dropdown validation for the row
sheet.getRange(sourceRow, sourceCol + 1).setDataValidation(rangeRule); // set range to your range
}
}
}
Any help would be very much appreciated.
Thanks
Chris
UPDATE
I changed the code to this - but still not that much faster:
function onEdit(event) {
//SETTINGS
var ss = event.source;
var sheet = event.source.getActiveSheet();
var r = event.source.getActiveRange();
var sheetName = sheet.getName();
var sourceCol = r.getColumn();
var sourceRow = r.getRow();
if(sheet.getName() == 'Damages & Repairs July 2018') {
var lcol = 3; // leftmost column number you are monitoring
var rcol =6; // rightmost column number you are monitoring
}else{
var lcol = 4; // leftmost column number you are monitoring
var rcol =7; // rightmost column number you are monitorin
}
var sourceRange = sheet.getRange('R' + sourceRow + 'C' + lcol + ':R' + sourceRow + 'C' + rcol).getValues();
if (sheetName == 'Refunds July 2018' || sheetName == 'Exchanges July 2018'|| sheetName == 'Damages & Repairs July 2018') {
var ss = SpreadsheetApp.getActiveSpreadsheet();
if(sheetName == 'Damages & Repairs July 2018') {
if(sourceCol == 4) {
var optName = sourceRange[0][0] + sourceRange[0][1];
} else if ( sourceCol == 5) {
var optName = sourceRange[0][1];
} else {
var optName =sourceRange[0][0];
}
} else {
if(sourceCol == 5) {
var optName = sourceRange[0][0] + sourceRange[0][1];
} else if ( sourceCol == 6) {
var optName = sourceRange[0][1];
} else {
var optName = sourceRange[0][0];
}
}
var optName = optName.replace(/\s/g, "");
var tableRange = ss.getRangeByName(optName).getValues();
var optList = "";
if (sourceCol >= lcol && sourceCol <= rcol) {
// define the dropdown/validation rules
var rangeRule = SpreadsheetApp.newDataValidation().requireValueInList(tableRange);
// Clear the validation
sheet.getRange(sourceRow, sourceCol + 1).clearDataValidations()
sheet.getRange(sourceRow, sourceCol + 1).clearContent()
// set the dropdown validation for the row
sheet.getRange(sourceRow, sourceCol + 1).setDataValidation(rangeRule); // set range to your range
}
}
}
Related
Trying to set a cell's data validation to be between two numbers namely, 1 and the balance of items in a budget. It keeps giving the following error:
Oct 12, 2022, 9:41:14 PM Error Exception: The parameters
(number,String) don't match the method signature for
SpreadsheetApp.DataValidationBuilder.requireNumberBetween.
at applyQtyValidation(Code:242:8)
at getQtyValidationData(Code:233:3)
at onEdit(Code:59:7)
Please help...
//Global variables
var reqSheetName = "Material Requisition";
var colStructure = 1;
var colComponent = 2;
var colWorks = 3;
var colItem = 4;
var colQty = 5;
var colUnit = 6;
var colBalance = 7;
var colBudgetCode = 8;
var colDuplicate = 18;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var wsBudget = ss.getSheetByName("Budget");
var wsRequisition = ss.getSheetByName(reqSheetName);
var rawData = wsBudget.getRange(5, 1, wsBudget.getLastRow(), 7).getValues();
var arrDetails = [];
function onEdit(e) {
//variables needed
var editedCell = e.range;
var sheetName = editedCell.getSheet().getName();
var r = editedCell.getRow();
var c = editedCell.getColumn();
var valFilter = editedCell.getValue();
//Set order qty
if (sheetName === reqSheetName && c === colItem && r > 11) {
getQtyValidationData(r);
}
}
function getQtyValidationData(r) {
var minQty = 1;
var maxQty = wsRequisition.getRange(r, colBalance).getValue();
var cell = wsRequisition.getRange(r, colQty).getA1Notation();
applyQtyValidation(minQty, maxQty, cell);
}
function applyQtyValidation(minQty, maxQty, cell) {
var rule = SpreadsheetApp
.newDataValidation()
.requireNumberBetween(minQty, maxQty)
.setAllowInvalid(false)
.setHelpText("Select a number between " + minQty + " and " + maxQty)
.build();
wsRequisition.getRange(cell).setDataValidation(rule);
}
This is working:
function onEdit(e) {
e.source.toast('Entry');
const sh = e.range.getSheet();
if (sh.getName() == "Sheet1" && e.range.columnStart == 4 && e.range.rowStart > 11) {
e.source.toast('Gate1');
sh.getRange(e.range.rowStart, 5).clearDataValidations();
var maxQty = sh.getRange(e.range.rowStart, 7).getValue();
var rule = SpreadsheetApp.newDataValidation().requireNumberBetween(1, maxQty).setHelpText(`Select a number between 1 and ${maxQty}`).setAllowInvalid(true).build();
sh.getRange(e.range.rowStart, 5).setDataValidation(rule);
}
}
I would have preferred to do it like this:
function onEdit(e) {
e.source.toast('Entry');
const sh = e.range.getSheet();
if (sh.getName() == "Sheet1" && e.range.columnStart == 4 && e.range.rowStart > 11) {
e.source.toast('Gate1');
sh.getRange(e.range.rowStart, 5).clearDataValidations();
var maxQty = sh.getRange(e.range.rowStart, 7).getValue();
let list = [...Array.from(new Array(maxQty).keys(),x => String(Number(x+1)))];
Logger.log(JSON.stringify(list));
var rule = SpreadsheetApp.newDataValidation().requireValueInList(list).setHelpText(`Select a number between 1 and ${maxQty}`).setAllowInvalid(false).build();
sh.getRange(e.range.rowStart, 5).setDataValidation(rule);
}
}
Demo:
I am trying to transfer a row (range A:AE) from sheet NSI to the next available row in Sheet1 if cell AE= 1.
My code doesn't seem to work, please could somebody help me?
Thank you!!
function myFunction() {
function copyRows() {
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = sSheet.getSheetByName("NSI");
var lastRow = srcSheet.getLastRow();
for (var i = 2; i <= lastRow; i++) {
var srcRange = srcSheet.getRange("A" + i + ":AE" + i);
var cell = srcSheet.getRange("AE" + i);
var val = cell.getValue();
//sets the target sheet depending on the exam in column AE
if (val == "1") {
var tarSheet = sSheet.getSheetByName("Sheet1");
}
//insets the row in the correct target worksheet
var tarRow = tarSheet.getLastRow()+1;
tarSheet.insertRows(tarRow);
var tarRange = tarSheet.getRange("A" + (tarRow) + ":AE" + (tarRow));
srcRange.copyTo(tarRange);
}
};
}
function copyRows() {
var sSheet = SpreadsheetApp.getActive();
var srcSheet = sSheet.getSheetByName("NSI");
const vs = srcSheet.getRange(2, 1, srcSheet.getLastRow() - 1, 31).getDisplayValues();
var tarSheet = sSheet.getSheetByName("Sheet1");
vs.forEach(r => {
if (r[30] == "1") {
tarSheet.appendRow(r);
}
});
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
The dropdown list I want should be dynamic. So based on the options I choose in columns D and E, the dropdownlist in column E should show only the products that are in column C. Below i added the code where you can see how I have done the other dropdown lists.
var mainWsName = "Inkoop";
var wsVerkoop = "Verkoop"
var sittardWsName = "Sittard";
var merkColumn = 4;
var modelColumn = 5;
var categorieColumn = 6;
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(mainWsName);
var wVerkoop = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(wsVerkoop);
var wsSittard = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sittardWsName);
var arraySittard = wsSittard.getRange(2,1,wsSittard.getLastRow()-1,3).getValues();
function categorie(){
}
function onEdit(e){
var activeCell = e.range;
var val = activeCell.getValue();
var r = activeCell.getRow();
var c = activeCell.getColumn();
var wsName = activeCell.getSheet().getSheetName()
if(wsName == mainWsName && c == merkColumn && r > 1){
if(val === ""){
ws.getRange(r ,modelColumn).clearContent();
ws.getRange(r ,modelColumn).clearDataValidations();
ws.getRange(r ,categorieColumn).clearContent();
} else{
ws.getRange(r ,modelColumn).clearContent();
var filterarraySittard = arraySittard.filter(function(o){return o[0] === val});
var listToApply = filterarraySittard.map(function(o){ return o[1]});
var cell = ws.getRange(r ,modelColumn);
applyValidationToCell(listToApply, cell);
}
}
if(wsName == wsVerkoop && c == merkColumn && r > 1){
if(val === ""){
wVerkoop.getRange(r ,modelColumn).clearContent();
wVerkoop.getRange(r ,modelColumn).clearDataValidations();
wVerkoop.getRange(r ,categorieColumn).clearContent();
} else{
wVerkoop.getRange(r ,modelColumn).clearContent();
var filterarraySittard = arraySittard.filter(function(o){return o[0] === val});
var listToApply = filterarraySittard.map(function(o){ return o[1]});
var cell = wVerkoop.getRange(r ,modelColumn);
applyValidationToCell(listToApply, cell);
}
}
} // end onEdit
function applyValidationToCell(list,cell){
var rule = SpreadsheetApp.newDataValidation()
.requireValueInList(list)
.setAllowInvalid(false)
.build();
cell.setDataValidation(rule);
}
Try this:
Code:
var dstName = 'Sheet1';
var srcName = 'Sheet2';
var sprdSheet = SpreadsheetApp.getActiveSpreadsheet();
var dstSheet = sprdSheet.getSheetByName(dstName);
var srcSheet = sprdSheet.getSheetByName(srcName);
function populateMerk() {
var merk = dstSheet.getRange("D2:D");
var merkList = getData("", "A");
var rangeRule = SpreadsheetApp.newDataValidation().requireValueInList(merkList);
merk.setDataValidation(rangeRule);
}
function populateModel(id, row, sheetName) {
var model = dstSheet.getRange("E" + row);
var modelList = getData(id, "B");
var rangeRule = SpreadsheetApp.newDataValidation().requireValueInList(modelList);
var category = model.offset(0, 1);
var mValue = model.getValue();
model.clearDataValidations();
model.clearContent();
model.setDataValidation(rangeRule);
if (sheetName == dstName) {
category.clearDataValidations();
category.clearContent();
}
else if (sheetName == srcName) {
model.setValue(mValue);
}
}
function populateCategory(id, row, sheetName) {
var category = dstSheet.getRange("F" + row);
var categoryList = getData(id, "C");
var rangeRule = SpreadsheetApp.newDataValidation().requireValueInList(categoryList);
var cValue = category.getValue();
category.clearDataValidations();
category.clearContent();
category.setDataValidation(rangeRule);
if (sheetName == srcName) {
category.setValue(cValue);
}
}
function getData(srcId, endCol) {
var srcLastRow = srcSheet.getLastRow();
var srcData = srcSheet.getRange("A2:" + endCol + srcLastRow).getValues();
var dataList = [];
if (!srcId) {
// Get unique items for merk
dataList = srcData.flat().filter((item, i, ar) => ar.indexOf(item) === i);
}
else {
srcData.forEach(function(row) {
// Only add unique models
if (srcId == row[0] && !dataList.includes(row[1]) && !row[2]) {
dataList.push(row[1]);
}
// Only add unique categories
else if (srcId == (row[0] + row[1]) && !dataList.includes(row[2])) {
dataList.push(row[2]);
}
});
}
return dataList;
}
function onEdit(e) {
var sheetName = e.source.getActiveSheet().getName();
var range = e.range;
var col = range.getColumn();
var row = range.getRow();
if (row > 1) {
if (sheetName == dstName) {
var merk = dstSheet.getRange(row, 4).getValue();
var model = dstSheet.getRange(row, 5).getValue();
if (col == 4) {
populateModel(merk, row, sheetName);
}
else if (col == 5) {
populateCategory(merk + model, row);
}
}
else if (sheetName == srcName) {
switch (col) {
case 1:
populateMerk();
break;
case 2:
var lastE = dstSheet.getRange("E2:E").getValues().filter(String).length;
var merk;
for (var i = 0; i < lastE; i++) {
merk = dstSheet.getRange("D" + (i + 2)).getValue();
populateModel(merk, i + 2, sheetName);
}
break;
case 3:
var lastF = dstSheet.getRange("F2:F").getValues().filter(String).length;
var merk, model, row;
for (var i = 0; i < lastF; i++) {
row = i + 2;
merk = dstSheet.getRange("D" + row).getValue();
model = dstSheet.getRange("E" + row).getValue();
populateCategory(merk + model, row, sheetName);
}
break;
}
}
}
}
Sample data in Sheet2:
Outputs in Sheet1:
Note:
The code also notes when you edit your source sheet. If updated, will update all dropdowns for that column in the destination sheet. And since there will be a lot of calls when this happens, it will be a bit slow. You can still optimize that but for now, this still works.
Also, please see the references below and learn how we do things in StackOverflow as per Cooper's comment above:
References:
How to Ask
Code Formatting
Minimal Reproducible Example
Learn More
I am trying to copy a row over to a new sheet multiple times (based on user response).
After the row has been copied over x number of times, it should move to another sheet and then be removed from the original sheet.
I have it almost working but the while() loop will only subtract from the active cell once in row z and then just keeps repeating.
I would appreciate any help. Here is what I have:
function dupLines()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = SpreadsheetApp.getActiveSheet();
var r = SpreadsheetApp.getActiveRange();
var POStatus = ss.getSheetByName("PO STATUS");
var awarded = ss.getSheetByName("AWARDED");
var cell = s.getCurrentCell();
var cellValue = cell.getValue();
function getTimeStamp()
{
var now = new Date();
return ((now.getMonth() + 1) + '/' + (now.getDate()) + '/' + now.getFullYear() );
}
while (cellValue > '0')
{
POStatus.insertRows(19,1);
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetPO = POStatus.getRange("A19");
s.getRange(row, 1, 1, numColumns).copyTo(targetPO);
POStatus.getRange("X19").setValue(getTimeStamp());
cell.setValue(cellValue - 1);
}
awarded.insertRows(19,1);
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetAwd = awarded.getRange("A19");
s.getRange(row, 1, 1, numColumns).moveTo(targetAwd);
awarded.getRange("X19").setValue(getTimeStamp());
s.deleteRow(row);
}
******************* UPDATE ********************
This is what I have that is now working. I am sure it can be simplified?
function onOpen(e){
SpreadsheetApp.getUi().createMenu('QUEUE MENU')
.addItem('Create POs', 'CreatePOs')
.addSeparator()
.addItem('Sidebar Queue', 'openSidebar')
.addToUi();
}
function CreatePOs() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = SpreadsheetApp.getActiveSheet();
var r = SpreadsheetApp.getActiveRange();
var POStatus = ss.getSheetByName("PO STATUS");
var awarded = ss.getSheetByName("AWARDED");
if(s.getName() == "QUEUE" && r.getColumn() == 22 && r.getValue() == true) {
userInput();
dupLines();
moveToAwarded();
}
else
{
Browser.msgBox('Please check box in PO Status column.');
};
}
function userInput() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getCurrentCell().offset(0, 4).activate();
var prompt = SpreadsheetApp.getUi().prompt('How many lines do you want to send to PO STATUS?', SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
if(prompt.getSelectedButton() === SpreadsheetApp.getUi().Button.OK){
value = prompt.getResponseText();
}
spreadsheet.getCurrentCell().setValue(value);
}
function dupLines(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = SpreadsheetApp.getActiveSheet();
var r = SpreadsheetApp.getActiveRange();
var POStatus = ss.getSheetByName("PO STATUS");
var awarded = ss.getSheetByName("AWARDED");
var cell = s.getCurrentCell();
var cellValue = cell.getValue();
function getTimeStamp() {
var now = new Date();
return ((now.getMonth() + 1) + '/' +
(now.getDate()) + '/' +
now.getFullYear() );
}
while (cellValue > 0) {
POStatus.insertRows(19,1);
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetPO = POStatus.getRange("A19");
s.getRange(row, 1, 1, numColumns).copyTo(targetPO);
POStatus.getRange("X19").setValue(getTimeStamp());
cellValue--;
} }
function moveToAwarded() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = SpreadsheetApp.getActiveSheet();
var r = SpreadsheetApp.getActiveRange();
var POStatus = ss.getSheetByName("PO STATUS");
var awarded = ss.getSheetByName("AWARDED");
function getTimeStamp() {
var now = new Date();
return ((now.getMonth() + 1) + '/' +
(now.getDate()) + '/' +
now.getFullYear() );
}
awarded.insertRows(19,1);
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetAwd = awarded.getRange("A19");
s.getRange(row, 1, 1, numColumns).moveTo(targetAwd);
awarded.getRange("X19").setValue(getTimeStamp());
s.deleteRow(row);
}
function openSidebar(){
var html = HtmlService.createHtmlOutputFromFile('Sidebar').setTitle('Queue Quick View');
SpreadsheetApp.getUi().showSidebar(html);
}
One of the problems (and there may be others) that I can spot is in:
cell.setValue(cellValue - 1); // Changes the value in the cell but not in the script
This changes the value in the active cell. But it does not change the value of the variable cellValue.
Try this while-loop instead:
while (cellValue > '0')
{
POStatus.insertRows(19,1);
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetPO = POStatus.getRange("A19");
s.getRange(row, 1, 1, numColumns).copyTo(targetPO);
POStatus.getRange("X19").setValue(getTimeStamp());
cellValue--; // Reduce value by 1
cell.setValue(cellValue); // Set new value in cell
}
A few other suggestions that may help:
1
while (cellValue > '0') is checking for a string value '0'. It works because alphabetically, all positive numbers are greater than 1. But strictly speaking you want while (cellValue > 0)
2
cell.setValue(cellValue); has cosmetic value, i.e. it updates the cell. But the updated value is not used in the script.
Best practices suggest not making unnecessary calls to the sheet. So you could do without that line and have the script run a bit faster.
I've was wondering if what to do is possible and how to go about it. This is For Google Sheets. Here is the script I'm using (Found this script and edited it for my use):
function onEdit(e) {
var s = e.source.getActiveSheet().getName();
var cols = [5];
if (s !== 'Michele' && s !== 'Janet' && s !== 'Stephanie' || cols.indexOf(e.range.columnStart) ==-1 || !e.value) return;
e.range.offset(0,1).setValue(Utilities.formatDate(new Date(), "CST", "MM/dd/yyyy HH:mm:ss"));
}
Column 5 (E) has the option to choose different statuses. So far, I have it putting the TimeStamp of Column 5's change in its adjacent column, 6 (F). What I'm trying to figure out is if the status is changed again (Pending -> Confirmed-> Installed-> ect) , instead of updating Column 6, which would already be TimeStamped, it will instead move on to Column 7, then 8, then 9, ect.
Let me know if more detail is needed.
Thanks a Bunch!
I've tested this code and it works. It finds the number of cells to the right of column E that already have values in them, and then calculates what the next empty column is, and writes the new date to the next empty column.
function onEdit(e) {
var sh = e.source.getActiveSheet();
var s = sh.getName();
var lastCol = sh.getLastColumn();
var cols = [5];
var startCol = SpreadsheetApp.getActiveSpreadsheet().getRangeByName('ColumnE').getColumn();
//In the spreadsheet, name a range that is in the column you want to start at
if (s !== 'Michele' && s !== 'Janet' && s !== 'Stephanie' || cols.indexOf(e.range.columnStart) ==-1 || !e.value) return;
var rowEdited = e.range.getRow(); //Get the row that was edited
//Start in row edited and column 6, get 1 row and X columns
var datesInCells = sh.getRange(rowEdited,startCol,1,lastCol - 5).getValues();
Logger.log('datesInCells: ' + datesInCells);
Logger.log('datesInCells.length: ' + datesInCells[0].length);
var numberOfDates = 0;
for (var i=0;i<datesInCells[0].length;i+=1) {
if (datesInCells[0][i] !== "") {
numberOfDates +=1;
};
};
Logger.log('numberOfDates: ' + numberOfDates);
var colToWriteTo = startCol + numberOfDates;
var newDate = Utilities.formatDate(new Date(), "CST", "MM/dd/yyyy HH:mm:ss");
//var theStatus = sh.getRange(rowEdited, 5).getValue();
var theStatus = e.value;
var bothStatusAndDate = newDate + " : " + theStatus;
sh.getRange(rowEdited,colToWriteTo).setValue(bothStatusAndDate);
};
Version two:
function onEdit(e) {
var sh = e.source.getActiveSheet();
var s = sh.getName();
var lastCol = sh.getLastColumn();
var cols = [5];
if (s !== 'Michele' && s !== 'Janet' && s !== 'Stephanie' || cols.indexOf(e.range.columnStart) ==-1 || !e.value) return;
var rowEdited = e.range.getRow(); //Get the row that was edited
//Start in row edited and column 6, get 1 row and X columns
var datesInCells = sh.getRange(rowEdited,6,1,lastCol - 5).getValues();
Logger.log('datesInCells: ' + datesInCells);
Logger.log('datesInCells.length: ' + datesInCells[0].length);
var numberOfDates = 0;
for (var i=0;i<datesInCells[0].length;i+=1) {
if (datesInCells[0][i] !== "") {
numberOfDates +=1;
};
};
Logger.log('numberOfDates: ' + numberOfDates);
var newDate = Utilities.formatDate(new Date(), "CST", "MM/dd/yyyy HH:mm:ss");
if (numberOfDates > 4) {
var existingValues = sh.getRange(rowEdited,7,1,4).getValues();
sh.getRange(rowEdited,6,1,4).setValues(existingValues);
sh.getRange(rowEdited,10).setValue(newDate);
return;
};
var colToWriteTo = 6 + numberOfDates;
sh.getRange(rowEdited,colToWriteTo).setValue(newDate);
};