Брекетинг нескольких функций onEdit
У меня есть 3 функции сценария приложения onEdit в моей электронной таблице Google, которые работают индивидуально, но я не могу понять, где поставить скобки, чтобы вложить их.
Все они находятся в функции onEdit(e). Я понял, что вы не можете разделить функции onEdit, как другие функции. Скажите, пожалуйста, если я ошибаюсь.
Это мой код, который немного запутан и, вероятно, нуждается в приведении в порядок.
// Cut Employees Left from Unit Standards sheet and paste in Unit Standards - Employees Left sheet
function onEdit(e) {
var ss = e.source;
var sheet = ss.getActiveSheet();
var sheetName = "Unit Standards"
var range = e.range;
var editedColumn = range.getColumn();
var editedRow = range.getRow();
var column = 2;
var date = range.getValue();
// Object.prototype.toString.call(date) === '[object Date]' --> checks if value is date
// editedColumn == column && editedRow > 4 --> checks if edited cell is from 'Date Left'
// sheet.getName() == sheetName --> checks if edited sheet is 'Unit Standards'
if(Object.prototype.toString.call(date) === '[object Date]' && editedColumn == column && editedRow > 4 && sheet.getName() == sheetName) {
var numCols = sheet.getLastColumn();
var row = sheet.getRange(editedRow, 1, 1, numCols).getValues();
var destinationSheet = ss.getSheetByName("Unit Standards - Employees Left");
// Get first empty row:
var emptyRow = destinationSheet.getLastRow() + 1;
// Copy values from 'Unit Standards'
destinationSheet.getRange(emptyRow, 1, 1, numCols).setValues(row);
sheet.deleteRow(editedRow);
sheet.hideColumns(column);
}
//Dependent Dropdowns for Event/Incidents Sheet
{
var range = e.range;
var editedRow = range.getRow();
var spreadsheet = SpreadsheetApp.getActive();
var dropdownSheet = spreadsheet.getSheetByName("Dropdown Lists");
var eventsSheet = spreadsheet.getSheetByName("Events/Incidents");
var baseSelected = eventsSheet.getRange('C' + editedRow).getValue();
var column;
switch (baseSelected) {
case 'EBOP': column = 'A'; break;
case 'Tauranga': column = 'B'; break;
case 'Palmerston North': column = 'C'; break;
case 'Kapiti': column = 'D';
}
var startCell = dropdownSheet.getRange( column +'4');
var endCellNotation = startCell.getNextDataCell(SpreadsheetApp.Direction.DOWN).getA1Notation();
var ruleRange = dropdownSheet.getRange(startCell.getA1Notation() + ':' + endCellNotation);
var dropdown1 = eventsSheet.getRange('D' + editedRow);
var dropdown2 = eventsSheet.getRange('E' + editedRow);
var rule1 = SpreadsheetApp.newDataValidation().requireValueInRange(ruleRange).build();
var rule2 = SpreadsheetApp.newDataValidation().requireValueInRange(ruleRange).build();
dropdown1.setDataValidation(rule1);
dropdown2.setDataValidation(rule2);
}
}
if (ss.getSheetName() == tabValidation) {
var lock = LockService.getScriptLock();
if (lock.tryLock(0)) {
autoid_(ss);
lock.releaseLock();
}
}
}
}
// Auto ID for Event/Incident Sheet
function autoid_(sheet) {
var data = sheet.getDataRange().getValues();
if (data.length < 2) return;
var indexId = data[1].indexOf('ID');
var indexDate = data[1].indexOf('Event/Incident Date');
if (indexId < 0 || indexDate < 0) return;
var id = data.reduce(
function(p, row) {
var year =
row[indexDate] && row[indexDate].getTime
? row[indexDate].getFullYear() % 100
: '-';
if (!Object.prototype.hasOwnProperty.call(p.indexByGroup, year)) {
p.indexByGroup[year] = [];
}
var match = ('' + row[indexId]).match(/(\d+)-(\d+)/);
var idVal = row[indexId];
if (match && match.length > 1) {
idVal = match[2];
p.indexByGroup[year].push(+idVal);
}
p.ids.push(idVal);
p.years.push(year);
return p;
},
{ indexByGroup: {}, ids: [], years: [] }
);
// Logger.log(JSON.stringify(id, null, ' '));
var newId = data
.map(function(row, i) {
if (row[indexId] !== '') return [row[indexId]];
if (isNumeric(id.years[i])) {
var lastId = Math.max.apply(
null,
id.indexByGroup[id.years[i]].filter(function(e) {
return isNumeric(e);
})
);
lastId = lastId === -Infinity ? 1 : lastId + 1;
id.indexByGroup[id.years[i]].push(lastId);
return [
Utilities.formatString(
'%s-%s',
id.years[i],
('000000000' + lastId).slice(-3)
)
];
}
return [''];
})
.slice(1);
sheet.getRange(2, indexId + 1, newId.length).setValues(newId);
}
/**
*
* @param {any} n
* @return {boolean}
*/
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
Первая функция:
// Вырезать сотрудников слева из листа стандартов подразделения и вставить в лист стандартов подразделения - сотрудников слева
Второй:
// Зависимые выпадающие списки событий / инцидентов
Третий:
// Автоматический идентификатор для листа событий / происшествий
Я просмотрел ответы на предыдущие вопросы по этому поводу и до сих пор не могу понять, как поставить скобки в нужное место и заставить их работать. Я был бы очень признателен за помощь.
1 ответ
Не очень понятно, что вы пытаетесь сделать. Для начала, ваша вторая функция даже не определена. Итак, я попытался ответить тем, что могу понять о вашем коде, но вам придется ознакомиться с условиями.
Я бы порекомендовал вам сделать каждую из ваших функций автономной. В вашемonEdit()
, вы можете вызывать их всякий раз, когда выполняется определенное условие. Например:
function onEdit(e) {
var sheetName = e.range.getSheet().getName();
if (sheetName == "Sheet1") {
// do something
} else if (sheetName == "Sheet2") {
// do something else
}
}
С такой структурой вы можете легко вызывать нужные вам функции всякий раз, когда выполняются ваши конкретные условия. Вот окончательный код, но, опять же, просмотрите условия, поскольку я ввел здесь фиктивные значения.
function onEdit(e) {
var value = e.range.getValue();
var sheetName = e.range.getSheet().getName();
if (
Object.prototype.toString.call(value) === "[object Date]" && // Check if value is a date
sheetName == "Unit Standards" && // checks if edited sheet is 'Unit Standards'
e.range.columnStart == 2 && // checks if edited cell is from 'Date Left'
e.range.rowStart > 4
) {
moveEmployees_(e.range);
} else if (sheetName == "Sheet2" && e.range.rowStart == 2 && e.range.columnStart == 2) {
dependentDropdowns_(e.range);
} else if (sheetName == "Sheet3" && e.range.rowStart == 3 && e.range.columnStart == 3) {
autoid_(e.range.getSheet());
}
}
/**
* Cut Employees Left from Unit Standards sheet and paste in Unit Standards - Employees Left sheet
* @param {Range} range
*/
function moveEmployees_(range) {
var sheet = range.getSheet();
var editedRow = range.getRow();
var column = 2;
var numCols = sheet.getLastColumn();
var row = sheet.getRange(editedRow, 1, 1, numCols).getValues();
var destinationSheet = ss.getSheetByName("Unit Standards - Employees Left");
// Get first empty row:
var emptyRow = destinationSheet.getLastRow() + 1;
// Copy values from 'Unit Standards'
destinationSheet.getRange(emptyRow, 1, 1, numCols).setValues(row);
sheet.deleteRow(editedRow);
sheet.hideColumns(column);
}
/**
* Dependent Dropdowns for Event/Incidents Sheet
* @param {Range} range
*/
function dependentDropdowns_(range) {
var editedRow = range.getRow();
var spreadsheet = SpreadsheetApp.getActive();
var dropdownSheet = spreadsheet.getSheetByName("Dropdown Lists");
var eventsSheet = spreadsheet.getSheetByName("Events/Incidents");
var baseSelected = eventsSheet.getRange('C' + editedRow).getValue();
var column;
switch (baseSelected) {
case 'EBOP': column = 'A'; break;
case 'Tauranga': column = 'B'; break;
case 'Palmerston North': column = 'C'; break;
case 'Kapiti': column = 'D';
}
var startCell = dropdownSheet.getRange(column + '4');
var endCellNotation = startCell.getNextDataCell(SpreadsheetApp.Direction.DOWN).getA1Notation();
var ruleRange = dropdownSheet.getRange(startCell.getA1Notation() + ':' + endCellNotation);
var dropdown1 = eventsSheet.getRange('D' + editedRow);
var dropdown2 = eventsSheet.getRange('E' + editedRow);
var rule1 = SpreadsheetApp.newDataValidation().requireValueInRange(ruleRange).build();
var rule2 = SpreadsheetApp.newDataValidation().requireValueInRange(ruleRange).build();
dropdown1.setDataValidation(rule1);
dropdown2.setDataValidation(rule2);
}
/**
* Auto ID for Event/Incident Sheet
* @param {Sheet} sheet
*/
function autoid_(sheet) {
var data = sheet.getDataRange().getValues();
if (data.length < 2) return;
var indexId = data[1].indexOf('ID');
var indexDate = data[1].indexOf('Event/Incident Date');
if (indexId < 0 || indexDate < 0) return;
var id = data.reduce(
function (p, row) {
var year = row[indexDate] && row[indexDate].getTime ? row[indexDate].getFullYear() % 100 : '-';
if (!Object.prototype.hasOwnProperty.call(p.indexByGroup, year)) {
p.indexByGroup[year] = [];
}
var match = ('' + row[indexId]).match(/(\d+)-(\d+)/);
var idVal = row[indexId];
if (match && match.length > 1) {
idVal = match[2];
p.indexByGroup[year].push(+idVal);
}
p.ids.push(idVal);
p.years.push(year);
return p;
}, { indexByGroup: {}, ids: [], years: [] }
);
var newId = data.map(function (row, i) {
if (row[indexId] !== '') return [row[indexId]];
if (isNumeric(id.years[i])) {
var lastId = Math.max.apply(null, id.indexByGroup[id.years[i]].filter(function (e) {
return isNumeric(e);
}));
lastId = lastId === -Infinity ? 1 : lastId + 1;
id.indexByGroup[id.years[i]].push(lastId);
return [Utilities.formatString('%s-%s', id.years[i], ('000000000' + lastId).slice(-3))];
}
return [''];
}).slice(1);
sheet.getRange(2, indexId + 1, newId.length).setValues(newId);
}
/**
* Check if an object is numeric.
* @param {*} n
* @return {boolean}
*/
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
Наконец, чтобы решить вашу озабоченность по поводу скобок, здесь нет необходимости во вложенных функциях. Если бы вы действительно этого хотели, вы бы просто поместили все вложенные функции непосредственно перед последней скобкой "родительской" функции.
function parent() {
var result = isNumeric("abc");
Logger.log(result); // false
return result;
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
}