【问题标题】:Google apps script spreadsheet:error谷歌应用脚​​本电子表格:错误
【发布时间】:2014-05-08 21:41:52
【问题描述】:

我在一个公立学区工作,并编写了一个脚本,用于从 Google 表单响应表中获取数据,并根据信息所涉及的学校将其过滤到单独的表中。使用位于 https://developers.google.com/apps-script/guides/sheets 的教程。修改后的脚本长达 1300 行(包括一些解释),并且一直运行到最近。

脚本现在返回许多错误。最常见的错误是:

“服务超时:电子表格(第 40 行,文件“Transfer/SortID/Copy/Sort”)”

“服务错误:电子表格(第 40 行,文件“Transfer/SortID/Copy/Sort”)”

错误中标记的行是

"headersRange.setValues([columnNames]);"

我已经尝试了所有我能想到的方法,包括创建一个新的目标电子表格。

我已经包含了下面代码的开始部分。同样,这个脚本直到最近都运行良好。 (上次成功运行是5/6)

提前感谢您的帮助!

// This is where the data used in this example will be retrieved from:
// https://docs.google.com/a/psdschools.org/spreadsheet/ccc?key=0AswYUpTPhetrdFYxUEJZSkxHeVdfSk5pajh3UjYxaUE&usp=drive_web#gid=0
function TransferAndSort() {{
var DATA_SPREADSHEET_ID = "0AswYUpTPhetrdFYxUEJZSkxHeVdfSk5pajh3UjYxaUE"

//update data

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];

  var dataSs = SpreadsheetApp.openById(DATA_SPREADSHEET_ID);
  var dataSheet = dataSs.getSheets()[0];

  // Fetch all the data
  var data = getRowsData(dataSheet);

  // This is the data we want to display
  var columnNames = ["Last Name","First Name", "ID Number", "School", "Date Written", "Purpose", "Requested Route #", "Requested Stop Location", "Type of Student", "Contact Made"];


// Index data by School name
  var dataBySchool = {};
  var schools = [];
  for (var i = 0; i < data.length; ++i) {
    var rowData = data[i];
    if (!dataBySchool[rowData.school]) {
      dataBySchool[rowData.school] = [];
      schools.push(rowData.school);
    }
    dataBySchool[rowData.school].push(rowData);
  }

  schools.sort();
  var headerBackgroundColor = dataSheet.getRange(1, 1).getBackgroundColor();
  for (var i = 0; i < schools.length; ++i) {
    var sheet = ss.getSheetByName(schools[i]) ||
      ss.insertSheet(schools[i], ss.getSheets().length);
    sheet.clear();
    var headersRange = sheet.getRange(1, 1, 1, columnNames.length);
    headersRange.setValues([columnNames]);
    headersRange.setBackgroundColor(headerBackgroundColor);
    setRowsData(sheet, dataBySchool[schools[i]]);
  }
}

// setRowsData fills in one row of data per object defined in the objects Array.
// For every Column, it checks if data objects define a value for it.
// Arguments:
//   - sheet: the Sheet Object where the data will be written
//   - objects: an Array of Objects, each of which contains data for a row
//   - optHeadersRange: a Range of cells where the column headers are defined. This
//     defaults to the entire first row in sheet.
//   - optFirstDataRowIndex: index of the first row where data should be written. This
//     defaults to the row immediately below the headers.
function setRowsData(sheet, objects, optHeadersRange, optFirstDataRowIndex) {
  var headersRange = optHeadersRange || sheet.getRange(1, 1, 1, sheet.getMaxColumns());
  var firstDataRowIndex = optFirstDataRowIndex || headersRange.getRowIndex() + 1;
  var headers = normalizeHeaders(headersRange.getValues()[0]);

  var data = [];
  for (var i = 0; i < objects.length; ++i) {
    var values = []
    for (j = 0; j < headers.length; ++j) {
      var header = headers[j];
      // If the header is non-empty and the object value is 0...
      if ((header.length > 0) && (objects[i][header] == 0)) {
        values.push(0);
      }
      // If the header is non-empty or the object value is empty...
      else if ((!(header.length > 0)) || (objects[i][header]=='')) {
        values.push('');
      }
      else {
        values.push(objects[i][header]);
      }
    }
    data.push(values);
  }

  var destinationRange = sheet.getRange(firstDataRowIndex, headersRange.getColumnIndex(),
                                        objects.length, headers.length);
  destinationRange.setValues(data);
}

