menu
書いてる野郎
orebike@gmail.com
GAS ではセル単独の操作ではなく、その範囲の集合体として操作する。 つまり、その範囲がセル1個分ならばセルの操作となる。
セルはシートオブジェクトから得られる。
var ss = SpreadsheetApp.getActiveSpreadsheet(); var s = ss.getSheetByName("sheet1"); var range = s.getRange(2, 3, 100, 4);
セルは1個1個ではなくて、Range というセルの集合体として取得される。
↑の例では、2行目の3列目から、全体で100行、4列の範囲を得ている。 つまり、2行目から101行目(100行)、3列目(C列)から6列目(F列)の範囲(hoge が書き込まれている所)ということになる。
A | B | C | D | E | F | G | |
---|---|---|---|---|---|---|---|
1 | |||||||
2 | hoge | hoge | hoge | hoge | |||
3 | hoge | hoge | hoge | hoge | |||
… | … | … | … | … | |||
101 | hoge | hoge | hoge | hoge | |||
102 |
第三引数と第四引数は省略可能で、その場合は自動的に「1」に設定される。
なので、このように取得すると、セル1個を表すこととなる。
var range = s.getRange(2, 3);
列は画面上では A,B,C,… と振られているが GAS の数値としてはそれらに 1,2,3,… と数値が割り当てられている。 つまり3列目には「C」と呼ばれるが、内部では「3」である。
このような連続的な箱はプログラミングでは配列で表現されることが多くその番号は「0」から始まることが多いが、 Google Spread Sheets では「1」スタートである。
Range は Range の集合体ではないのだが、範囲セル1個分に限っては扱うことができて、それ専用のメソッドもある
var ss = SpreadsheetApp.getActiveSpreadsheet(); var s = ss.getSheetByName("sheet1"); var range = s.getRange(2, 3, 100, 4); var cell = range.getCell(10, 4); // s.getRange(11, 6) と同じ範囲を得る
このようにすると 1個分の Range、つまりセルが範囲に対する相対位置指定で取得できる。
この場合ならば、2行目から10個目↓のセル、2,3,4,5,6,7,8,9,10,11 つまり 11行目、3列目から4個→のセル、3,4,5,6 つまり 6列目 のセルを得ることができる。
マウスやキーボード等で選択されている範囲を取得することができる。 このことによりシートを簡易的なデータ選択入力フォームとして使えるようになるので便利である。
var ss = SpreadsheetApp.getActiveSpreadsheet(); var s = ss.getSheetByName("sheet1"); var range = s.getActiveRange();
↓で示すような飛び地の複数範囲選択状態になっっている場合は、最後に選択した範囲を得られるようだ。
Google Spread Sheets の操作として1個のデカイ範囲でなく、Ctrl 等のキーと組み合わせて、複数の飛び地のセルを選択状態にできるが、 そのような場合はどうするのか?
以前はこのような状態を取得することはできなかったようなのだが、2018年08月現在、できるようになっている。
var ss = SpreadsheetApp.getActiveSpreadsheet(); var s = ss.getSheetByName("sheet1"); var rangeList = s.getActiveRangeList(); var row1 = rangeList.getRanges()[0].getRow(); var row2 = rangeList.getRanges()[1].getRow(); var row3 = rangeList.getRanges()[2].getRow();
RangeList という Range の集合体概念がありそこから getRanges メソッドにより配列として取得できる。 この配列の順番は、選択した順番になっている。
var range = s.getRange(2, 3, 100, 4); var row = range.getRow(); // -> 2
このように取得できる。 getRowIndex()
というメソッドも存在するが、動作は同じで名前だけが違う。
↑の例ならば、2 という値が取得できる。範囲中の一番左上のセルの行番号が取得できると思ってよい。
行数が取得できるわけではない
逆に範囲の右下のセルの行番号がほしい場合はこうなる。
var range = s.getRange(2, 3, 100, 4); var row = range.getLastRow(); // -> 101
列の値も同様に getColumn
というメソッドがあるのでそれを使う。
行「番号」ではなくて「行数」がほしい場合はこのようにする。
var range = s.getRange(2, 3, 100, 4); var size = range.getNumRows(); // -> 100
列数も同様に getNumColumns
というメソッドがあるのでそれを使う。
セルに値を書き込む場合はこのようにする
var range = s.getRange(2, 3, 100, 4); range.setValue("hogehoge");
この setValue
というメソッドで書き込むことができる。
この例の場合は範囲に対して1個の値を書き込んでいるので、
この範囲の全セルに対して「hogehoge」という値が書き込まれる。
値を書き込む際にその値が、undefined
だった場合、文字列として undefined
という文字がセルに書き込まれる。
明示的に何も入れないは null
を書き込む。
setValue でセルに値を書き込むのだが、連続した複数のセルに同じ値を書き込むのは稀であって、 この操作は結局1セル分の範囲を指定して何度も書き込むことになることが多い。
しかしここに問題があってこの setValue の操作がやたら遅いのである。 なので連続で何度も呼び出すと時間がかかってしまう。
ここでこの複数のセルに一括で書き込む処理をするための別のメソッドがあるのでそれを使う
var range = s.getRange(2, 3, 100, 4); range.setValues([ [1, 2, 3, 4], [2, 4, 6, 8], [3, 6, 9, 12], ... [100, 200, 300, 400] ]);
この範囲のセルと行数列数完全に同一の2次元配列を作って、それを渡してやることで一括書き込みができる。複数形になっているところがポイント。
このメソッドを使う上で不便なところは、指定している範囲と配列の大きさを完全に同一にしなければならないというところ。 小さくても大きくてもだめ。存在する分だけ書き込んでくれるわけでもなく、はみ出したら切り捨ててくれるわけでもない。
値が無いからといって列を書かないというわけでもない。無いなら null でも詰め込んで同一形状にする必要がある。
使い勝手がめちゃくちゃ悪い。
ちなみに JavaScript の配列は length のプロパティは取得だけでなく設定もできて、length に設定した値が強制的にその大きさになるので、多ければ切り捨て、少なければ付け足しという動作になる。
セルから値を読み取るには getValue というメソッドを使う
var range = s.getRange(2, 3); var v = range.getValue();
セルに値をセットする場合と同様にセルから値を読み取るモノにも一気にやるやりかたがある
var range = s.getRange(2, 3, 100, 4); var v = range.getValues();
このように getValues というメソッドを使う。
これを実行すると、setValues の反対で、2次元配列の形で範囲の値を一気に取得することができる。
clearContent を使うことで値のみ削除できる。
var range = s.getRange(2, 3, 100, 4); range.clearContent();
この削除は値のみで書式は維持されるので、シートの構築は普通の Google Spread Sheets の操作でやって、その中のデータの構築は GAS でやるような役割分担ができるようになる。
range.breakApart()
結合解除の後は結合されていた複数のセルが選択状態になる