首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否有更好的方法,使脚本适用于每一张纸?

是否有更好的方法,使脚本适用于每一张纸?
EN

Stack Overflow用户
提问于 2021-12-08 17:56:34
回答 2查看 115关注 0票数 0

我编写了一些脚本来帮助我清理/重置每周重复使用的工作表。我们的想法是,我们有大约50人使用这个,由于恶意和无知的结合,他们经常找到绕过我们的权限的方法,并编辑我们不希望他们做的事情。最近,这个工作表变得如此之大,以至于我写得不好的脚本会在结束之前超时。(我们目前的价格是250张。)我已经能够重写其中的大部分,并大大降低了运行时。一个步骤继续放慢我的速度,不过:删除和重新应用分带到一个特定的范围(A5:H27)在每一页。

有什么方法可以使这段代码更高效,并将运行时从~12分钟减少到这个步骤?

代码语言:javascript
运行
复制
function fixBanding(){
  var spreadsheet = SpreadsheetApp.getActive();
  var allSheets = spreadsheet.getSheets();
  
  allSheets.forEach(function(sheet){
    if(sheet.getSheetName() !== "HelperSheet"){
      sheet.getRange('A5:H27').activate();
      sheet.getRange("A5:H27").getBandings().forEach(banding => banding.remove());
      sheet.getRange("A5:H27").applyRowBanding()
        .setHeaderRowColor('white')
        .setFirstRowColor('#cbcbcb') //med grey
        .setSecondRowColor('white');
    }
  })
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-12-09 00:06:32

我相信你的目标如下。

  • 你的剧本写得很好。并且,您希望降低脚本的进程成本。

在这种情况下,如何使用Sheets?当使用Sheets时,可以稍微降低一些处理成本。当在脚本中使用Sheets时,它如下所示。

修改脚本:

在使用此脚本之前,请在高级谷歌服务器上启用Sheets

代码语言:javascript
运行
复制
function myFunction() {
  // Retrieve sheet IDs and andedRange IDs.
  const ss = SpreadsheetApp.getActive();
  const spreadsheetId = ss.getId();
  const { sheetIds, bandedRangeIds } = Sheets.Spreadsheets.get(spreadsheetId, { fields: "sheets(properties(sheetId,title),bandedRanges(bandedRangeId))" }).sheets.reduce((o, { properties: { sheetId, title }, bandedRanges }) => {
    if (title != "HelperSheet") {
      o.sheetIds.push(sheetId);
      o.bandedRangeIds = [...o.bandedRangeIds, ...bandedRanges.map(({ bandedRangeId }) => bandedRangeId)];
    }
    return o;
  }, { sheetIds: [], bandedRangeIds: [] });
  
  // Create the request body for Sheets API.
  const firstBandColor = { red: 0.79, green: 0.79, blue: 0.79 };
  const secondBandColor = { red: 1, green: 1, blue: 1 };
  const headerColor = { red: 1, green: 1, blue: 1 };
  const requests = [...bandedRangeIds.map(id => ({ deleteBanding: { bandedRangeId: id } })), ...sheetIds.map(sheetId => ({ addBanding: { bandedRange: { rowProperties: { headerColor, firstBandColor, secondBandColor }, range: { sheetId, startRowIndex: 4, endRowIndex: 27, startColumnIndex: 0, endColumnIndex: 8 } } } }))
  ];
  
  // Request to Sheets API using the created request body.
  Sheets.Spreadsheets.batchUpdate({ requests }, spreadsheetId);

  // If you want to activate 'A5:H27' in each sheet, please use the following script.
  // SpreadsheetApp.flush();
  // ss.getSheets().forEach(sheet => {
  //   if (sheet.getSheetName() !== "HelperSheet") sheet.getRange('A5:H27').activate();
  // });
}

参考文献:

票数 0
EN

Stack Overflow用户

发布于 2021-12-08 19:45:55

似乎您的代码已经得到了足够的优化,我认为您可以将运行拆分为多个运行:

1)在循环开始时,初始化一个日期变量来存储当前时间。

2)在循环检查床单的同时,从一开始就检查过去的总时间

3)如果总时间大于脚本可用执行时间的80% (6分钟),那么在20秒可安装触发器之后启动一个新的触发调度。

4)并将已完成处理的工作表编号或名称存储在新的excel工作表(例如配置)中。

5)当触发器启动时,代码应从"config“工作表中获取工作表名称/编号,该表是已完成处理的工作表,并在该工作表编号之后开始处理。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70279622

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档