みなさんこんにちは!GASおじさんです。
「GASでスプレッドシートを自由自在に操るためのスキル習得講座」の第8回です。
前回の記事はこちら。
前回は繰り返し処理のfor文について学習しました。
今回はループさせる配列を自動生成して、より汎用性の高いプログラムにしていきましょう。
応用問題レベル2
解説にあたって応用問題レベル2を用意しました。
まずは以下のスプレッドシート「GASをはじめよう!応用問題レベル2」を開いてコピーを作成してください。
レベル2では新たに「D社」「E社」が追加されました。
問題の内容としてはレベル1と同じです。「集計」シートに5社の売上を集計するプログラムを作成しましょう。
前回作成したコード
まずは前回作成したコードを振り返りましょう。
function setTotalSales() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('集計');
const companies = ['A社', 'B社', 'C社'];
const values = [];
for(const company of companies){
values.push([getTotalSales(company)]);
}
sheet.getRange(2, 2, values.length, values[0].length).setValues(values);
}
function getTotalSales(sheetName) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
const lastRow = sheet.getLastRow();
return sheet.getRange(lastRow, 2).getValue();
}
こちらは「A社」「B社」「C社」の3社を集計するプログラムでした。
ポイントは4行目、
const companies = ['A社', 'B社', 'C社'];
ですね。
ここで配列を定義して、この配列をfor文でループさせて各社の売上を集計しているのでした。
したがって、ここに「D社」「E社」を追加する場合は、
const companies = ['A社', 'B社', 'C社', 'D社', 'E社'];
とすればOKですね。
function setTotalSales() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('集計');
const companies = ['A社', 'B社', 'C社', 'D社', 'E社'];
const values = [];
for(const company of companies){
values.push([getTotalSales(company)]);
}
sheet.getRange(2, 2, values.length, values[0].length).setValues(values);
}
function getTotalSales(sheetName) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
const lastRow = sheet.getLastRow();
return sheet.getRange(lastRow, 2).getValue();
}
これにてレベル2クリアです!
以上、お疲れ様でした!
…
…
…
…というわけには行きませんよね。
お気づきだと思いますが、これでは今後また社数が増えた時に、その都度手動で配列にデータを加えていかないといけません。
せっかくなのでここも自動化してしまいたいですよね。
ということで、この配列を自動生成する方法について考えていきましょう!
配列を自動生成する方法
集計シートのA列から引っ張る
それでは、配列を自動生成する方法について考えていきましょう。
まずは「集計」シートに着目してみてください。
今回はこちらのA列に欲しいデータがありますね。
ということで、このA列からデータを引っ張って配列を生成すればいいのではないでしょうか?
A列、より厳密な範囲を言うと、「A2:A6」ですね。
さらに、この「A2:A6」という範囲を番地で言い換えるなら、
「2行1列目から、5行1列分」
ということになります。
ここまでを踏まえて、新たにgetCompanies()
という関数を定義して、配列を生成するためのロジックを記述していきましょう。
ではまず、「2行1列目から、5行1列分」のデータを取得してみましょう。
function getCompanies() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('集計');
const values = sheet.getRange(2, 1, 5, 1).getValues();
}
複数のセルの値を取得するときは、getValuesを使うのでした。覚えているでしょうか?
また、getRange(2, 1, 5, 1)
の「5」に関しては、社数によって変化する数字ですよね。つまり変数です。
ここは、getLastRow()を使って、うまく変数化できるのではないでしょうか。次のように書き直せるでしょう。
function getCompanies() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('集計');
const lastRow = sheet.getLastRow();
const values = sheet.getRange(2, 1, lastRow-1, 1).getValues();
}
注意点としては、lastRow-1、つまり「最終行マイナス1」とすることですね。
なぜなら、1行目のヘッダーがある分をマイナスしないといけないからです。
では、取得した値をconsole.log(values);
でログ出力してみましょう。
function getCompanies() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('集計');
const lastRow = sheet.getLastRow();
const values = sheet.getRange(2, 1, lastRow-1, 1).getValues();
console.log(values);
}
ファイルを保存したら、実行する関数を「getCompanies」に変更して実行してみてください。
すると、以下のような実行結果となります。
無事、A社〜E社の5社の名前を取得できました。
しかしここで注意すべきなのは、そのデータが二次元配列の形式で取得されているということです。
getValuesで値を取得すると、データは二次元配列の形式になるのでした。
しかし、今回欲しい配列は、
const companies = ['A社', 'B社', 'C社', 'D社', 'E社'];
というような一次元の配列です。
そこで、flat()
というメソッドを使います。
二次元配列に対してflatメソッドを使うと、一次元配列に変換することができるのです。
以下はflatメソッドの使用例です。
function myFunction() {
const values1 = [['A社'], ['B社'], ['C社'], ['D社'], ['E社']];
const values2 = values1.flat();
console.log(values1);
console.log(values2);
}
二次元配列のvalues1に対してflatメソッドを使った結果、values2は一次元配列となりました。
これを利用して、getValues()に続けてflat()と記述することで、欲しいデータを一次元配列にすることができます。
function getCompanies() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('集計');
const lastRow = sheet.getLastRow();
const values = sheet.getRange(2, 1, lastRow-1, 1).getValues().flat();
console.log(values);
}
再びgetCompanies
を実行してみましょう。
すると無事、欲しいデータを一次元配列にすることができました!
あとは、この配列をreturnして、setTotalSales関数の中でgetCompanies関数を呼び出してあげればいいですね。
完成系のコードはこちらです。
function setTotalSales() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('集計');
const companies = getCompanies();
const values = [];
for(const company of companies){
values.push([getTotalSales(company)]);
}
sheet.getRange(2, 2, values.length, values[0].length).setValues(values);
}
function getCompanies() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('集計');
const lastRow = sheet.getLastRow();
const values = sheet.getRange(2, 1, lastRow-1, 1).getValues().flat();
return values;
}
function getTotalSales(sheetName) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
const lastRow = sheet.getLastRow();
return sheet.getRange(lastRow, 2).getValue();
}
それでは、実行する関数を「setTotalSales」に戻して実行してみましょう。
実行後、スプレッドシートを確認すると…
無事、集計されました!
これで、今後さらに「F社」「G社」「H社」・・・と社数が増えていっても対応できる、より汎用性の高いプログラムとなりましたね。
集計シートのA列が空白の場合は?
さて、無事、集計シートのA列から会社名を引っ張って配列を自動生成することができました。
しかし、これはあくまで「集計シートのA列にすでに会社名が入力されている」という状況が前提となっている方法です。
ではもし、A列に何も記入されていない場合はどうしたらいいでしょうか?
これについては、「応用問題レベル3」として、次回の記事で解説していきたいと思います。
もし余裕のある人は、ぜひ自分の力で挑戦してみてください!
以下にヒントとなるキーワードを提示しておきます。
- 全シートを取得するss.getSheets()
- シート名を取得するsheet.getName()
- 条件分岐のif文
- ノットイコールを表す
!=
- if(sheetName != ‘集計’)
本講座ではまだ出てきていないキーワードもあるので、まったくの初心者という場合は少し難しいかもしれませんが、キーワードを調べながら自分の力で実装することはとてもいい訓練になります。
プログラミングではそのような「自分で調べて実装する」という、いわゆる「自走力」が最終的には一番大事になってくるので、チャレンジしてみる価値は大いにあるでしょう。
もちろん、わからないからといって自信をなくす必要はありません。その場合はさっさと答えを見にいって、必要な知識を身につけて、また次の機会に活かせばいいのです。
ひたすらトライアンドエラーを繰り返して、徐々にスキルアップしていきましょう!
まとめ
以上、flatメソッドを使用して配列を自動生成する方法について解説しました。
前々回と前回、そして今回の記事で、
- 売上を集計するgetTotalSales関数を作る
- for文で配列をループさせて各社の売上を集計する
- ループさせる配列を自動生成する
ということをしてきました。
最初の方に実装したコードと見比べると、かなり汎用性の高いプログラムになってきていると思います。
プログラミングとはこのように、1個ずつ手順を踏んで、地道に自動化を進めていく作業です。
夢中になって進んでいる間は気づきにくいですが、ふと振り返ると「いつの間にかすごいものができあがってるな」と感じることがあります。プログラミングの楽しさはそのような瞬間にあると思ったりします。本シリーズでその楽しさを少しでも味わえてもらえたら嬉しいです。
それでは、次回は応用問題レベル3の答え合わせをしていきます!
連載目次: 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では月2〜3回セールが開かれますので、セール期間中にご購入いただくのがオススメです。
コメント