简体   繁体   English

在Google Apps脚本中定义多个范围

[英]Define multiple ranges in Google Apps Script

I'm having difficulty defining multiple ranges in GAS. 我在GAS中定义多个范围时遇到困难。

I have the following simple function I need to perform: 我需要执行以下简单功能:

var dataRange = sheet.getRange(checkRange);
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++) {
  for (var j = 0; j < values[i].length; j++) {
    if (values[i][j] == false) {
      values[i][j] = true; 
    }
  }
}
dataRange.setValues(values);

My range is actually defined by another function: 我的范围实际上是由另一个函数定义的:

var checkRange = [];

  for(var i = 0; i<checkboxes.length; i++) {
  if(checkboxes[i]) {

  checkRange.push('C' + (i+9));
  Logger.log(checkRange);
  }
  }

Now, the required range is being created nicely as I can see in my logs. 现在,可以很好地创建所需范围,正如我在日志中看到的那样。 However, clearly the format that GAS required for cell ranges is different as my range is not defined. 但是,很明显,单元格范围所需的GAS格式不同,因为我的范围未定义。 Furthermore, I have tried to work out the precise acceptable way of writing a range in GAS. 此外,我试图找出在GAS中编写范围的精确可接受的方法。 If I put a range like 'C9:C11' the script works fine. 如果我将范围设为“ C9:C11”,则脚本可以正常运行。 If I put a list like 'C9, C10' or 'C9', 'C10' etc. it does not. 如果我输入类似“ C9,C10”或“ C9”,“ C10”等的列表,则不会。 Neither do multiple ranges ('C9:C11', 'C13:C14') etc... not quite sure how I need to write this 也没有多个范围(“ C9:C11”,“ C13:C14”)等...不太确定我该怎么写

When accessing ranges from Google Apps Script each Range must be a continuous block, you can't select discrete ranges like C9:C11 and C13:C14 as a single Range object. 从Google Apps脚本访问范围时,每个范围必须是一个连续的块,您不能将离散范围(如C9:C11和C13:C14)选择为单个范围对象。 You need to access those ranges separately. 您需要分别访问这些范围。

A simple, but potentially inefficient, way to modify your existing code would be to loop over your checkRange array and access them one at a time: 修改现有代码的一种简单但可能效率不高的方法是遍历checkRange数组并一次访问它们:

for(var j = 0; j < checkRange.length; j++){
   dataRange = sheet.getRange(checkRange[j]);
   var values = dataRange.getValues();
   for (var i = 0; i < values.length; i++) {
     for (var j = 0; j < values[i].length; j++) {
       if (values[i][j] == false) {
         values[i][j] = true; 
       }
     }
   }
 }

If each range is just a single cell, you can switch getValues() for getValue(), and then you don't need to loop over your values array. 如果每个范围只是一个单元格,则可以将getValues()切换为getValue(),然后就不需要遍历values数组。

However, this will be very inefficient if you are accessing what could be one large range as a series of smaller ranges. 但是,如果您访问的是一个较大的范围或一系列较小的范围,则效率将非常低下。 It would be better to either use some logic to build multi-cell ranges where possible, or to read in the entire sheet as a single range ( sheet.getDataRange().getValues() ), and then use Array notation to access the cells you are interested in, before writing back the entire array. 最好使用一些逻辑来构建多单元格范围,或者将整个工作表作为单个范围读取( sheet.getDataRange().getValues() ),然后使用数组符号访问单元格您有兴趣,然后再写回整个数组。

Performing the same operation on possibly-disjoint Range s is most easily done with the Rangelist class , and does not require directly accessing the member Range s. 使用Rangelist最容易地对可能不相交的Range执行相同的操作,并且不需要直接访问成员Range However, even if the operations are different (or conditional), a RangeList can be used to optimize the use of the Spreadsheet Service, rather than repeatedly calling Sheet#getRange . 但是,即使操作不同(或有条件),也可以使用RangeList来优化Spreadsheet Service的使用,而不必重复调用Sheet#getRange

From your code, we can determine that the goal is to operate on a set of ranges related to "true" checkboxes: 根据您的代码,我们可以确定目标是在与“真实”复选框相关的一组范围内进行操作:

var checkRange = [];
for (var i = 0; i < checkboxes.length; i++) {
  if (checkboxes[i]) {
    checkRange.push('C' + (i+9));
    Logger.log(checkRange);
  }
}

You then (appear to) have a conditional alteration of the related range's value: 然后,您(似乎)对相关范围的值进行了有条件的更改:

var dataRange = sheet.getRange(checkRange);
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++) {
  for (var j = 0; j < values[i].length; j++) {
    if (values[i][j] == false) {
      values[i][j] = true; 
    }
  }
}
dataRange.setValues(values);

Instantiating a RangeList is done with an Array of string references to ranges on a sheet, eg [ "A1:A10", "C2", "D6:E8", "R5C9:R100C9" ] . 实例化RangeList是通过对工作表上的范围的字符串引用Array来完成的,例如[ "A1:A10", "C2", "D6:E8", "R5C9:R100C9" ] Thus, it appears your current checkRange has the desired format already. 因此,您当前的checkRange似乎已经具有所需的格式。

Your consumption code is then something like the following: 然后,您的消费代码如下所示:

const rl = sheet.getRangeList(checkRange);
rl.getRanges().forEach(function (rg) {
  // Assumption: only single-cell ranges, based on the above checkRange code
  if (rg.getValue() == false) // matches false, null, undefined, 0, or ""
    rg.setValue(true);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM