GASの基本

【GASの始め方】setValuesで複数のセルに値を入力しよう

複数セルに入力するsetValuesメソッド GASの基本

みなさんこんにちは!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メソッドを使うときは、入力する値を二次元配列の形式にしなければならない、という部分ですね。

ここは初学者がつまづきやすいポイントですので、繰り返し読んで理解に努めてください。

特にsetValuesetValuesを間違えるミスはよくあるので、単数形と複数形の違いはよく意識しておきましょう

二次元配列をセット
二次元配列をセット

番地で範囲指定した後に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列分」という複数の範囲を指定しています。

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

こうですね!

5行1列目から、3行5列分
5行1列目から、3行5列分

正解できたでしょうか?

しつこいようですが、こういうのは何度も練習しておいたほうがいいので、最後にもう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」という数字を取得することになります。

values[0]の要素数は5
values[0]の要素数は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)と書く

今回の内容は繰り返し練習して、理解を深めるようにしておきましょう。

さて、前回と今回で値を入力するsetValuesetValuesについて学習してきました。

次回からは、そんなsetValuesetValuesと対をなす存在、getValueメソッドとgetValuesメソッドについて学習していきます!

以下から次に進みましょう!

連載目次: GASでスプレッドシートを自由自在に操るためのスキル習得講座

  1. 【GASの始め方】まずはスプレッドシートの操作から始めてみよう
  2. 【GASの始め方】setValuesで複数のセルに値を入力しよう
  3. 【GASの始め方】getValueで値を取得してsetValueで入力しよう
  4. 【GASの始め方】getValuesで複数のセルの値を取得しよう
  5. 【GASの始め方】getValuesして別のシートにsetValuesしよう

GASを勉強するならこちら!

▼オススメ書籍はこちら!

スポンサーリンク
GASおじさんをフォローする
GASおじさんのブログ

コメント

タイトルとURLをコピーしました