LoginSignup
2
1

More than 3 years have passed since last update.

GAS Rangeを制するものはスプシを

Posted at

GASの鉄板が、「セル1つ1つ処理をしない」こと。
以下のコードは相当な遅さになるそうな。(やったことないから伝聞)

for(let i = 0;i < 100 ; i++){
  let data = SpreadsheetApp.getActiveSheet().getRange(1,i).getValue();
  data = data + "-";
  SpreadsheetApp.getActiveSheet().getRange(1,i).setValue(data);
}

セル操作がそこそこ時間がかかるので、なるべくまとめてgetsetしたほうがよい、と。
結果、以下のようにするのがはやいそうな(こっちでしかしたことがない。)

let range = SpreadsheetApp.getActiveSheet().getRange(1,0,1,100);
let values = range.getValues();
for(let i = 0;i < 100 ; i++){
  values[0][i] = values[0][i] + "-";
}
range.setValues(values);

1.Range

クラスリファレンス
いわゆるセルのかたまり。
セル1つでも、グループでもレンジとしてデータの取得、設定ができる。
大体、ループで処理をすると思うので、レンジで処理すると楽。
レンジの取得はいくつかのメソッドがある

let sheet = SpreadsheetApp.getActiveSheet();
let rangeA = sheet.getRange(row,column);
let rangeB = sheet.getRange(row,column,numOfRow);
let rangeC = sheet.getRange(row,column,numOfCol);
let rangeD = sheet.getRange(row,column,numOfRow,numOfCol);
let rangeE = sheet.getRange("Invoices!A1:D4");

rangeAは(row,col)の位置の1つのセル
rangeBは(row,col)の位置からnumOfRow個のセル(行)
rangeCは(row,col)の位置からnumOfCol個のセル(列)
rangeDは(row,col)の位置からnumOfCol,numOfRowのセル(行、列)
rangeEはInvoicesシートのA1からD4の範囲のセル
大抵はrangeDを使うことが多い。E使うくらいなら、下のnamedRangeを使う。

このRangeに対して、


let values = range.getValues() // returns string[][];
for(let i = 0;i < values.length;i++){
  for(let j = 0; j < values[i].length;j++){
   console.log(values[i][j]);
  }
}
...
...

range.setValues(values);

などとデータ操作が可能となる。
注意点としては、setValuesの引数の配列の次元とrangeの次元が合わないと実行エラーとなる。

2.Backgrounds Notes など

スプシなので、キレイに背景色やフォント、メモを設定したい。
Rangeでちまちま1つ一つやらず、配列にいれて一気に設定したい。

let colors = range.getBackgrounds(); // returns string[][]
let notes = rage.getNotes(); // returns string[][]
...
...
range.setBackgrounds(colors);
range.setNotes(notes);

多分、設定できるものはすべて、単体と複数のget,setメソッドあると思うので、rangeをつかって一気にやりたいもの。

3.NamedRange

他のシートの範囲を取りたい、複数人で触ってて行、列が変わってしまったりする(勝手に行を足しちゃう)、等を考えると、namedRangeを使うと楽に。
シートからは、「データ」→「名前付き範囲」で確認できる。
名前をつけた範囲は簡単に取得できる。

名前付き範囲を名前から取得

let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
let range = spreadsheet.getRangeByName('myRange'); // returns Range
...

NamedRange自身を取得するにはgetNamedRangesで取得できる配列を回してとる必要がある。
(NamedRangeに対する操作はほぼ不要なので使うことはないと思われる。)

名前付き範囲の設定

名前付き範囲の設定も簡単

let range = sheet.getRange(row,col,numOfRow,NumOfCol);
spreadsheet.setNamedRange("My range",range);

NamedRange自身は使うけど、NamedRangeオブジェクトはほぼ使わないと思われる。
メソッドの戻りがRangeオブジェクトだし、NamedRangeオブジェクトのメソッドにはあまり使うものがない。

備考

注意点としては、NamedRangeの操作はSpreadsheetオブジェクトに対して行う、という点。
名前を一意につけてない場合は、シート名+範囲名とする(リファレンスソースより)

getRangeByName('TaxRates') or getRangeByName('Sheet Name!TaxRates')

備考の備考

(名前付き範囲をいじるのはメニューをひらかないといけないから、そうそう変な操作の影響は受けないと思う)

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1