【问题标题】:"The starting column of the range is too small" error“范围的起始列太小”错误
【发布时间】:2020-07-03 17:22:46
【问题描述】:

这是我正在运行的脚本的一个示例:

    function onFormSubmit(e) {
var date = e.values[0];
var user = e.values[1];
var busUnit = e.values[2];
var body = "Request for Add-On form submission" +"\n\n"+"Date:\t\t\t\t"+date +"\n"+ "Employee Email:\t\t"+user +"\n"+"Business Unit:\t\t"+busUnit +"\n\n" +"Form Responses:\t\t" + "https://docs.google.com/spreadsheets/d/ID/";

    if (busUnit=="Acme") 
  {
    MailApp.sendEmail("admin@acme.com", "Request for Add-On Submission",body);
    }
    
    if (busUnit=="fakename")
   {
     MailApp.sendEmail("admin@fakename.com", "Request for Add-On Submission",body);
     }
   
   if (busUnit=="fakename2")
   {
     MailApp.sendEmail("admin@fakename.com", "Request for Add-On Submission",body);
     }

}

function getColIndexByName(colName) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var numColumns = sheet.getLastColumn();
  var row = sheet.getRange(1, 1, 1, numColumns).getValues();
  for (i in row[0]) {
    var name = row[0][i];
    if (name == colName) {
      return parseInt(i) + 1;
    }
  }
  return -1;
}

function emailStatusUpdates() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var row = sheet.getActiveRange().getRowIndex();
  var Email = "alladmins@fakename.com";
  var subject = "Add-On Request Update";
  var body = "The Fake Team has updated the status of the latest request.\n\nStatus: " + sheet.getRange(row, getColIndexByName("approval status")).getValue();
  body += "\n\nRequest: " + sheet.getRange(row, getColIndexByName("What are you requesting to have approved?")).getValue();
  body += "\n\nDescription: " + sheet.getRange(row, getColIndexByName("Provide a brief description")).getValue();
 //body += "\n\nNotes: " + sheet.getRange(row, getColIndexByName("Notes")).getValue();
 //body += "\n\nURL: "+ "https://docs.google.com/spreadsheets/d/ID/";

  MailApp.sendEmail(Email, subject, body, {name:"The Fake Team"});
}

function onOpen() {
  var subMenus = [{name:"Send Approval Status", functionName: "emailStatusUpdates"}];
  SpreadsheetApp.getActiveSpreadsheet().addMenu("Send Status Update", subMenus);
}

我想启用最后 2 个body += 行。当我这样做时,我收到此错误:

异常:范围的起始列太小。在 emailStatusUpdates(Code:45:99)

我尝试将此行更改为var row = sheet.getRange(1, 1, 1, 4, numColumns).getValues();,但随后出现此错误:

异常:参数(数字、数字、数字、数字)与 SpreadsheetApp.Sheet.getRange 的方法签名不匹配。 在 getColIndexByName(代码:30:19) 在 emailStatusUpdates(代码:45:113)

【问题讨论】:

  • 错误出现在哪一行?

标签: google-apps-script google-sheets


【解决方案1】:

错误说明

异常:参数(数字、数字、数字、数字)与方法不匹配

getRange 方法的方法签名只有四个参数,顺序如下:

  1. 从行开始
  2. 起始列
  3. 要跨越的行数(可选,默认为 1)
  4. 要跨越的列数(可选,默认为 1)

fifths 参数无效,错误信息明确指出。该消息令人困惑的是它省略了无效参数,但这是在使用的错误处理库上。

异常:范围的起始列太小

一方面,您的getColIndexByName 函数(设计为与indexOf() 方法类似)有两种可能的返回状态:正向number(如果我们在JS 中有类型,则为“整数”)或-1未能找到作为参数传递的colName

另一方面,getRange 方法只接受正数numbers,因此如果传递的数字是<= 0,则会抛出错误。考虑以下重现“范围的起始列太小”错误的示例:

function testOutOfRange() {
  const ss = SpreadsheetApp.openById('yourIdHere');
  const sh = ss.getSheets()[0];
  sh.getRange(1, -1);
}

注意:在 V8 运行时,函数(至少对于我的测试而言)只是无限期挂起。在 Rhino 运行时,会抛出“期望的”错误。

由于您在没有任何保护的情况下使用getColIndexByName,因此如果找不到Notes 列(我认为是这种情况,因为该调用适用于其他列名),则以下行会爆炸:

body += "\n\nNotes: " + sheet.getRange(row, getColIndexByName("Notes")).getValue();

优化

你的getColIndexByName 可以减少到(注意它会在不匹配时返回0 并且仍然会破坏发送):

function getColIndexByName(colName) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var numColumns = sheet.getLastColumn();
  var row = sheet.getRange(1, 1, 1, numColumns).getValues()[0];
  return row.indexOf(colName) + 1;
}

应用于问题

如果脚本适用于其他列名的假设成立,则 getColIndexByName 无法找到 "Name" 列,并且由于缺少保护,emailStatusUpdates 脚本由于参数约束违反而失败。

如果不是这样,答案将会更新

【讨论】:

  • 别提了,很高兴问题得到了解决——不过要小心,因为这只能解决症状——我喜欢 Cooper 的方法,因为你真的不应该依赖如何命名列来获得所需结果。按位置引用通常更可靠。
【解决方案2】:

试试这个:

function getColIndexByName(colName) {
  var sh=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var hA=sh.getRange(1,1,1,sh.getLastColumn()).getValues()[0];
  var idx={};
  hA.forEach(function(h,i){idx[h]=i+1;});
  if(idx.hasOwnProperty(colName)) {
    return idx[colName];
  }else{
    return -1;
  }
}

【讨论】:

  • 嗨@Cooper 谢谢,但我现在在添加您的代码后收到此错误:ReferenceError: sh is not defined at getColIndexByName(Code:28:31) var hA = sheet.getRange(1,1,1,sh.getLastColumn()).getValues()[0]; at emailStatusUpdates(Code :58:113) var body = "The Team has updated the status of the latest request.\n\nStatus: " + sheet.getRange(row, getColIndexByName("approval status")).getValue();
  • 好的,很抱歉。我有在代码中使用短变量的习惯。
  • 不用担心。只是我不知道hA或idx是什么。
  • 如果您在脚本中使用这三行代码:var hA=sh.getRange(1,1,1,sh.getLastColumn()).getValues()[0]; var idx={}; hA.forEach(function(h,i){idx[h]=i;}); 然后您可以在整个代码中使用 idx['columnName'] ,而无需进行外部函数调用。我一直为希望能够添加新列并在不破坏代码的情况下移动它们的客户这样做。
  • 哦,我刚刚意识到您需要列号而不是数组索引,因为您使用了 getValue()。对此感到抱歉。
猜你喜欢
  • 2022-11-11
  • 2022-12-13
  • 1970-01-01
  • 2023-01-14
  • 2023-01-13
  • 2021-11-09
  • 1970-01-01
  • 2021-10-11
  • 2016-03-08
相关资源
最近更新 更多