【问题标题】:Bracketing multiple onEdit functions包围多个 onEdit 函数
【发布时间】:2019-11-21 23:06:43
【问题描述】:

我的 Google 电子表格中有 3 个 onEdit 应用脚本函数,它们可以单独工作,但我无法确定将括号嵌套在哪里。

Database

它们都在 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);
}

第一个函数是:

// 从单位标准表中剪切员工左侧并粘贴到单位标准 - 员工左侧表中

第二个是:

//事件/事件表的相关下拉列表

第三个是:

// 事件/事件表的自动 ID

我已经查看了有关此问题的先前问题的答案,但仍然无法弄清楚如何将括号放在正确的位置并使其正常工作。非常感谢您的帮助。

【问题讨论】:

  • 这可能应该在Code Review Stack Exchange 而不是 SO 上提出。
  • 那么你的问题需要改进和努力。例如,我只看到一个“onEdit”函数,不知道你试图做什么
  • 我明白了——抱歉——这是我对代码的工作原理缺乏了解。
  • @tehhowch - 我的问题更好还是我需要添加更多?

标签: google-apps-script google-sheets triggers


【解决方案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);
  }
}

【讨论】:

  • 我完全迷路了。我现在无法使用任何功能。我复制了您所做的,但无法识别虚拟值。所以我然后尝试分离每个功能,现在没有工作 - 没有错误 - 只是不执行。
  • @McChief 尝试单独运行这些函数,看看它们是否正常工作(您需要将值传递给它们)。虚拟值在onEdit() 的条件语句中。例如,我写了if (sheetName == "Sheet2" &amp;&amp; e.range.rowStart == 2 &amp;&amp; e.range.columnStart == 2),但这可能不是您想要运行dependentDropdowns_() 的条件。
  • 我让它们单独工作,但无法让 autoid 功能正常工作。 autoid 在我的嵌套代码中有效,但在我将其分开时无效。依赖下拉函数单独工作,但不在我的嵌套代码中。我已经分享了我的数据库的链接。
  • @McChief autoid_() 在您独立运行时是否正常工作?从您的评论中不清楚它是否根本不起作用,或者只是在被 onEdit() 调用时不起作用。
  • 感谢您的帮助和解释
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-10
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
相关资源
最近更新 更多