【问题标题】:setFormulas and rangeListsetFormulas 和 rangeList
【发布时间】:2018-12-25 03:45:47
【问题描述】:

我正在尝试setFormulas 覆盖一系列不连续的单元格。我需要一个公式(它们都不同)在单列(c)中设置每 30 个单元格。

它适用于每个单元格的setFormula,但创建 56 个变量似乎没有必要。我可以得到公式,但不能按预期设置它们。我也尝试过使用getRangeList,但我不确定它是否符合我的想法。有什么建议吗?

function test() {
  var spreadsheetU09U10 = SpreadsheetApp.openById('some url');
  var sheetU09 = spreadsheetU09U10.getSheetByName('TEST');
  var sheetU10 = spreadsheetU09U10.getSheetByName('U10');
  var sheetDATA = spreadsheetU09U10.getSheetByName('Sheet4');

  //U09 SHEET
  //var rangeListU09 = sheetU09.getRangeList(['C4','C34','C64','C94','C124','C154','C184','C204','C234','C264','C294','C324','C354','C384','C404','C434','C464','C494',
  //'C524','C554','C584','C604','C634','C664','C694','C724','C754','C784']);
  //Logger.log(rangeListU09);
  var startRow = 4;
  var startColumn = 3;
  var numRows = sheetU09.getLastRow();
  var numColumns = 1;
  var range = sheetU09.getRange(startRow, startColumn, numRows, numColumns);

  var getFormulasU09 = sheetDATA.getRange('C30:C57').getFormulas();
  //Logger.log(getFormulasU09);
  Logger.log(getFormulasU09.length);

  for (var i = 0; i < getFormulasU09.length; i++) {
    var setFormulasU09 = range.setFormulas(getFormulasU09);
    Logger.log(setFormulasU09);
    startRow = startRow + 29; 
  }

【问题讨论】:

    标签: arrays google-apps-script google-sheets google-sheets-api


    【解决方案1】:

    尚不清楚您使用的公式的确切来源,但RangeList 类可以帮助reduce the read time,即使您只是使用它来调用getRanges。如果公式在 R1C1 格式中相同,那么您可以非常有效地使用RangeList#setFormulaR1C1

    假设您在一个区域中的公式必须逐字写入一组不相交的单元格中:

    const wb = SpreadsheetApp.getActive();
    // Assuming only text formulas, not actual "entered" formulas
    const formulas = wb.getSheetByName("formulas").getDataRange()
        .getValues()
        .map(function (row) { return row[0]; });
    
    const sheet = wb.getSheetByName("some name");
    const destinations = [
      // Depending on the relationship between destinations, one could programmatically generate these
    ];
    // Efficiently acquire references to multiple disjoint Ranges
    const rl = sheet.getRangeList(destinations);
    // Assume the i-th formula goes in the i-th range
    rl.getRanges().forEach(function (rg, i) {
      rg.setFormula(formulas[i]);
    });
    // The RangeList makes uniformly formatting these disjoint ranges extremely simple
    rl.setFontWeight('bold');
    ...
    

    参考 - RangeList

    【讨论】:

    • 这些是实际的“输入”公式,这就是我使用getFormulas 的原因。如果我使用纯文本版本,我是否需要通过并插入= 以使它们全部激活?
    • 您可以将getValues 替换为getFormulas 以获得等效性。我相信如果使用 setFormula 变体时不存在等号,则会添加等号。
    【解决方案2】:
    • 您想将公式放入各个单元格。
      • 您想在TEST 的工作表中将28 个公式放入['C4','C34','C64','C94','C124','C154','C184','C204','C234','C264','C294','C324','C354','C384','C404','C434','C464','C494', 'C524','C554','C584','C604','C634','C664','C694','C724','C754','C784'] 的单元格中。

    如果我的理解是正确的,那么使用 Sheets API 的 values.batchUpdate 怎么样?该脚本的流程如下。

    1. 将范围列表设置为一维数组。
    2. 检索公式。
    3. 为 sheet.spreadsheets.values.batchUpdate 创建请求正文。

    要使用此脚本,请在高级 Google 服务和 API 控制台中启用 Sheets API。您可以在 here 了解如何启用 Sheets API。

    示例脚本:

    function test() {
      var spreadsheetId = "### spreadsheetId ###"; // Please set this.
    
      var sheetName = "TEST";
      var spreadsheetU09U10 = SpreadsheetApp.openById(spreadsheetId);
      var sheetU09 = spreadsheetU09U10.getSheetByName(sheetName);
    //  var sheetU10 = spreadsheetU09U10.getSheetByName('U10'); // This is not used in this script.
      var sheetDATA = spreadsheetU09U10.getSheetByName('Sheet4');
    
      var rangeListU09 = ['C4','C34','C64','C94','C124','C154','C184','C204','C234','C264','C294','C324','C354','C384','C404','C434','C464','C494', 'C524','C554','C584','C604','C634','C664','C694','C724','C754','C784'];
      var getFormulasU09 = sheetDATA.getRange('C30:C57').getFormulas();
    
      rangeListU09 = rangeListU09.map(function(e) {return sheetName + "!" + e});
      var resource = {
        data: rangeListU09.map(function(e, i) {return {range: e, values: [[getFormulasU09[i][0]]]}}),
        valueInputOption: "USER_ENTERED",
      };
      Sheets.Spreadsheets.Values.batchUpdate(resource, spreadsheetId);
    }
    

    注意:

    • 根据您的问题,我不确定详细公式。如果需要修改每个公式的a1Notation,能否提供包含公式的示例电子表格?

    参考:

    如果我误解了你的问题,请告诉我。我想修改它。

    【讨论】:

    • 效果很好。我不能 100% 确定你做了什么,但它确实有效,并且给了我一些可以修补的东西。
    • @Nate Davis 很高兴您的问题得到了解决。也谢谢你。
    【解决方案3】:

    我假设您要从数组中的单元格位置开始复制整个列。这对我来说并不是很清楚。

    function test109() {
      var ss=SpreadsheetApp.getActive();
      var shU09=ss.getSheetByName('35');//formulas get copied into here starting at row 4
      var shDATA=ss.getSheetByName('36');//formulas stored in here C30:C57
      var fA=shDATA.getRange('C30:C57').getFormulas();
      var dA=['C4','C34','C64','C94','C124','C154','C184','C204','C234','C264','C294','C324','C354','C384','C404','C434','C464','C494','C524','C554','C584','C604','C634','C664','C694','C724','C754','C784'];  
      for(var i=0;i<dA.length;i++){
        var rgs=Utilities.formatString('%s:%s',dA[i],shU09.getRange(dA[i]).offset(fA.length-1,0).getA1Notation());//this uses range.offset to calculate the correct range in A1Notation.
        shU09.getRange(rgs).setFormulas(fA);
      }
    }
    

    事实证明,我刚刚注意到有 28 个位置和 28 个公式。也许这是故意的,您想在每个位置复制不同的公式,那么这个版本会这样做。

    function test109() {
      var ss=SpreadsheetApp.getActive();
      var shU09=ss.getSheetByName('35');//formulas get copied into here starting at row 4
      var shDATA=ss.getSheetByName('36');//formulas stored in here C30:C57
      var fA=shDATA.getRange('C30:C57').getFormulas();
      var dA=['C4','C34','C64','C94','C124','C154','C184','C204','C234','C264','C294','C324','C354','C384','C404','C434','C464','C494','C524','C554','C584','C604','C634','C664','C694','C724','C754','C784'];
      for(var i=0;i<dA.length;i++){
        shU09.getRange(dA[i]).setFormula(fA[i][0]);
      }
    }
    

    【讨论】:

    • 我不断收到错误“无法将数组转换为对象[][]”
    • 只需要稍作调整。对不起,昨晚我这样做的时候已经很晚了。只需将shU09.getRange(dA[i]).setFormulas(fA[i]) 更改为shU09.getRange(dA[i]).setFormula(fA[i][0])
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 2011-02-17
    相关资源
    最近更新 更多