Javascript 如何使我的谷歌应用程序脚本在电子表格多色甘特图中运行得更快?

Javascript 如何使我的谷歌应用程序脚本在电子表格多色甘特图中运行得更快?,javascript,google-apps-script,google-sheets,gantt-chart,setbackground,Javascript,Google Apps Script,Google Sheets,Gantt Chart,Setbackground,我正在将谷歌工作表的列和行格式化为一个大甘特图。这个图显示每个员工在每个项目中的工作周数。每个人都有一个独特的颜色栏。颜色栏的位置和长度基于项目的开始周和持续时间。我创建了一个“全部更新”按钮,并将函数Update_All()分配给该按钮。一旦我运行这个函数,我希望所有的颜色栏都被更新 我的剧本还可以。然而,更新70行需要40秒,这使得它很难扩展到更大的员工群体。耗时最长的操作是将单元格的背景色设置为员工指定的颜色。如何改进脚本以使其更快,有什么建议吗 这是甘特图的样子——goole工作表文件

我正在将谷歌工作表的列和行格式化为一个大甘特图。这个图显示每个员工在每个项目中的工作周数。每个人都有一个独特的颜色栏。颜色栏的位置和长度基于项目的开始周和持续时间。我创建了一个“全部更新”按钮,并将函数Update_All()分配给该按钮。一旦我运行这个函数,我希望所有的颜色栏都被更新

我的剧本还可以。然而,更新70行需要40秒,这使得它很难扩展到更大的员工群体。耗时最长的操作是将单元格的背景色设置为员工指定的颜色。如何改进脚本以使其更快,有什么建议吗

这是甘特图的样子——goole工作表文件

这是我的密码

function updateall(){

     var sss = SpreadsheetApp.openById("1nvnZB62CYUeUUZSkAuHsxMJF5MBr7D1rNG3ffU8jKdI");
  var ssColor = sss.getSheetByName("2. Color Legend");
  var ssPlanner = sss.getSheetByName("Project Planner");

  // Step 1: clear all the orginal color 
  ssPlanner.getRange("I4:BU120").setBackground('#ffffff');

  // Step 2: create a dictionay {staff name : coloe code}
   var keycolumns = ssColor.getRange(3,2,16,1).getValues();
  var data = ssColor.getRange(3,3,16,1).getValues();
  var dict_data = {};
  for (var keys in keycolumns) {
    var key = keycolumns[keys];
    dict_data[key] = data[keys];
  }

  Logger.log(dict_data["BBB"]);

  //Step3:set background color for each row
    for (var bRow=4; bRow<121; bRow++){
    if (ssPlanner.getRange("E"+bRow).getValue()!=""){

    var start = ssPlanner.getRange(bRow,7).getValue()-ssPlanner.getRange(3,9).getValue()+9;
    var duration = ssPlanner.getRange(bRow,8).getValue();

  ssPlanner.getRange(bRow,start,1,duration).setBackground(dict_data[ssPlanner.getRange(bRow,5).getValue()]);

  }
  }
 }
函数updateall(){
var sss=SpreadsheetApp.openById(“1NVNZB62CYUEUUUZSKAUHSXMJF5MBR7D1RNG3FFU8JKDI”);
var ssColor=sss.getSheetByName(“2.颜色图例”);
var ssPlanner=sss.getSheetByName(“项目规划器”);
//步骤1:清除所有原始颜色
ssPlanner.getRange(“I4:BU120”).setBackground(“#ffffff”);
//步骤2:创建一个字典{员工姓名:coloe代码}
var keycolumns=ssColor.getRange(3,2,16,1).getValues();
var data=ssColor.getRange(3,3,16,1).getValues();
var dict_data={};
for(键列中的变量键){
var key=keycolumns[keys];
dict_data[键]=数据[键];
}
Logger.log(dict_数据[“BBB”]);
//步骤3:为每行设置背景色

对于(var bRow=4;bRow我相信您的目标如下

  • 您希望降低脚本的处理成本
对于这个问题,这个答案如何

修改点:
  • 在您的脚本中,
    getRange
    getValue
    setBackground
    用于循环中。我认为在这种情况下,脚本的处理成本将很高。为了降低脚本的成本,我想提出以下流程。在这次修改中,我修改了脚本中的
    Step3

  • 从范围
    E3:I121
    中检索所有值。
    • 使用了
      getValues()
  • 创建一个数组,用于使用检索到的值放置颜色。
    • 在本例中,您要设置的颜色是从您创建的
      dict_data
      中使用的。并且,没有颜色的单元格被设置为
      null
      。因此在本例中,
      ssPlanner.getRange(“I4:BU120”).setBackground('#ffffff')
      可以修改为
      ssPlanner.getRange(“I4:BU120”).setBackground(null)
    • 不使用
      getRange
      getValue
      setBackground
  • 使用创建的数组(包括颜色代码)设置颜色。
    • 使用设置背景
当上述流程反映到脚本中时,它将变成如下所示

修改脚本: 修改脚本时,请按以下方式修改

发件人: 参考资料:

您是否尝试对每列使用setBackground()。@Cooper没有。因为颜色栏是水平的,所以我选择了每行的特定范围(单元格)。你是建议翻转它吗?什么颜色是相同的。颜色范围一次全部覆盖。这太棒了!非常感谢。虽然这些功能对我来说是新的,但我需要学习。它工作得非常好!@Macrocks感谢你的回复。我很高兴你的问题得到解决。也谢谢你。
//Step3:set background color for each row
  for (var bRow=4; bRow<121; bRow++){
  if (ssPlanner.getRange("E"+bRow).getValue()!=""){

  var start = ssPlanner.getRange(bRow,7).getValue()-ssPlanner.getRange(3,9).getValue()+9;
  var duration = ssPlanner.getRange(bRow,8).getValue();

ssPlanner.getRange(bRow,start,1,duration).setBackground(dict_data[ssPlanner.getRange(bRow,5).getValue()]);

}
}
// Step3:set background color for each row
// 1. Retrieve all values from the range of `E3:I121`.
const values = ssPlanner.getRange("E3:I121").getValues();
const offset = values.shift()[4];

// 2. Create an array for putting the colors using the retrieved values.
const colors = values.reduce((ar, [e,f,g,h]) => {
  let base = Array(65).fill(null);
  if (e != "") Array.prototype.splice.apply(base, [g - offset, h].concat(Array(h).fill(dict_data[e][0])));
  ar.push(base);
  return ar;
}, []);

// 3. Set the colors using the created array including the color codes.
ssPlanner.getRange(4, 9, colors.length, colors[0].length).setBackgrounds(colors);