// getRowsData iterates row by row in the input range and returns an array of objects.
// Each object contains all the data for a given row, indexed by its normalized column name.
// Arguments:
//   - sheet: the sheet object that contains the data to be processed
//   - range: the exact range of cells where the data is stored
//       This argument is optional and it defaults to all the cells except those in the first row
//       or all the cells below columnHeadersRowIndex (if defined).
//   - columnHeadersRowIndex: specifies the row number where the column names are stored.
//       This argument is optional and it defaults to the row immediately above range;
// Returns an Array of objects.
function getRowsData(sheet, range, columnHeadersRowIndex) {
  var headersIndex = columnHeadersRowIndex || range ? range.getRowIndex() - 1 : 1;
  var dataRange = range ||
    sheet.getRange(headersIndex + 1, 1, sheet.getMaxRows() - headersIndex, sheet.getMaxColumns());
  var numColumns = dataRange.getEndColumn() - dataRange.getColumn() + 1;
  var headersRange = sheet.getRange(headersIndex, dataRange.getColumn(), 1, numColumns);
  var headers = headersRange.getValues()[0];
  return getObjects(dataRange.getValues(), normalizeHeaders(headers));
}

// For every row of data in data, generates an object that contains the data. Names of
// object fields are defined in keys.
// Arguments:
//   - data: JavaScript 2d array
//   - keys: Array of Strings that define the property names for the objects to create
function getObjects(data, keys) {
  var objects = [];
  for (var i = 0; i < data.length; ++i) {
    var object = {};
    var hasData = false;
    for (var j = 0; j < data[i].length; ++j) {
      var cellData = data[i][j];
      if (isCellEmpty(cellData)) {
        continue;
      }
      object[keys[j]] = cellData;
      hasData = true;
    }
    if (hasData) {
      objects.push(object);
    }
  }
  return objects;
}

// Returns an Array of normalized Strings.
// Empty Strings are returned for all Strings that could not be successfully normalized.
// Arguments:
//   - headers: Array of Strings to normalize
function normalizeHeaders(headers) {
  var keys = [];
  for (var i = 0; i < headers.length; ++i) {
    keys.push(normalizeHeader(headers[i]));
  }
  return keys;
}

// Normalizes a string, by removing all alphanumeric characters and using mixed case
// to separate words. The output will always start with a lower case letter.
// This function is designed to produce JavaScript object property names.
// Arguments:
//   - header: string to normalize
// Examples:
//   "First Name" -> "firstName"
//   "Market Cap (millions) -> "marketCapMillions
//   "1 number at the beginning is ignored" -> "numberAtTheBeginningIsIgnored"
function normalizeHeader(header) {
  var key = "";
  var upperCase = false;
  for (var i = 0; i < header.length; ++i) {
    var letter = header[i];
    if (letter == " " && key.length > 0) {
      upperCase = true;
      continue;
    }
    if (!isAlnum(letter)) {
      continue;
    }
    if (key.length == 0 && isDigit(letter)) {
      continue; // first character must be a letter
    }
    if (upperCase) {
      upperCase = false;
      key += letter.toUpperCase();
    } else {
      key += letter.toLowerCase();
    }
  }
  return key;
}

// Returns true if the cell where cellData was read from is empty.
// Arguments:
//   - cellData: string
function isCellEmpty(cellData) {
  return typeof(cellData) == "string" && cellData == "";
}

// Returns true if the character char is alphabetical, false otherwise.
function isAlnum(char) {
  return char >= 'A' && char <= 'Z' ||
    char >= 'a' && char <= 'z' ||
    isDigit(char);
}

// Returns true if the character char is a digit, false otherwise.
function isDigit(char) {
  return char >= '0' && char <= '9';
}

【问题讨论】:

    标签: google-apps-script


    【解决方案1】:

    我没有给你很好的答案,但这可能会有所帮助,或者至少提供一些见解。我正在开发的附加组件遇到类似的问题。该问题似乎与调用 sheet.clear() 有关。在 sheet.clear() 之后,某些操作在第一次被调用时需要很长时间。在我们的例子中,我们看到 sheet.getMaxColumns() 在调用 sheet.clear() 后需要超过 20 秒,而如果我们删除 sheet.clear() 调用,则只需几毫秒。如果我连续调用两次,第一次调用需要很长时间,但第二次调用又很快。我已经确认即使切换到 sheet.clearContents() 也是如此。

    我希望这是谷歌最近引入的某种错误,它会很快得到解决,因为我们目前还没有真正的解决方法来调用 sheet.clear()。

    希望这会有所帮助,祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多