首页 > 解决方案 > 尝试使用独立脚本时出现“找不到脚本函数”

问题描述

我是 Apps 脚本的新手。我的背景是大型机,所以类 Java 语言的术语和概念对我来说有点陌生。这是我的情况。我有几个非常相似的谷歌电子表格,但彼此略有不同。我想使用相同的独立 Apps 脚本来重置这些 Google 电子表格中的字段。我编写的脚本在容器绑定时运行良好,但是当我将它放入 MyDrive 中的 Google Apps 脚本(项目?)文件并尝试使用分配给函数名称 resetRounds 的按钮从那里执行它时,我得到“脚本未找到”错误。我不想在每个电子表格中都有相同脚本的副本。我必须做任何特别的事情来将项目文件连接到电子表格吗?什么可能导致“未找到” 健康)状况?任何帮助或建议将不胜感激。

这是存在于 Google Apps 脚本项目文件中的脚本。

function resetRounds() {


  var ss = SpreadsheetApp.getActive();
  var ssName = ss.getName();
  var shRounds = ss.getSheetByName("Rounds");
  var shLog = ss.getSheetByName('Print-Log').getName();
  var shDDList = ss.getSheetByName("DD-Lists"); 

  // Restore SVE team name from DD-Lists sheet 
  var source = shDDList.getRange("A3"); /* Team name should be in cell A3 */
  var destn  = shRounds.getRange("D3"); /* copy it to Team Name cell */
  source.copyTo(destn, {contentsOnly:true}); /* copy contents only, not the formatting */
 
  // Reset visitor team name and Captains to trigger cell conditional formatting */ 
  destn = shRounds.getRange("L3").activate().setValue('None');
  destn = shRounds.getRange("N4").activate().setValue('None');
  
  
  // Set the date to 1/1/2001 to trigger conditional formatting
  // Week number will show as blank (0) when special date 1/1/2001 is used
  source = shDDList.getRange("A51"); /* Special date should be in cell A51 */
  destn  = shRounds.getRange("Q3");  /* Only the first cell needs to be selected */ 
  source.copyTo(destn, {contentsOnly:true}); /* copy contents only, not the formatting */

  // Restore times from DD-Lists sheet 
  source = shDDList.getRange("A5"); /* Round 1 time should be in cell A5 */
  destn  = shRounds.getRange("C6"); /* copy it to Round 1 cell */
  source.copyTo(destn, {contentsOnly:true}); /* copy contents only, not the formatting */

  source = shDDList.getRange("A6"); /* Round 2 time should be in cell A6 */
  destn  = shRounds.getRange("L6"); /* copy it to Round 2 cell */
  source.copyTo(destn, {contentsOnly:true}); /* copy contents only, not the formatting */

 // Reset court numbers 
  ss.getRange("B8:B13").activate().setValue('Y');  /* Court number 1 */
  ss.getRange("B15:B20").activate().setValue('2'); /* Court number 2 */
  ss.getRange("B22:B27").activate().setValue('3'); /* Court number 3 */
  ss.getRange("B29:B34").activate().setValue('4'); /* Court number 4 */
  ss.getRange("B36:B41").activate().setValue('5'); /* Court number 5 */
  ss.getRange("B43:B48").activate().setValue('6'); /* Court number 6 */
  // Clear round 1 and round 2 player names 
  ss.getRange("C8:C48").activate().clear({contentsOnly: true, skipFilteredRows: true}); 
  ss.getRange("E8:E48").activate().clear({contentsOnly: true, skipFilteredRows: true}); 
  ss.getRange("L8:L48").activate().clear({contentsOnly: true, skipFilteredRows: true}); 
  ss.getRange("N8:N48").activate().clear({contentsOnly: true, skipFilteredRows: true}); 
  // Clear round 1 and round 2 scores
  ss.getRange("G8:H48").activate().clear({contentsOnly: true, skipFilteredRows: true}); 
  ss.getRange("P8:Q48").activate().clear({contentsOnly: true, skipFilteredRows: true}); 
  // Clear scorekeeper names
  ss.getRange("C56:E59").activate().clear({contentsOnly: true, skipFilteredRows: true}); 
  ss.getRange("C61:E62").activate().clear({contentsOnly: true, skipFilteredRows: true}); 
  /* Reset cursor to Visitor */
  ss.getRange('L3:N3').activate();


  }

标签: google-apps-scriptgoogle-sheets

解决方案


建议的解决方法

您希望使用按钮从中心位置在工作表子集上运行脚本。不幸的是,按钮方面会使事情变得更复杂(最后有一些建议),但如果按钮不是必需的并且您愿意从脚本编辑器(或基于时间的触发器)运行它,那么下面应该管用:

