みなさんこんにちは!GASおじさんです。
「GASでスプレッドシートを自由自在に操るためのスキル習得講座」の第2回です。
前回の記事はこちら。
前回はスプレッドシートの単一のセルに値を入力するsetValueメソッドについて学びました。
今回は複数のセルに値を入力するsetValuesメソッドについて学習していきましょう!
前回のおさらい: 単一セルに値を入力するsetValueメソッド
まずは前回のおさらいです。
単一セルに値を入力するコードとして、以下のような書き方がありました。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
sheet.getRange('A1').setValue('あああ!');
}
こちらは「A1セルに『あああ!』と入力してください」と指示をするためのプログラムでしたね。
また、以下のような書き方もありました。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
sheet.getRange(2, 1).setValue('いいい!');
}
こちらは「2行1列目に『いいい!』と入力してください」と指示をするためのプログラムでした。
このように、getRangeメソッドのカッコの中で、
getRange('A1')
のように、「A1記法」で範囲を指定する方法getRange(1, 1)
のように、「何行何列目」という番地で範囲を指定する方法
の2つの方法があるんでしたね。
そしてgetRangeメソッドで範囲を指定した後に、setValueメソッドを使って値を入力する、という流れでした。
複数のセルに値を入力するsetValuesメソッド
では今回の主題である「複数のセルに値を入力する方法」についてです。
まず結論から述べると、setValuesメソッドというものを使います。
setValueではなく、setValuesですね。複数の値を入力するので複数形になっています。
単一セルの入力と同様に、getRangeメソッドで範囲指定をした後に、setValuesメソッドを使う、という流れになります。
そして、getRangeメソッドで範囲指定する際は、次の2通りの方法があります。
getRange('A1:E3')
のように、「A1記法」で範囲を指定する方法getRange(1, 1, 3, 5)
のように、「何行何列目から、何行何列分」という番地で範囲を指定する方法
1個ずつ説明していきます。
A1記法で範囲指定した後にsetValuesする
まずはプログラムを実行する
まずは実際にプログラムを動かしてみましょう。
以下のコードをエディタにコピペして、実行してみてください。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
sheet.getRange('A1:E3').setValues(values);
}
実行後スプレッドシートを確認すると…
A1からE3セルに複数の値が入力されていることが確認できました!
あらためてコードを確認しましょう。まず以下の9行目に注目してください。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
sheet.getRange('A1:E3').setValues(values);
}
sheet.getRange(‘A1:E3’)で「A1セルからE3セルまで」という複数の範囲を指定しています。
その後、setValuesメソッドで値を入力しています。この流れは単一セルの入力と同様ですね。
ただし、今回のsetValuesメソッドのカッコの中には、values
という変数が与えられています。
「変数」とはなんだったかというと、左辺にある「箱」のことでしたね。
右辺のデータを左辺の箱(変数)に代入することによって、右辺の長いデータを左辺の短い文字で楽に管理できるようになるのでした。
ではその変数values
はどこで定義されているかというと、4行目〜8行目ですね。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
sheet.getRange('A1:E3').setValues(values);
}
今回の右辺は複数行に渡っています。このように右辺は必ずしも1行だけで終わるとは限りません。
特に今回のように「二次元配列」を扱うときは、複数行に渡って書くことが多いですね。
配列について
ここで「配列」について説明しておきましょう。
['あ', 'い', 'う', 'え', 'お']
のように、大括弧[ ]
で定義されるデータのことを「配列」と呼びます。
配列は複数のデータを扱いたい時に用いるデータの管理手法です。
['あ', 'い', 'う', 'え', 'お']
では、あ〜おまでの5文字、つまり5つのデータを管理しているわけです。
ちなみに配列の中にある一つ一つのデータのことを「要素」と呼びます。要素と要素はカンマで区切ります。
今回の配列は['あ', 'い', 'う', 'え', 'お']
以外にも['か', 'き', 'く', 'け', 'こ']
と['さ', 'し', 'す', 'せ', 'そ']
がありますね。
そしてこれら3つの配列が、さらに大きな配列[ ]
の中に収納されています。
このように配列の中に配列がある状態のことを、「二次元配列」と言います。
今回の変数values
は二次元配列のデータが代入されているということですね。
ここであらためてイメージ図で確認してみましょう。
「右辺のデータを左辺の箱(変数)に代入する」の図です。そろそろこのイメージ図が頭に定着してきたでしょうか?この図を思い浮かべながら、「右辺を左辺に代入する」を念仏のように唱えて、変数についての理解を深めましょう。
setValuesメソッドでは入力する値を二次元配列の形式にする
さて、ここであらためて、単一セルに入力するコードと、複数セルに入力するコードを見比べてみましょう。
まず単一セルに入力するコードはこちら。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
sheet.getRange('A1').setValue('あああ!');
}
ちなみにこちらは以下のように書き換えることもできます。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const value = 'あああ!';
sheet.getRange('A1').setValue(value);
}
setValueする「あああ!」という値をvalue
という変数に代入しました。単数のデータなので単数形のvalueという変数名にしています。
一方、複数セルに入力するコードはこちらです。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
sheet.getRange('A1:E3').setValues(values);
}
どうでしょう。こうしてみると単一セルを入力するコードとよく似ていませんか?
その違いを以下のようにまとめてみました。
単一セルの入力 | 複数セルの入力 | |
---|---|---|
範囲指定 | getRange(‘A1’) | getRange(‘A1:E3’) |
メソッド | setValue(value) | setValues(values) |
入力する値 | ▼単一のデータ value = ‘あああ!’; | ▼二次元配列 values = [ [‘あ’, ‘い’, ‘う’, ‘え’, ‘お’], [‘か’, ‘き’, ‘く’, ‘け’, ‘こ’], [‘さ’, ‘し’, ‘す’, ‘せ’, ‘そ’], ]; |
一番重要なポイントは、複数のセルに値を入力するsetValuesメソッドを使うときは、入力する値を二次元配列の形式にしなければならない、という部分ですね。
ここは初学者がつまづきやすいポイントですので、繰り返し読んで理解に努めてください。
特にsetValueとsetValuesを間違えるミスはよくあるので、単数形と複数形の違いはよく意識しておきましょう。
番地で範囲指定した後にsetValuesする
まずはプログラムを実行する
では次に、番地で範囲指定した後にsetValuesする方法についてみていきます。
以下のコードをコピペして実行してみてください。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
sheet.getRange(1, 1, 3, 5).setValues(values);
}
実行後スプレッドシートを確認すると…
先ほどと同様、A1からE3セルに複数の値が入力されていることが確認できました!
getRangeで「何行何列目から、何行何列分」を指定する
あらためてコードを確認しましょう。以下の9行目に注目してください。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
sheet.getRange(1, 1, 3, 5).setValues(values);
}
sheet.getRange(1, 1, 3, 5)で「1行1列目から、3行5列分」という複数の範囲を指定しています。
getRangeメソッドのカッコの中の数字が4つあります。
最初の2つの数字が「開始地点」です。「何行何列目から」という意味ですね。
そして残りの2つの数字が「何行何列分」という意味になります。
A1セルからE3セルをこの番地指定の表記法で表すと、
「1行1列目から3行5列分」なので、getRange(1, 1, 3, 5)となるわけですね。
では、A5セルからE7セルに入力したい場合はどうすればいいでしょうか?
ここはぜひ、答えを見ずに、少し考えてチャレンジしてみてください。
・・・
・・・
・・・
さて、そろそろいいでしょうか?
それでは、正解は…
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
sheet.getRange(5, 1, 3, 5).setValues(values);
}
こうですね!
正解できたでしょうか?
しつこいようですが、こういうのは何度も練習しておいたほうがいいので、最後にもう1問です。
B9セルからF11セルに入力したい場合はどうすればいいでしょうか?
・・・
・・・
・・・
正解は…
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
sheet.getRange(9, 2, 3, 5).setValues(values);
}
です!
他にもいろいろ数字を書き換えて実行してみて、理解を深めてくださいね。
values.length
さて、
- A1セルからE3セルに入力する場合はgetRange(1, 1, 3, 5)
- A5セルからE7セルに入力する場合はgetRange(5, 1, 3, 5)
- B9セルからF11セルに入力する場合はgetRange(9, 2, 3, 5)
ということで、勘のいい人は、「後ろ2つの数字は常に一定になりそうだな」ということに気づけるかと思います。
そう、後ろ2つの数字は、セットする二次元配列の要素数で決まるんですね。
今回セットする二次元配列は、以下のような配列です。
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
このvaluesの要素数について考えてみましょう。
この配列は、以下のような構造になっています。
const values = [
1個目の要素,
2個目の要素,
3個目の要素,
];
これはつまり、valuesの要素数は「3」であるということです。
配列の要素数が欲しいときは、配列に対して.length
とすることで、要素数を取得することができます。
今回で言うとvalues.length
とすると、「3」という数字を取得することができるんですね。
つまり、getRangeメソッドの3つ目の数字は、以下のように書きかえることができます。
- A1セルからE3セルに入力する場合はgetRange(1, 1, values.length, 5)
- A5セルからE7セルに入力する場合はgetRange(5, 1, values.length, 5)
- B9セルからF11セルに入力する場合はgetRange(9, 2, values.length, 5)
このように抽象化することができるので、二次元配列の要素数が変わっても常にこの書き方で乗り切れます。
たとえば、valuesが以下のように変わったとしましょう。
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
['た', 'ち', 'つ', 'て', 'と'],
];
「た行」が増えました。この場合、valuesの要素数は「4」です。
なので、従来の書き方だったら、
getRange(1, 1, 3, 5)
となっていたところを、
getRange(1, 1, 4, 5)
と書き換えなければいけないのですが、
getRange(1, 1, values.length, 5)
であれば、values.lengthは今回の場合「4」になってくれるので、この書き方のまま乗り切れますよね。
なので要素数を気にせず、getRangeの3番目の数字は常にvalues.lengthでOKということになります。
values[0].length
ではつづいて、getRangeの4番目の数字について考えましょう。
以下のgetRangeの4番目の数字に注目ください。
- A1セルからE3セルに入力する場合はgetRange(1, 1, values.length, 5)
- A5セルからE7セルに入力する場合はgetRange(5, 1, values.length, 5)
- B9セルからF11セルに入力する場合はgetRange(9, 2, values.length, 5)
今回で言うと4番目の数字は常に「5」という数字になります。
これは、['あ', 'い', 'う', 'え', 'お']
という配列や、['か', 'き', 'く', 'け', 'こ']
という配列の要素数ですよね。
なのでこれらの要素数を取得する書き方をすればいいということになります。
ここで、配列の個別の要素を取得する方法を紹介します。
配列の要素は、配列名[インデックス番号]
という書き方で取得できます。
「インデックス番号」というのは、各要素に割り振られた連番のことです。
注意点として、インデックス番号は「0」から開始されます。
なので、今回の以下の配列の場合、
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
values[0]
は['あ', 'い', 'う', 'え', 'お']
values[1]
は['か', 'き', 'く', 'け', 'こ']
values[2]
は['さ', 'し', 'す', 'せ', 'そ']
ということになります。
では、values[0]
に対して.length
を使うとどうなるでしょうか。
これはつまり、['あ', 'い', 'う', 'え', 'お']
という配列に対して.length
を使うということになるので、「5」という数字を取得することになります。
ということで、getRangeの4つ目の数字は、以下のように書くことができます。
- A1セルからE3セルに入力する場合はgetRange(1, 1, values.length, values[0].length)
- A5セルからE7セルに入力する場合はgetRange(5, 1, values.length, values[0].length)
- B9セルからF11セルに入力する場合はgetRange(9, 2, values.length, values[0].length)
このように抽象化することができるので、これまた二次元配列の要素数が変わっても常にこの書き方で乗り切れます。
たとえば、valuesが以下のように変わったとしましょう。
const values = [
['あ', 'い', 'う', 'え', 'お', 'ア', 'イ', 'ウ', 'エ', 'オ'],
['か', 'き', 'く', 'け', 'こ', 'カ', 'キ', 'ク', 'ケ', 'コ'],
['さ', 'し', 'す', 'せ', 'そ', 'サ', 'シ', 'ス', 'セ', 'ソ'],
];
ひらがなにつづけてカタカナを追加しました。
この場合、values[0]の要素数は「10」です。
なので、従来の書き方だったら、
getRange(1, 1, values.length, 5)
となっていたところを、
getRange(1, 1, values.length, 10)
と書き換えなければいけないのですが、
getRange(1, 1, values.length, values[0].length)
であれば、values[0].lengthは今回の場合「10」になってくれるので、この書き方のまま乗り切れますよね。
なので要素数を気にせず、getRangeの4番目の数字は常にvalues[0].lengthでOKということになります。
getRange(開始行, 開始列, values.length, values[0].length)
ということで、ここまでをまとめると、番地で範囲指定した後にsetValuesメソッドを使うときは、次のように書けば良いということになります。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
sheet.getRange(開始行, 開始列, values.length, values[0].length).setValues(values);
}
9行目の「開始行」と「開始列」の部分には、適当な数字を入力します。
ためしに、「13行3列目から」入力する場合で実際にプログラムを実行してみましょう。
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const values = [
['あ', 'い', 'う', 'え', 'お'],
['か', 'き', 'く', 'け', 'こ'],
['さ', 'し', 'す', 'せ', 'そ'],
];
sheet.getRange(13, 3, values.length, values[0].length).setValues(values);
}
こちらをコピペして実行します。
スプレッドシートを確認すると…
無事、13行3列目から入力されていることが確認できました。
では、以下のように二次元配列の中身を変えてみたらどうでしょうか?
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('シート1');
const values = [
['あ', 'い', 'う', 'え', 'お', 'ア', 'イ', 'ウ', 'エ', 'オ'],
['か', 'き', 'く', 'け', 'こ', 'カ', 'キ', 'ク', 'ケ', 'コ'],
['さ', 'し', 'す', 'せ', 'そ', 'サ', 'シ', 'ス', 'セ', 'ソ'],
['た', 'ち', 'つ', 'て', 'と', 'タ', 'チ', 'ツ', 'テ', 'ト'],
];
sheet.getRange(17, 1, values.length, values[0].length).setValues(values);
}
二次元配列の中身が、4行10列分のサイズとなりました。
また、開始行と開始列は「17行1列目から」としています。
こちらもコピペして実行してみてください。
実行後、スプレッドシートを確認すると…
無事、17行1列目から、4行10列分のデータが入力されていることが確認できました!
まとめ
以上、複数のセルに値を入力するsetValuesメソッドについて解説してきました。
初心者にとっては初めての概念がたくさん出てきて、少し大変だったかもしれません。
しかし今回の内容は、GASでスプレッドシートを自由自在に操れるようになるためには、避けては通れない、とても重要な部分になります。がんばって乗り越えましょう。
ポイントを以下にまとめておきます。
- 複数のデータを扱う際は「配列」を使う
- 配列の中身の個別のデータのことを「要素」という
- setValuesメソッドでは入力する値を二次元配列の形式にする
- setValuesするときの範囲指定は、
getRange(開始行, 開始列, values.length, values[0].length)
と書く
今回の内容は繰り返し練習して、理解を深めるようにしておきましょう。
さて、前回と今回で値を入力するsetValueとsetValuesについて学習してきました。
次回からは、そんなsetValueやsetValuesと対をなす存在、getValueメソッドとgetValuesメソッドについて学習していきます!
以下から次に進みましょう!
連載目次: GASでスプレッドシートを自由自在に操るためのスキル習得講座
- 【GASの始め方】まずはスプレッドシートの操作から始めてみよう
- 【GASの始め方】setValuesで複数のセルに値を入力しよう
- 【GASの始め方】getValueで値を取得してsetValueで入力しよう
- 【GASの始め方】getValuesで複数のセルの値を取得しよう
- 【GASの始め方】getValuesして別のシートにsetValuesしよう
- 【GASの始め方】応用問題で関数について学ぼう
- 【GASの始め方】繰り返し処理の「for文」を習得しよう
- 【GASの始め方】flat()でループさせる配列を自動生成しよう
- 【GASの始め方】for文とif文でデータ抽出して配列を生成しよう
- 【GASの始め方】TextFinderで行と列を特定しよう
- 【GASの始め方】オブジェクトとメソッドについて学ぼう
- 【GASの始め方】リファクタリングで生成AIを活用しよう
Udemy動画解説
当シリーズはUdemyで動画解説をしています。
動画で学びたい方は以下からご購入ください。Udemyでは月4〜5回セールが開かれますので、セール期間中にご購入いただくのがオススメです。
コメント