Google Apps脚本:setFormulas和rangeList

时间:2018-12-25 03:45:47

标签: google-apps-script google-sheets

我正在尝试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; 
  }

3 个答案:

答案 0 :(得分:2)

  • 您想将公式放入各个单元格。
    • 您要在['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']表中的TEST的单元格中放入28个公式。

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

  1. 将范围列表设置为一维数组。
  2. 检索公式。
  3. 为sheets.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,可以提供一个包含公式的电子表格示例吗?

参考:

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

答案 1 :(得分: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

答案 2 :(得分:1)

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

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]);
  }
}