function resetRounds() {
  var IDs = ["[SS ID 1]", "[SS ID 2]", "[SS ID 3]"]; // Add the spreadsheet IDs here

  // This `forEach` loop will go through each id
  IDs.forEach((id) => {

    var ss = SpreadsheetApp.openById(id); // Instead of calling `getActive` you are opening by Ids
    
    // This part of the script is unchanged vvvv

    var ssName = ss.getName();
    var shRounds = ss.getSheetByName("Rounds");
    var shLog = ss.getSheetByName("Print-Log").getName();
    var shDDList = ss.getSheetByName("DD-Lists");

    // Restore SVE team name from DD-Lists sheet
    var source = shDDList.getRange("A3"); /* Team name should be in cell A3 */
    var destn = shRounds.getRange("D3"); /* copy it to Team Name cell */
    source.copyTo(destn, {
      contentsOnly: true,
    }); /* copy contents only, not the formatting */

    // Reset visitor team name and Captains to trigger cell conditional formatting */
    destn = shRounds.getRange("L3").activate().setValue("None");
    destn = shRounds.getRange("N4").activate().setValue("None");

    // Set the date to 1/1/2001 to trigger conditional formatting
    // Week number will show as blank (0) when special date 1/1/2001 is used
    source = shDDList.getRange("A51"); /* Special date should be in cell A51 */
    destn = shRounds.getRange(
      "Q3"
    ); /* Only the first cell needs to be selected */
    source.copyTo(destn, {
      contentsOnly: true,
    }); /* copy contents only, not the formatting */

    // Restore times from DD-Lists sheet
    source = shDDList.getRange("A5"); /* Round 1 time should be in cell A5 */
    destn = shRounds.getRange("C6"); /* copy it to Round 1 cell */
    source.copyTo(destn, {
      contentsOnly: true,
    }); /* copy contents only, not the formatting */

    source = shDDList.getRange("A6"); /* Round 2 time should be in cell A6 */
    destn = shRounds.getRange("L6"); /* copy it to Round 2 cell */
    source.copyTo(destn, {
      contentsOnly: true,
    }); /* copy contents only, not the formatting */

    // Reset court numbers
    ss.getRange("B8:B13").activate().setValue("Y"); /* Court number 1 */
    ss.getRange("B15:B20").activate().setValue("2"); /* Court number 2 */
    ss.getRange("B22:B27").activate().setValue("3"); /* Court number 3 */
    ss.getRange("B29:B34").activate().setValue("4"); /* Court number 4 */
    ss.getRange("B36:B41").activate().setValue("5"); /* Court number 5 */
    ss.getRange("B43:B48").activate().setValue("6"); /* Court number 6 */
    // Clear round 1 and round 2 player names
    ss.getRange("C8:C48")
      .activate()
      .clear({ contentsOnly: true, skipFilteredRows: true });
    ss.getRange("E8:E48")
      .activate()
      .clear({ contentsOnly: true, skipFilteredRows: true });
    ss.getRange("L8:L48")
      .activate()
      .clear({ contentsOnly: true, skipFilteredRows: true });
    ss.getRange("N8:N48")
      .activate()
      .clear({ contentsOnly: true, skipFilteredRows: true });
    // Clear round 1 and round 2 scores
    ss.getRange("G8:H48")
      .activate()
      .clear({ contentsOnly: true, skipFilteredRows: true });
    ss.getRange("P8:Q48")
      .activate()
      .clear({ contentsOnly: true, skipFilteredRows: true });
    // Clear scorekeeper names
    ss.getRange("C56:E59")
      .activate()
      .clear({ contentsOnly: true, skipFilteredRows: true });
    ss.getRange("C61:E62")
      .activate()
      .clear({ contentsOnly: true, skipFilteredRows: true });
    /* Reset cursor to Visitor */
    ss.getRange("L3:N3").activate();

    // This part of the script is unchanged ^^^^

  });
}

这里发生的所有事情是,它没有调用getActive打开电子表格,而是调用openById. 它从脚本顶部初始化的 ID 数组或列表中获取 ID。然后forEach在该数组上调用该方法,该方法将对该列表中的每个项目重复特定操作。我们使用每个项目来调用openById. 这将为每个电子表格运行脚本,只要您具有对它们的编辑权限。

将其分配给按钮

您可以拥有一个带有绑定脚本的工作表,除了此工作表的全部用途是有一个按钮。它本身没有任何数据,它只是供用户启动脚本而无需进入脚本编辑器并手动运行它。

在触发器上运行它

例如,您还可以查看每天自动运行此“主”脚本的触发器(链接如下)。如果失败,它还会给您发送电子邮件。

参考


推荐阅读